172

I realize one can specify a custom graphic to be a replacement bullet character, using CSS attribute:

list-style-image

And then giving it a URL.

However, in my case, I just want to use the '+' symbol. I don't want to have to create a graphic for that and then point to it. I'd rather just instruct the unordered list to use a plus symbol as the bullet symbol.

Can this be done or am I forced to make it a graphic first?

idStar
  • 10,674
  • 9
  • 54
  • 57

19 Answers19

195

This is a late answer, but I just came across this... To get the indenting correct on any lines that wrap, try it this way:

ul {
  list-style: none;
  margin-left: 0;
  padding-left: 0;
}

li {
  padding-left: 1em;
  text-indent: -1em;
}

li:before {
  content: "+";
  padding-right: 5px;
}
Mike T
  • 2,536
  • 2
  • 18
  • 9
  • 2
    For me, it works better to use ch as the unit of measurement, specifically to do `text-indent: -2ch` to account for the + sign and the space after it, then `padding-right: 1ch` to add that space. Still, a big +1. – cobaltduck Aug 10 '16 at 15:58
94

The following is quoted from Taming Lists:

There may be times when you have a list, but you don’t want any bullets, or you want to use some other character in place of the bullet. Again, CSS provides a straightforward solution. Simply add list-style: none; to your rule and force the LIs to display with hanging indents. The rule will look something like this:

ul {
   list-style: none;
   margin-left: 0;
   padding-left: 1em;
   text-indent: -1em;
}

Either the padding or the margin needs to be set to zero, with the other one set to 1em. Depending on the “bullet” that you choose, you may need to modify this value. The negative text-indent causes the first line to be moved to the left by that amount, creating a hanging indent.

The HTML will contain our standard UL, but with whatever character or HTML entity that you want to use in place of the bullet preceding the content of the list item. In our case we'll be using », the right double angle quote: ».

» Item 1
» Item 2
» Item 3
» Item 4
» Item 5 we'll make
   a bit longer so that
   it will wrap

Community
  • 1
  • 1
  • 1
    Your solution worked, in combination with the :before pseudo-selector that you and @Tieson T. both point to. I liked that you called out how the various attributes on
      work in concert to mimic bullet indentation.
    – idStar Oct 08 '11 at 21:08
  • 10
    This is how I put it together, which worked: ul { font-size: 14px; line-height: 16px; list-style: none; margin-left: 0; padding-left: 1em; text-indent: -1em; } li:before { content: "+ "; } I did have to put a space after the + symbol, but it looks reasonably well aligned. – idStar Oct 08 '11 at 21:09
  • 6
    Unfortunately with this method the bullet sign gets included in selections which is not the case for the normal bullets. – Konrad Höffner Aug 02 '12 at 12:41
82

This is the W3C solution. Works in Firefox, Chrome and Edge.

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

http://dev.w3.org/csswg/css-lists/#marker-content

ul { list-style-type: " "; }
<ul>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
</ul>

You can also style that inline. Combine single ' and double quotes " to avoid conflict:

<ul style="list-style-type: ' ';">
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
</ul>

If you can't risk to write unicode in your source code you still can set the HTML entity (ie: &#x1F514;) in the list-style-type and it will be properly rendered (ie: ) - Run the code snippet to try it out.

<ul style="list-style-type: '&#x1F514; ';">
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
</ul>
Xavi Montero
  • 9,239
  • 7
  • 57
  • 79
Handsome Nerd
  • 17,114
  • 22
  • 95
  • 173
  • 3
    Although it *seems* to work in current versions of Firefox, the result is extremely ugly: custom bullet is placed right in front of text content (snapping to it), *almost* as if `li:before {content:"…";}` was used without any other indentation and alignment. – Anton Samsonov Jul 15 '16 at 13:18
  • 3
    @AntonSamsonov it seems extremely pretty to me. – Handsome Nerd Jun 05 '21 at 21:04
  • 4
    I needed to an SVG instead of the default marker, so I used ```ul { list-style-image: url(assets/...); }``` -> Works perfectly! – MikhailRatner Feb 17 '22 at 08:51
  • Wow, didn't know this was a thing way back in 2013! Without a doubt it's the simplest answer to the question—no hacks, full support by all the major browsers. This should be the accepted answer. – Kal Sep 08 '22 at 05:35
66

So many solutions.
But I still think there is room for improvement.

Advantages:

  • very compact code
  • works with any font size
    (no absolute pixel values contained)
  • aligns rows perfectly
    (no slight shift between first line and following lines)

ul {
 position: relative;
 list-style: none;
 margin-left: 0;
 padding-left: 1.2em;
}
ul li:before {
 content: "+";
 position: absolute;
 left: 0;
}
<ul>
  <li>Curabitur non nulla sit amet nisl tempus convallis quis ac lectus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec velit neque, auctor sit amet aliquam vel, ullamcorper sit amet ligula. Pellentesque in ipsum id orci porta dapibus.</li>
  <li>Nulla porttitor accumsan tincidunt. Mauris blandit aliquet elit, eget tincidunt nibh pulvinar a. Aliquet quam id dui posuere blandit. Curabitur non nulla sit amet nisl tempus convallis quis ac lectus.</li>
</ul>
Jpsy
  • 20,077
  • 7
  • 118
  • 115
  • 3
    this is the very best – user3168511 Aug 21 '17 at 15:45
  • 1
    This is a better answer in my opinion because it points out how you can customize other details as well. And it also has the "Run code snippet" attached! – Ionut Ciuta Apr 01 '18 at 09:57
  • 1
    This is should be the answer. Clean and simple – EvilDr Aug 22 '18 at 08:20
  • 2
    I was looking for a solution using an image and tried lots of answers, but this one worked best for me! I was able to use `content: url('link-to-my-asset.svg');` and set the image width and padding between the bullet and content. Thanks! – AnnieP May 23 '19 at 17:33
  • This is a good answer. However, I needed a solution which could support column-count as well – Kushagr Arora Jul 21 '20 at 04:29
  • 1
    Great answer! Like @KushagrArora I was looking for a multi-column answer, but I got it to work by adding absolute positioning to the `
  • ` instead
  • –  Nov 24 '20 at 18:28
  • 1
    This is perfect! – Felix Dec 15 '20 at 19:22