Instead of using align-self: center use align-items: center.
There's no need to change flex-direction or use text-align.
Here's your code, with one adjustment, to make it all work:
ul {
height: 100%;
}
li {
display: flex;
justify-content: center;
/* align-self: center; <---- REMOVE */
align-items: center; /* <---- NEW */
background: silver;
width: 100%;
height: 20%;
}
The align-self property applies to flex items. Except your li is not a flex item because its parent – the ul – does not have display: flex or display: inline-flex applied.
Therefore, the ul is not a flex container, the li is not a flex item, and align-self has no effect.
The align-items property is similar to align-self, except it applies to flex containers.
Since the li is a flex container, align-items can be used to vertically center the child elements.
* {
padding: 0;
margin: 0;
}
html, body {
height: 100%;
}
ul {
height: 100%;
}
li {
display: flex;
justify-content: center;
/* align-self: center; */
align-items: center;
background: silver;
width: 100%;
height: 20%;
}
<ul>
<li>This is the text</li>
</ul>
codepen demo
Technically, here's how align-items and align-self work...
The align-items property (on the container) sets the default value of align-self (on the items). Therefore, align-items: center means all flex items will be set to align-self: center.
But you can override this default by adjusting the align-self on individual items.
For example, you may want equal height columns, so the container is set to align-items: stretch. However, one item must be pinned to the top, so it is set to align-self: flex-start.
example
How is the text a flex item?
Some people may be wondering how a run of text...
<li>This is the text</li>
is a child element of the li.
The reason is that text that is not explicitly wrapped by an inline-level element is algorithmically wrapped by an inline box. This makes it an anonymous inline element and child of the parent.
From the CSS spec:
9.2.2.1 Anonymous inline
boxes
Any text that is directly contained inside a block container element
must be treated as an anonymous inline element.
The flexbox specification provides for similar behavior.
4. Flex Items
Each in-flow child of a flex container becomes a flex item, and each
contiguous run of text that is directly contained inside a flex
container is wrapped in an anonymous flex item.
Hence, the text in the li is a flex item.