Unicode character as bullet for list-item in CSS
Asked Answered
S

14

130

I need to use, for example, the star-symbol(★) as the bullet for a list-item.

I have read the CSS3 module: Lists, that describes, how to use custom text as bullets, but it's not working for me. I think, the browsers simply don't support the ::marker pseudo element.

How can I do it, without using images?

Saturant answered 8/7, 2010 at 11:55 Comment(3)
can you put up the code you're using? And what browser are you testing this in?Mernamero
#3068699 has some Unicode bullets. Neither the star symbol you have above, nor 26AB (medium black circle) display on my Windows machine, though they are OK on Ubuntu.Circumferential
This answer (to a similar question) solved it for me: https://mcmap.net/q/141739/-custom-bullet-symbol-for-lt-li-gt-elements-in-lt-ul-gt-that-is-a-regular-character-and-not-an-imageIbo
S
84

EDIT

I probably wouldn't recommend using images anymore. I'd stick to the approach of using a Unicode character, like this:

li:before {
  content: "\2605";
}

OLD ANSWER

I'd probably go for an image background, they're much more efficient versatile and cross-browser-friendly.

Here's an example:

<style type="text/css">
  ul {list-style:none;} /* you should use a css reset too... ;) */
  ul li {background:url(images/icon_star.gif) no-repeat 0 5px;}
</style>

<ul>
  <li>List Item 1</li>
  <li>List Item 2</li>
  <li>List Item 3</li>
</ul>
Scallion answered 8/7, 2010 at 14:46 Comment(4)
How is that “much more efficient”? You’re sending an additional HTTP request to fetch the image and the total file increases as you load an image for something that could just be done through the use of a single Unicode character.Gay
you're right, probably "efficient" is not the word i should have used if you're looking for performance, but using an image background is certainly much more versatile than using text.Scallion
It's not very good to resize an image, but a character is perfect on every size, so I would say a character is more versatile :P I think backword-compatible or with widest range of browser support would be the word...Rsfsr
This doesn't work well when the <li> text wraps: The bullet doesn't remain unindented, and ends up looking like the beginning of a paragraph of text. This answer fixes this issue: https://mcmap.net/q/173235/-unicode-character-as-bullet-for-list-item-in-cssPachton
F
120

Using Text As Bullets

Use li:before with an escaped Hex HTML Entity (or any plain text).


Example

My example will produce lists with check marks as bullets.

ul {
    list-style: none;
    padding: 0px;
}

ul li:before
{
    content: '\2713';
    margin: 0 1em;    /* any design */
}
<ul>
  <li>First item</li>
  <li>Second item</li>
</ul>

Browser Compatibility

Haven't tested myself, but it should be supported as of IE8. At least that's what quirksmode & css-tricks say.

You can use conditional comments to apply older/slower solutions like images, or scripts. Better yet, use both with <noscript> for the images.

HTML:

<!--[if lt IE 8]>
    *SCRIPT SOLUTION*
    <noscript>
        *IMAGE SOLUTION*
    </noscript>
<![endif]-->

About background images

Background images are indeed easy to handle, but...

  1. Browser support for background-size is actually only as of IE9.
  2. HTML text colors and special (crazy) fonts can do a lot, with less HTTP requests.
  3. A script solution can just inject the HTML Entity, and let the same CSS do the work.
  4. A good resetting CSS code might make list-style (the more logical choice) easier.

Enjoy.

Fly answered 24/11, 2012 at 23:53 Comment(6)
useful conversion tool for escaping special characters rishida.net/tools/conversionLongeron
This does not work properly if the contents of the li element wrap over multiple lines; those wrapped lines will not be indented correctly.Relativistic
float: left; margin-left: -12px; on the :before to take care of that, @RichardEverettHartzell
I works for one line but doesn't work if several lines are wrapping.Bahner
i don't know if this works everywhere equally, but i got best results with: margin-right: 0.5em; margin-left:-1.5em; it looks like the star is exactly 1em in width because multiple lines now line up perfectly. so i guess the general rule would be: margin-left = - (margin-right + width of character)Honeymoon
Works only for single-line list-items. Multi-lines will drop beneath the bullet rather than indenting.Detergency
S
84

EDIT

I probably wouldn't recommend using images anymore. I'd stick to the approach of using a Unicode character, like this:

li:before {
  content: "\2605";
}

OLD ANSWER

I'd probably go for an image background, they're much more efficient versatile and cross-browser-friendly.

Here's an example:

<style type="text/css">
  ul {list-style:none;} /* you should use a css reset too... ;) */
  ul li {background:url(images/icon_star.gif) no-repeat 0 5px;}
