5

I'm looking to vertically align text in a list item. I'm using display: flex; and align-items: center;. But my code contains a strong tag, which gets interpreted as a separate flex item, and so the spaces on either side get collapsed.

I could hack it with  , but is there a proper way to get my text, with inline elements, to vertically align center?

  • I know I could wrap the text in a <p>. I'm trying to avoid that.
  • My text might be long enough to wrap, so line-height isn't an option.
  • Once display: contents; becomes widely supported, that would be my go-to solution here.

li {
  display: flex;
  align-items: center;
  height: 8em;/* just for example */
  border: 2px solid red;/* just for example */
}
<ul>
  <li>It is <strong>Very important</strong> that this text is vertically centered!</li>
  <li>Also <strong>Very important</strong> that there are spaces in the text.</li>
</ul>
TylerH
  • 20,799
  • 66
  • 75
  • 101
nHaskins
  • 805
  • 8
  • 22
  • 1
    `I know I could wrap the text in a

    . I'm trying to avoid that.` --> you should do this and never ever make text container a flexbox container, what you have is nothing compared to what you will have if you will have more lines. Related: https://stackoverflow.com/a/54903923/8620333

    – Temani Afif Nov 12 '19 at 19:19

4 Answers4

0

The only efficient solution to your problem is to remove the text from the flex formatting context. You can do this by wrapping the text in another element, making that element the flex item. Now your text is back in a standard block formatting context, and the collapsing spaces are no longer a problem.

li {
  display: flex;
  align-items: center;
  height: 8em;
  border: 2px solid red;
}
<ul>
  <li>
    <p>It is <strong>Very important</strong> that this text is vertically centered!</p>
  </li>
  <li>
    <p>Also <strong>Very important</strong> that there are spaces in the text.</p>
  </li>
</ul>

Also, note that all children of a flex container are block-level elements, regardless of what you specify. So the idea that you're dealing with inline-level elements is incorrect. There are no inline-level elements in a flex container.

§ 4. Flex Items

The display value of a flex item is blockified. If the specified display of an in-flow child of an element generating a flex container is an inline-level value, it computes to its block-level equivalent.

More details:

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
0

You can consider CSS grid and fake the borders. You will visually have the expected result:

li {
  list-style:none;
  text-align:center;
}
ul {
  display:grid;
  grid-auto-rows:8em;
  grid-gap:2px;
  align-items:center;
  border: 2px solid red;
  background:linear-gradient(red,red) center/100% 2px no-repeat;
  padding:0;
  margin:0;
}
<ul>
  <li>It is <strong>Very important</strong> that this <br>text is vertically centered!</li>
  <li>Also <strong>Very important</strong> that there are spaces in the text.</li>
</ul>

For more items you can adjust the background:

li {
  list-style:none;
  text-align:center;
}
ul {
  display:grid;
  grid-auto-rows:8em;
  grid-gap:2px;
  align-items:center;
  border: 2px solid red;
  background: repeating-linear-gradient(transparent 0 8em,red 8em calc(8em + 2px));
  padding:0;
  margin:0;
}
<ul>
  <li>It is <strong>Very important</strong> that this <br>text is vertically centered!</li>
  <li>Also <strong>Very important</strong> that there are spaces in the text.</li>
  <li>It is <strong>Very important</strong> that this <br>text is vertically centered!</li>
  <li>Also <strong>Very important</strong> that there are spaces in the text.</li>
  <li>It is <strong>Very important</strong> that this <br>text is vertically centered!<br>text is vertically centered!</li>
  <li>Also <strong>Very important</strong> that there are spaces in the text.</li>
</ul>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
-2

This should fix the problem!

li {
  display: flex;
  align-items: center;
  height: 8em;/* just for example */
  border: 2px solid red;/* just for example */
}
span {
  position: relative;
  left: 50%;
  transform: translateX(-50%);
}
<ul>
  <li><span>It is <strong>Very important</strong> that this text is vertically centered!</span></li>
  <li><span>Also <strong>Very important</strong> that there are spaces in the text.</span></li>
</ul>
TylerH
  • 20,799
  • 66
  • 75
  • 101
Ameer
  • 1,980
  • 1
  • 12
  • 24
-3

In case like this I would suggest using display: contents with fallback with @supports() using either margin, or pseudo elements with contents of 1 space.

Akxe
  • 9,694
  • 3
  • 36
  • 71