550

Imagine a simple unsorted list with some <li> items. Now, I have defined the bullets to be square shaped via list-style:square; However, if I set the color of the <li> items with color: #F00; then everything becomes red!

While I only want to set the color of the square bullets. Is there an elegant way to define the color of the bullets in CSS...

...without using any sprite images nor span tags!

HTML

<ul> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> <ul> 

CSS

li{ list-style:square; } 
2
  • 4
    I'm not sure if this can be done elegantly (but I'm no CSS expert). If you don't get a "right" answer, you could consider using list-style-image and setting it to an image of a colored bullet. Commented Mar 15, 2011 at 1:57
  • 3
    Is (was) there any reason why not to use a <span>? For me this seems to be the only elegant and timeless way of doing this. It works perfectly cross browser even the demon child called IE supports it. It also grands a lot of control between the text and bullet like size. Commented Jan 18, 2014 at 9:50

16 Answers 16

1074

The most common way to do this is something along these lines:

ul { list-style: none; padding: 0; margin: 0; } li { padding-left: 1em; text-indent: -.7em; } li::before { content: "• "; color: red; /* or whatever color you prefer */ }
<ul> <li>Foo</li> <li>Bar</li> <li>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</li> </ul>

JSFiddle: http://jsfiddle.net/leaverou/ytH5P/

Will work in all browsers, including IE from version 8 and up.

Sign up to request clarification or add additional context in comments.

29 Comments

being a nitwit, I would remove the extra space in "• " ==> "•" and add this line below it: padding-right:7px; bit more controll there :) the rest is awesome and works everywhere. PS what does the :before mean/do here?
instead of "• " also possible: content: "4"; font-family:"Webdings"; which will result in a nice > or for a nice ■ content: "■"; font-family:"Arial Black";
Oh, and as for what :before does: It lets you dynamically insert (presentational) content inside an element, before its "real" content. More: w3.org/TR/CSS21/generate.html#before-after-content (I pasted the CSS2 spec to show you it's not even CSS3)
another alternative to "•" is "\002022"
@Sam "font-family:"Webdings";" is a terrible idea; you can't assume every user will have that font installed on their system (I don't, and I'm pretty sure it's not that common, especially on mobile devices).
|
91

browsing sometime ago, found this site, have you tried this alternative?

li{ list-style-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAYAAACp8Z5+AAAAE0lEQVQIW2NkYGD4D8RwwEi6AACaVAQBULo4sgAAAABJRU5ErkJggg=="); } 

sounds hard, but you can make your own png image/pattern here, then copy/paste your code and customize your bullets =) stills elegant?

EDIT:

following the idea of @lea-verou on the other answer and applying this philosophy of outside sources enhancement I've come to this other solution:

  1. embed in your head the stylesheet of the Webfont icons Library, in this case Font Awesome:

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">

  1. take a code from FontAwesome cheatsheet (or any other webfont icons).
