Customize list item bullets using CSS

Viewed 176748

Is it possible to change the size of an <li> element's bullet?

Take a look at the code below:

li {
    list-style: square; /* I want to change the size of this squared bullet. */
}

I can't seem to find any way to achieve that.

16 Answers

You can use the ::marker CSS pseudo-element to style the number or bullet of a list. Currently, January 2022, Safari support is limited to color and font-size.

Example:

::marker {
  color: red;
  font-size: 2rem
}

ul > li::marker {
  color: blue;
}

ol > li::marker {
  font-size: 1rem
}
<ul>
  <li>Step One</li>
  <li>Step Two</li>
  <li>Step Three</li>
</ul>
 
<ol>
  <li>Wake up</li>
  <li>Code</li>
  <li>Sleep</li>
</ol>

I just found a solution that I think works really well and gets around all of the pitfalls of custom symbols. The main problem with the li:before solution is that if list-items are longer than one line will not indent properly after the first line of text. By using text-indent with a negative padding we can circumvent that problem and have all the lines aligned properly:

ul{
    padding-left: 0; // remove default padding
}

li{
    list-style-type: none;  // remove default styles
    padding-left: 1.2em;    
    text-indent:-1.2em;     // remove padding on first line
}

li::before{
    margin-right:     0.5em; 
    width:            0.7em; // margin-right and width must add up to the negative indent-value set above
    height:           0.7em;

    display:          inline-block;
    vertical-align:   middle;
    border-radius: 50%;
    background-color: orange;
    content:          ' '
}

This method moves the disc out of the text flow where the original disc was, but is adjustable.

ul{
    list-style-type: none;
    
    li{ 
        position: relative;
      }
    li:before {
        position: absolute;
        top: .1rem;
        left: -.8em;
        content: '\2022';
        font-size: 1.2rem;
    }
}

Here is a Unicode version. This one allows you to drop in any text symbol or emoticon you like into your CSS bullet list. All you need is the Unicode "code point" value.

<style>
#html_list{
    position: relative;
    margin-left: 1em;
    list-style: none;
}
#html_list li::before {
    display: inline-block;
    content: "\2023";
    color: #114f66;
    font-size: 3rem;
    line-height: 0;
    padding: 0 .1em 0 0;
    margin: 0;
    text-align: left;
    vertical-align: top;
    position: relative;
    top: .2em;
    left: 0em;
}
#html_list li {
    text-align:left;
    vertical-align: top;
    padding: .2em 0em .2em 0em;
    margin: 0;
    font-size: 1rem;
}
</style>

<ul id="html_list">
    <li><a href="#">Area 1</a></li>
    <li><a href="#">Area 2</a></li>
    <li><a href="#">Area 3</a></li>
</ul>

The main problem in using Unicode or text symbols in lists is resizing. Even after you have stripped away height, line-height, padding, and margins, the symbol has spacing after resizing it using font-size. Most of this is based on the font you choose. Be careful and pick a font-face in CSS that has a range of Unicode glyphs.

I've designed the best possible solution above that keeps the Unicode bullet text and its style separate from the rest of the list text using a pseudo-element. This idea allows you to remove the default list-style bullet in the parent unordered list, insert a new Unicode bullet into a ::before pseudo-element. You can then resize and reposition it as you like. Once you have lined up your sized bullets with the list text, you can then start padding or sizing your list text as you need and the bullets should move with it.

Haven't seen this technique mentioned. It basically allows you to have a "dot" any size you want. It uses a round border to draw a circle.

li {
    list-style-type: none;
    position: relative;
    margin-left: 2.5rem;
}

li:before {
    content: " ";
    border: 1rem solid #1b1b1b;
    border-radius: 99rem;
    height: 0; /* it's all controlled by the border */
    width: 0;
    margin-top: -0.4rem;
    margin-left:  -2.5rem;
    position: absolute;
}

Result

Things have obviously changed a little since 2011. Today CSS offers two simple and well-supported ways of customising the bullets in an unordered list.

The most recent one is the ::marker pseudo-element. It allows you to apply styles directly to any marker, be it a bullet or a number. See Robert Kegel's answer for a more detailed description of that.

The other method is deceptively simple. You just set the list-style-type property on your ul to a quoted string and choose whatever Unicode character tickles your fancy. In this example, I've chosen character U+25A0 (Black Square), which is bigger than the standard square bullet:

ul {
  list-style-type: square;
}
ul.big-bullets {
  list-style-type: "■  ";
}
<ul class="big-bullets">
  <li>Check out my square bullets!</li>
  <li>They are big, and perfectly aligned.</li>
  <li>And all it took was one very simple line of CSS.</li>
</ul>
<ul>
  <li>They <em>are</em> big bullets.</li>
  <li>I'm a little jealous.</li>
</ul>

The ability to set a string on the list-style-type property has been around for many years, but browser support took a while to catch up. It's now over 92% according to Can I use.

Now, you may be thinking you'd rather just apply a font-size than delve into obscure Unicode characters, and in that case, you'd go for the ::marker method. But keep in mind, those bullet characters are only designed to line up nicely when used at the same font size as the rest of the text. IMHO, choosing the right bullet character in the first place is the way to go. If you want more fine-grained control, you can, of course, use both techniques together.

Related