[css] Is there a way to make numbers in an ordered list bold?

Is there any CSS selector to attach some style to the numerical part of an ordered list only?

I have HTML like:

<ol>
   <li>a</li>
   <li>b</li>
   <li>c</li>
</ol>

Which should output:

1.a
2.b
3.c

I need to make 1., 2. and 3. bold, while leaving a, b, and c regular.

I am aware of the <span> workaround...

This question is related to css html-lists

The answer is


This is an update for dcodesmith's answer https://stackoverflow.com/a/21369918/1668200

The proposed solution also works when the text is longer (i.e. the lines need to wrap): Updated Fiddle

When you're using a grid system, you might need to do one of the following (at least this is true for Foundation 6 - couldn't reproduce it in the Fiddle):

  • Add box-sizing:content-box; to the list or its container
  • OR change text-indent:-2em; to -1.5em

P.S.: I wanted to add this as an edit to the original answer, but it was rejected.


Answer https://stackoverflow.com/a/21369918/2526049 from dcodesmith has a side effect that turns all types of lists numeric. <ol type="a"> will show 1. 2. 3. 4. rather than a. b. c. d.

ol {
  margin: 0 0 1.5em;
  padding: 0;
  counter-reset: item;
}

ol > li {
  margin: 0;
  padding: 0 0 0 2em;
  text-indent: -2em;
  list-style-type: none;
  counter-increment: item;
}

ol > li:before {
  display: inline-block;
  width: 1em;
  padding-right: 0.5em;
  font-weight: bold;
  text-align: right;
  content: counter(item) ".";
}

/* Add support for non-numeric lists */

ol[type="a"] > li:before {
  content: counter(item, lower-alpha) ".";
}
ol[type="i"] > li:before {
  content: counter(item, lower-roman) ".";
}

The above code adds support for lowercase letters, lowercase roman numerals. At the time of writing browsers do not differentiate between upper and lower case selectors for type so you can only pick uppercase or lowercase for your alternate ol types I guess.


A new ::marker pseudo-element selector has been added to CSS Pseudo-Elements Level 4, which makes styling list item numbers in bold as simple as

ol > li::marker {
  font-weight: bold;
}

It is currently supported by Firefox 68+, Chrome/Edge 86+, and Safari 11.1+.


If you are using Bootstrap 4:

<ol class="font-weight-bold">
    <li><span class="font-weight-light">Curabitur aliquet quam id dui posuere blandit.</span></li>
    <li><span class="font-weight-light">Curabitur aliquet quam id dui posuere blandit.</span></li>
</ol>

You also could put <span style="font-weight:normal"> around a,b,c and then bold the ul in the CSS.

Example

ul {
    font-weight: bold;
}

<ul><li><span style="font-weight:normal">a</span></li></ul>

I had a similar issue while writing a newsletter. So I had to inline the style this way:

<ol>
    <li style="font-weight:bold"><span style="font-weight:normal">something</span></li>
    <li style="font-weight:bold"><span style="font-weight:normal">something</span></li>
    <li style="font-weight:bold"><span style="font-weight:normal">something</span></li>
</ol>

Pretty late answer, but hopefully someone will find this useful

I had a situation like this:

  1. List item

    a. List item

Where the first item was <strong>, the sub-element was normal weight and the '1.' just wouldn't bold.

My solution was via jQuery:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
    $(document).ready(function () {
        if ($('ol').has('li').has('strong')) {
            $('ol ').css('font-weight', 'bold');
            $('ol > li > ol').css('font-weight', 'normal');
        }
     });
</script>

Hopefully this helps someone!


JSFiddle:

ol {
    counter-reset: item;
}
ol li { display: block }

ol li:before {
    content: counter(item) ". ";
    counter-increment: item;
    font-weight: bold;
}

Another easy possibility would be to wrap the list item content into a <p>, style the <li> as bold and the <p> as regular. This would be also preferable from an IA point of view, especially when <li>s can contain sub-lists (to avoid mixing text nodes with block level elements).

Full example for your convenience:

<html>
    <head>
        <title>Ordered list items with bold numbers</title>
        <style>
            ol li {
                font-weight:bold;
            }
            li > p {
                font-weight:normal;
            }
        </style>
    </head>
    <body>
        <ol>
            <li>
                <p>List Item 1</p>
            </li>
            <li>
                <p>Liste Item 2</p>
                <ol>
                    <li>
                        <p>Sub List Item 1</p>
                     </li>
                    <li>
                        <p>Sub List Item 2</p>
                     </li>
                </ol>
            </li>
            <li>
                <p>List Item 3.</p>
            </li>
        </ol>
    </body>
</html>

If you prefer a more generic approach (that would also cover other scenarios like <li>s with descendants other than <p>, you might want to use li > * instead of li > p:

<html>
    <head>
        <title>Ordered list items with bold numbers</title>
        <style>
            ol li {
                font-weight:bold;
            }
            li > * {
                font-weight:normal;
            }
        </style>
    </head>
    <body>
        <ol>
            <li>
                <p>List Item 1</p>
            </li>
            <li>
                <p>Liste Item 2</p>
                <ol>
                    <li>
                        <p>Sub List Item 1</p>
                     </li>
                    <li>
                        <p>Sub List Item 2</p>
                     </li>
                </ol>
            </li>
            <li>
                <p>List Item 3.</p>
            </li>
            <li>
                <code>List Item 4.</code>
            </li>
        </ol>
    </body>
</html>

(Check the list item 4 here which is ol/li/code and not ol/li/p/code here.)

Just make sure to use the selector li > * and not li *, if you only want to style block level descendants as regular, but not also inlines like "foo <strong>bold word</strong> foo."