I tried to vertically centralize plain text inside a flex box element.
I decided to use property display:table-cell
with vertical-align: middle
. But it doesn't seem to work properly in flexbox elements.
How can I centralize it vertically, ideally without using a wrapper or positioning, and while still truncating long text with ellipses?
.container {
width: 400px;
height: 400px;
font-weight: 700;
border: 1px solid #d9d9d9;
display: flex;
flex-direction: column;
}
.item {
display: table-cell;
vertical-align: middle;
flex: 1 1;
background-color: cyan;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.item:nth-of-type(2n) {
background-color: aliceblue;
}
<div class="container">
<div class="item">Hello, I'm very very long string! Hello, I'm very very long string!</div>
<div class="item">Hello</div>
<div class="item">Hello</div>
<div class="item">Hello</div>
</div>
View On CodePen
One solution is to define each flex item as its own flex container in order to vertically center its contents with align-items:center
. To keep text-overflow
working, add a child element to each flex item, which can then be truncated with ellipses.
I can't offer a succinct explanation as to why text-overflow
doesn't work with display:flex
, and neither can David Wesst. In his words:
It turns out that there really isn't a clean way to do this. If you're wondering how I came to that conclusion you can stop because I didn't. Those responsible for the specification did, and you can read the full conversation that started with a Mozilla bug report and leads to a whole mail group discussion about why it should (or, in this case, should not) be implemented as part of the spec.
Here's a working example:
.container {
width: 400px;
height: 400px;
font-weight: 700;
border: 1px solid #d9d9d9;
display: flex;
flex-direction: column;
}
.item {
display: flex;
align-items: center;
flex: 1;
background-color: cyan;
}
.item span {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.item:nth-of-type(2n) {
background-color: aliceblue;
}
<div class="container">
<div class="item"><span>Hello, I'm very very long string! Hello, I'm very very long string!</span></div>
<div class="item"><span>Hello</span></div>
<div class="item"><span>Hello</span></div>
<div class="item"><span>Hello</span></div>
</div>
Also see:
Setting ellipsis on text from a flex container
When you make an element a flex container (with display: flex
or display: inline-flex
), all in-flow children become flex items.
All flex items have their display
value controlled by the container. It doesn't matter what you specify, the container overrides it.
So when you give a flex item display: table-cell
, the browser ignores it. Here's what it looks like in Chrome Dev Tools:
Style Tab
Computed Tab
A flex container "blockifies" flex items, causing them to assume many qualities of block-level elements (source).
But the vertical-align
property applies only to inline-level and table-cell elements (source).
That's why it doesn't work.
Regardless, vertical-align
, even if it worked, is a totally unnecessary hack in this case. There are flex properties designed for aligning content in flex items.
.container {
width: 500px;
height: 500px;
font-weight: 700;
border: 1px solid #d9d9d9;
display: flex;
flex-direction: column;
}
.item {
flex: 1 1;
display: flex;
justify-content: center; /* horizontal alignment, in this case */
align-items: center; /* vertical alignment, in this case */
background-color: cyan;
}
.item:nth-of-type(2n) {
background-color: aliceblue;
}
<div class="container">
<div class="item">Hello</div>
<div class="item">Hello</div>
<div class="item">Hello</div>
<div class="item">Hello</div>
</div>
Related posts:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With