Search code examples
htmlcssfrontendweb-frontend

How do I vertically center the text in a <li> without affecting the list bullet?


I am trying to build a simple website, the HTML is like this:

<ul>
    <li class="l1">Test item 1</li>
    <li class="l2">Test item 2</li>
</ul>

enter image description here

You can see the text does not align with the bullets. Here is what I tried:

ul{
  display: table;
}

and

li{
  display: table-cell;
  text-align:middle;
}

But the bullets disappeared: enter image description here

So I wanna ask if there are any ways to vertical center the text in the list item without affecting the bullets?


Solution

  • Only list-items have markers:

    The ::marker pseudo-element represents the automatically generated marker box of a list item. (See display: list-item.)

    So you need list-item:

    The list-item keyword causes the element to generate a ::marker pseudo-element box with the content specified by its list-style properties (CSS 2.1§12.5 Lists) together with a principal box of the specified type for its own contents.

    CSS Display 3 introduces some variants of list-item:

    list-item block flow
    list-item block flow-root
    list-item inline flow
    list-item inline flow-root
    list-item run-in flow
    list-item run-in flow-root
    

    but it seems there is no browser support, so better use the old display: list-item.

    That's why, if you use display: inline-block or display: table-cell, the markers disappear.

    If you want to align the markers vertically, the CSS Lists and Counters drafts allows

    li::marker {
      display: inline-block;
      vertical-align: middle;
    }
    

    However, don't expect any browser to support this yet. Instead, I would recommend hiding the markers and using a ::before pseudo-element instead:

    ul {
      list-style: none;
      padding-left: 0;
    }
    li::before {
      content: url('image.ico');
      display: inline-block;
      vertical-align: middle;
    }
    

    Note the behavior will be like if you used list-style-position: inside, which may not look right if the list items have line breaks. You can try absolute positioning if you want to emulate list-style-position: outside.