</style>

<ul>
  <li>List Item 1</li>
  <li>List Item 2</li>
  <li>List Item 3</li>
</ul>
Scallion answered 8/7, 2010 at 14:46 Comment(4)
How is that “much more efficient”? You’re sending an additional HTTP request to fetch the image and the total file increases as you load an image for something that could just be done through the use of a single Unicode character.Gay
you're right, probably "efficient" is not the word i should have used if you're looking for performance, but using an image background is certainly much more versatile than using text.Scallion
It's not very good to resize an image, but a character is perfect on every size, so I would say a character is more versatile :P I think backword-compatible or with widest range of browser support would be the word...Rsfsr
This doesn't work well when the <li> text wraps: The bullet doesn't remain unindented, and ends up looking like the beginning of a paragraph of text. This answer fixes this issue: https://mcmap.net/q/173235/-unicode-character-as-bullet-for-list-item-in-cssPachton
L
42

This is the W3C solution. You can use it in 3012!

ul { list-style-type: "*"; }
/* Sets the marker to a "star" character */

https://drafts.csswg.org/css-lists/#text-markers

Update: according to the comments this works in all modern browsers in 2021.

Lapidary answered 24/7, 2013 at 7:55 Comment(6)
I hear that in 3012, Internet Explorer finally works!Denbrook
This works in Firefox 48, but not in Chromium 51 or on my phone/tablet. On will have to use the li:before solution.Pasta
Works. Welcome to the future, ladies and gentlemen.Tusk
Thanks for the answer from the future, but In 2020, this works on Chrome, Firefox and Edge, but not Safari.Trireme
Hello from 2021. FYI this does work in Safari 14.1.Kalikow
People should probably use this as the primary answer, and then use css processors for compatibility.Malcolmmalcom
B
35

You can construct it:

#modal-select-your-position li {
/* handle multiline */
    overflow: visible;
    padding-left: 17px;
    position: relative;
}

#modal-select-your-position li:before {
/* your own marker in content */
   content: "—";
   left: 0;
   position: absolute;
}
<ul id="modal-select-your-position">
  <li>First item</li>
  <li>Second item</li>
</ul>
Brahe answered 13/1, 2013 at 8:36 Comment(3)
This is a great technique because if you don't do the absolute positioning of the character, then you end up with the "Bullet" being inline with the rest of the list item. That is very un-bullet-like behavior. So with this fix, you get the "bullet" off to the left of the list item just like you would with a normal bullet.Ethyne
Thank you for this! Exactly what I needed to get my bullets behaving again.Etem
This makes a wonderful navigation tree using '\21B3'! Thanks! It worked better than the other answers here. Also changed the padding-left in my design to 1em, which adapts well when your tree levels change size.Unwashed
M
15

Images are not recommended since they may appear pixelated on some devices (Apple devices with Retina display) or when zoomed in. With a character, your list looks awesome everytime.

Here is the best solution I've found so far. It works great and it's cross-browser (IE 8+).

ul {
  list-style: none;
  padding-left: 1.2em;
  text-indent: -1.2em;
}

li:before {
  content: "►";
  display: block;
  float: left;
  width: 1.2em;
  color: #ff0000;
}
<ul>
  <li>First item</li>
  <li>Second item</li>
</ul>

The important thing is to have the character in a floating block with a fixed width so that the text remains aligned if it's too long to fit on a single line. 1.2em is the width you want for your character, change it for your needs. Don't forget to reset padding and margin for ul and li elements.

EDIT: Be aware that the "1.2em" size may vary if you use a different font in ul and li:before. It's safer to use pixels.

Mulligan answered 17/2, 2014 at 15:14 Comment(2)
Perhaps add "height:1px" or similar to the li:before? That ensures that the float doesn't extend down to the next <li>, causing undesirable nesting.Discophile
Why the display:block; on li:before ? is it because by default its inline and you can't specify a width ?Bathsheeb
H
8

To add a star use the Unicode character 22C6.

I added a space to make a little gap between the li and the star. The code for space is A0.

li:before {
    content: '\22C6\A0';
}
Heder answered 30/8, 2013 at 12:55 Comment(0)
M
8

Today, there is a ::marker option. so,

li::marker {
  content: "\2605";
}
Mccready answered 5/1, 2021 at 9:10 Comment(1)
this answer deserves upvotes, while downvoting all others ;) As of feb. 2021 there is 86.58% browser coverage for pseudo element ::marker caniuse.com/?search=li%3A%3AmarkerForelli
C
5

As mentioned in these two comments, the modern approach is to use list-style-type or ::marker. You can also combine them depending on your use case.