i.e.: fa-angle-right [&#xf105;] 

and use the last part of f... followed by a number like this, with the font-family too:

li:before { content: "\f105"; font-family: FontAwesome; color: red; /* or whatever color you prefer */ margin-right: 4px; } 

and that's it! now you have custom bullet tips too =)

fiddle

6 Comments

I needed a solution for ie7 (of course, does not supports the :before selector).
So sorry to say that base64 images don't work in IE7 either... otherwise it would be the best solution...
Upvote for out of the box thinking
Screw IE7. It's a really old browser by now. This solution rocks! Anyway, if you really want to support IE7 you can just copy and paste the Base64 code into a modern browser address bar, then save the image as a PNG file using Ctrl+S (or Cmd+S in Mac) and use the actual PNG file instead of the Base64 encoded string
Patternify is awesome
|
64

I simply solve this problem like this, which should work in all browsers:

ul li { color: red } ul li span { color: blue; }
<ul> <li><span>Foo</span></li> <li><span>Bar</span></li> <li><span>Bat</span></li> </ul>

4 Comments

Oops, sorry. Overread that an answer was wanted WITHOUT span :-(
Also he wanted the bullet of another color, not the text.
All good, man. Helped in my first try. This almost never happens, you know how things go. Thanks for the answer. BTW, why not span?
the only non-bicycle solution here
63

The current spec of the CSS 3 Lists module does specify the ::marker pseudo-element which would do exactly what you want; FF has been tested to not support ::marker and I doubt that either Safari or Opera has it. IE, of course, does not support it.

So right now, the only way to do this is to use an image with list-style-image.

I guess you could wrap the contents of an li with a span and then you could set the color of each, but that seems a little hackish to me.

7 Comments

+1 for this: "IE, of course, does not support it." :)
As of 15th Dec 2016 no major browser supports :marker, see caniuse.com/#feat=css-marker-pseudo
What a shame! Until 2018 none of the major browser support this yet!
Firefox and Safari now do support ::marker pseudo elements.
This answer is slightly outdated. ::marker is now supported in all modern browsers except Opera.
|
51

One way to do it is using li:before with content: "" and styling it as inline-block element.

Here is a working code snippet:

ul { list-style-type: none; /* no default bullets */ } ul li { font-family: Arial; font-size: 18px; } ul li:before { /* the custom styled bullets */ background-color: #14CCBB; border-radius: 50%; content: ""; display: inline-block; margin-right: 10px; margin-bottom: 2px; height: 10px; width: 10px; }
<ul> <li>Swollen joints</li> <li>Pain in hands and knees</li> <li>Redness around joints</li> <li>Constant fatigue</li> <li>Morning stiffness in joints</li> <li>High fevers</li> <li>Rheumatoid nodules, which develop around joints</li> </ul>

3 Comments

So much easier than using content ". " or "\2022" as you don't need to worry about positioning of the bullet next to the text
Might be better to use ul li:before { ... } so that it doesn't mess with ol lists as well
@yeahlad good point! I have updated my answer.
25

Yet, another solution is to use a :before pseudo element with a border-radius: 50%. This will work in all browsers, including IE 8 and up.

Using the em unit allows responsiveness to font size changes. You can test this, by resizing your jsFiddle window.

ul { list-style: none; line-height: 1em; font-size: 3vw; } ul li:before { content: ""; line-height: 1em; width: .5em; height: .5em; background-color: red; float: left; margin: .25em .25em 0; border-radius: 50%; }
<ul> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> <ul>
jsFiddle

You can even play with the box-shadow to create some nice shadows, something that will not look nice with the content: "• " solution.

1 Comment

This worked perfect. I had to adjust the margin to be: margin: 0.5em 0.25em 0 0, but otherwise this was perfect
20

I tried this and things got weird for me. (css stopped working after the :after {content: "";} part of this tutorial. I found you can color the bullets by just using color:#ddd; on the li item itself.

Here's an example.

li{ color:#ff0000; list-style:square; } a { text-decoration: none; color:#00ff00; } a:hover { background-color: #ddd; } 

3 Comments

It is not. This also colors the text in the li, obviously.
@oarfish not actually, the text in li are wrapped with another tag, in case i used span.
I wrapped the inside li text with a span a this works wonders. Best answer!
18

I use jQuery for this:

jQuery('li').wrapInner('<span class="li_content" />'); 

& with some CSS:

li { color: red; } li span.li_content { color: black; } 

maybe overkill, but handy if you're coding for a CMS and you don't want to ask your editors to put an extra span in every list-items.

4 Comments

Aside from the jQuery bit this is the most cross-browser and (for me) cross-email-client compatible solution I have found.
Email compatible jQuery??
Keep in mind, that if no javascript is available, the base-color will become your fancy bullets color.
I styled the list normally and then if the js ran I updated the styling. That prevents the bullet color from being used for the list if js hasn't executed. Like: jQuery('ol').addClass('ol-wrapper').find('li').wrapInner('<span class="li-content" />');
11

I would recommend giving the LI a background-image and padding-left. The list-style-image attribute is flakey in cross-browser environments, and adding an extra element, such as a span, is unneccessary. So your code would end up looking something like this:

li { background:url(../images/bullet.png) 0 0 no-repeat; list-style:none; padding-left:10px; } 

Comments

10

The easiest thing you can do is wrap the contents of the <li> in a <span> or equivalent then you can set the color independently.

Alternatively, you could make an image with the bullet color you want and set it with the list-style-image property.

3 Comments

Works also if you would like to make numbers on an OL bold.
This is a no brainer for compatibility.
Yeah this is what I use for older IE compatibility. We're still supporting IE7 for legacy reasons of a very large company. The li::before method in the accepted answer above does not work in IE7 as it doesn't support ::before.
9

A variation of Lea Verou solution with perfect indentation in multi-line entries could be something like this:

ul{ list-style: none; position: relative; padding: 0; margin: 0; } li{ padding-left: 1.5em; } li:before { position: absolute; content: "•"; color: red; left: 0; } 

1 Comment

This solution is good if your first element in a li has display:block, as a p element
7

I know it's a bit of a late answer for this post, but for reference...

CSS

ul { color: red; } li { color: black; } 

The bullet colour is defined on the ul tag and then we switch the li colour back.

5 Comments

Not working in Chrome. Sadly.
Also not in Firefox 24.
Works in Firefox 25 and the most recent version of Chrome
This doesn't work for me, but changing li { to ul li * { does. Tested in Chrome v51 and Firefox v47.0
This does not work. Ferry, it likely worked for you because your text was wrapped in another element, such as <a> or <span>.
7

I am adding my solution to this problem.

I don't want to use image and validator will punish you for using negative values in CSS, so I go this way:

ul { list-style:none; padding:0; margin:0; } li { padding-left:0.75em; position:relative; } li:before { content:"•"; color:#e60000; position:absolute; left:0em; } 

Comments

4

Taking Lea's demo, here's a different way of making unordered lists, with borders: http://jsfiddle.net/vX4K8/7/

HTML

<ul> <li>Foo</li> <li>Bar</li> <li>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</li> <ul> <li>Son</li> <li>Of</li> <ul> <li>Foo</li> <li>Bar</li> <li>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</li> </ul> </ul> </ul> 

CSS

ul { list-style: none; margin: 0; } ul:first-child { padding: 0; } li { line-height: 180%; border-bottom: 1px dashed #CCC; margin-left: 14px; text-indent: -14px; } li:last-child { border: none; } li:before { content: ""; border-left: 4px solid #CCC; padding-left: 10px; } 

1 Comment

@user2188875 Very interesting twist! Thanks for elevating the question and so creatively adding new meaning to the answer. Indeed this way lists could be stylised very maturely! Is this compatible in email html templates too? say one would use this for html mails and send them. Would the receiving party (mac/win7/win10/android/etc) see and read the html properly??
4

Lea Verous solution is good but i wanted more control over the position of the bullets so this is my approach:

.entry ul { list-style: none; padding: 0; margin: 0; /* hide overflow in the case of floating elements around ... */ overflow: hidden; } .entry li { position: relative; padding-left: 24px; } .entry li:before { /* with absolute position you can move this around or make it bigger without getting unwanted scrollbars */ position: absolute; content: "• "; color: #E94E24; font-size: 30px; left: 0; /* use fonts like "arial" or use "sans-serif" to make the dot perfect round */ font-family: Arial, sans-serif; } 

Comments

-18

This will do it..

li{ color: #fff; } 

1 Comment

This will only affect the text content in the li element. Not the list style.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.