One of the more notable setbacks with these methods is that you can't yet apply margin or padding to ::marker, and instead must rely on whitespace (as illustrated in the examples here) or use an offset method as outlined in the demo provided in 2.1 below.

1. Using list-style-type to set a custom marker

li { list-style-type: "🔧 "; }
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
</ul>

2. Using ::marker to style list-style-type

/* intentional whitespace, may vary cross-browser */
li { list-style-type: "★      "; } 
li::marker { color: red; }
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
</ul>

2.1 Spacing

While it's not immediately apparent in the demo above, the marker is moving away from the list as opposed to pushing itself into it. This means that it may fall outside of your grid and/or may become obscured by another element.

I've created a demo on Codepen that highlights the whitespace issue alongside two potential solutions depending on if you need to match the default ul styling or create something that's inside the parent container.


3. Using ::marker exclusively for variants:

li.one::marker { content: "🥇 "; }
li.two::marker { content: "🥈 "; }
li.three::marker { content: "🥉 "; }
<ul>
  <li class="one">1</li>
  <li class="two">2</li>
  <li class="three">3</li>
</ul>

Additional Resources:

Complicated answered 18/7, 2022 at 21:6 Comment(0)
E
4

A more complete example of 222's answer:

ul {
    list-style:none;
    padding: 0 0 0 2em;     /* padding includes space for character and its margin */

    /* IE7 and lower use default */
    *list-style: disc;
    *padding: 0 0 0 1em;
}
ul li:before {
    content: '\25BA';
    font-family: "Courier New", courier, "Lucida Sans Typewriter", "Lucida Typewriter", monospace;
    margin: 0 1em 0 -1em;   /* right margin defines spacing between bullet and text. negative left margin pushes back to the edge of the parent <ul> */

    /* IE7 and lower use default */
    *content: none;
    *margin: 0;
}
ul li {
    text-indent: -1em;      /* negative text indent brings first line back inline with the others */

    /* IE7 and lower use default */
    *text-indent: 0;
}

I have included star-hack properties to restore the default list styles in older IE versions. You could pull these out and include them in a conditional include if desired, or replace with a background-image based solution. My humble opinion is that special bullet styles implemented in this manner should degrade gracefully on the few browsers that don't support pseudoselectors.

Tested in Firefox, Chrome, Safari and IE8-10 and renders correctly in all.

Erk answered 18/7, 2013 at 2:7 Comment(1)
text-indent: -1em; is an important property if you have multi-line list items. Without it the second and subsequent lines alighn with the bullet rather than the previous line.Brasil
B
3
ul {
    list-style-type: none;    
}

ul li:before {
    content:'*'; /* Change this to unicode as needed*/
    width: 1em !important;
    margin-left: -1em;
    display: inline-block;
}
Brief answered 8/2, 2016 at 10:27 Comment(0)
U
2

I've been through this whole list and there are partially correct and partially incorrect elements right through, as of 2020.

I found that the indent and offset was the biggest problem when using UTF-8, so I'm posting this as a 2020 compatible CSS solution using the "upright triangle" bullet as my example.

ul {
    list-style: none;
    text-indent: -2em; // needs to be 1 + ( 2 x margin), and the result 'negative'
}

ul li:before {
    content: "\25B2";
    margin: 0 0.5em; // 0.5 x 2 = 1, + 1 offset to get the bullet back in the right spot
}

use em as the unit to avoid conflict with font sizing

Univalence answered 22/2, 2020 at 10:27 Comment(0)
R
0

Try this code...

li:before {
    content: "→ "; /* caractère UTF-8 */
}
Reuben answered 11/12, 2012 at 1:18 Comment(0)
M
0

To expand on the top answer, and address the issues brought up regarding the overflowing lines not indenting properly, you could make the list items padding-left 20px (for example) and the position relative. Then in the li:before, set the position to absolute and left -20px;

Example:

ul {
    list-style: none;
    padding: 0 0 0 20px;
}

ul li {
    position: relative;
}

ul li:before {
    content: '\2713';
    position: absolute;
    top: 0;
    left: -20px; // or whatever your padding-left is on the ul
    font-size: inherit;
    line-height: inherit;
}

I would have written this as a comment on the answer, but don't have enough points to post a comment, but hopefully this can help someone having this issue.

Mellette answered 10/1, 2023 at 0:2 Comment(0)
D
-1

This topic may be old, but here's a quick fix ul {list-style:outside none square;} or ul {list-style:outside none disc;} , etc...

then add left padding to list element

ul li{line-height: 1.4;padding-bottom: 6px;}
Daven answered 10/1, 2016 at 2:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.