CSS defines only three bullet shapes: disc, circle, and square. To get custom bullets, web designers use small bullet images. The network latency cost for these images is high, slowing down the web site. Instead, avoid bullet images and use Unicode symbol characters as bullets. Unicode bullets require nothing extra to download and provide thousands of bullet shapes to choose from.
Table of Contents
Bullet methods
Let's look at a few typical ways to control bullets on a list, and then a latency-friendly way using Unicode characters.
A typical bullet list using standard bullets
The default bullet is a filled circle. In CSS, set the list-style on the <li> tag to select between bullet shapes and numbering schemes (not discussed here). The three available shapes are usable, but uninspired.
- Disc
- Circle
- Square
| HTML | <ul> <li style="list-style: disc">Disc</li> <li style="list-style: circle">Circle</li> <li style="list-style: square">Square</li> </ul> |
|---|
A typical bullet list using image bullets
To use a custom bullet image, set the list-style to an image URL. Keep the image about the same size as the font.
|
|
|
| HTML | <ul> <li style="list-style: url(square_10x10_small.gif)">Small square</li> ... </ul> |
|---|
Alternatively, disable the list-style bullet and add a CSS background image to each list item. Background image bullets can use CSS sprites to combine multiple bullets into one image file, but they don't print if the visitor has disabled background printing (the default in most browsers).
|
|
|
| HTML | <ul> <li style="list-style: none; padding-left: 20px; background: url(squareplus_10x10_large.gif) left center no-repeat;">Plus square</li> ... </ul> |
|---|
Custom bullet images are usually small, so the download time is negligable. But every image has a network latency cost as the browser asks for and waits to get the image from the web server. Typical latencies range from 1/10 to 1/2 second. While these seem small, they add up quickly. If you have a dozen different custom bullets, the latency alone can add several seconds to your page's load time. That's very expensive for a few little bullets. To help the page load faster, use Unicode bullets instead of images.
A latency-friendly bullet list using Unicode symbol characters
Unicode has over 100,000 characters for letters, numbers, punctuation, and symbols that span the world's languages. In HTML, use � to insert a Unicode character, replacing 0000 with its unique hex number. For example, ✓ is a check mark symbol ✓, ✶ is a six-pointed star ✶, and ➔ is a right arrow ➔. There are thousands of symbols to choose from. FileFormat.info has excellent pages listing Unicode characters. A sampling of bullets is shown below and at the end of this article.
To use a Unicode bullet symbol, add it within a <span> in each list item. Float the span left and give it a 2em width (to make bullet spacing uniform). Disable normal bullets with list-style: none; and set the line-height a bit taller than the bullets or the floats will stair-step the bullet list.
|
|
|
| HTML | <ul class="unilist"> <li><span class="unibull">●</span> Filled circle</li> ... </ul> |
|---|---|
| CSS | .unilist li { list-style: none; line-height: 1.5em; } .unibull { float: left; width: 2em; } |
You can also use CSS 2.0 content insertion to add bullets. Add an empty <span> for each list item, float it left and give it a 2em width. Give each bullet type its own class and use a CSS :before selector and a content value to insert the bullet symbol. Use \0000 in CSS to select a Unicode character. This will work in current Safari, Opera, and Firefox browsers, but not Internet Explorer 7 and earlier. In older browsers, and IE, the bullets won't be shown.
|
|
|
| HTML | <ul class="unilist"> <li><span class="unibull u1"></span> Double circle</li> ... </ul> |
|---|---|
| CSS | .unilist li { list-style: none; line-height: 1.5em; } .unibull { float: left; width: 2em; } .u1:before { content: "\25C9"; } ... |
Alternatively, use a bit of Javascript to scan the DOM and insert bullets for <span> tags with specific class names. Use \u0000 in Javascript to select a Unicode symbol character. Of course, if the visitor's browser doesn't have Javascript enabled, the bullets won't show up. But according to browser statistics, 94% of web visitors now enable Javascript.
|
|
|
| HTML | <ul class="unilist"> <li><span class="unibull ju1"></span> Up triangle</li> ... </ul> |
|---|---|
| CSS | .unilist li { list-style: none; line-height: 1.5em; } .unibull { float: left; width: 2em; } |
| JavaScript | <script type="text/javascript"> var tags = document.getElementsByTagName("span"); for ( var i = 0; i < tags.length; i++ ) { if ( tags[i].className == "unibull ju1" ) tags[i].appendChild( document.createTextNode( "\u25B2" ) ); ... } </script> |
Comparisons
Comparing features
Standard bullets and image bullets work in all web browsers on all platforms. Unicode works in all modern browsers, but no browser supports all of Unicode's 100,000+ characters yet. Most browsers support all of the "dingbats" and other common symbols that make interesting bullets.
The standard bullets method is, well, standard. It's what all HTML authoring tools know how to do. The other methods require hand-coding.
Custom image bullets are obviously the most flexible. Graphic designers can create anything they like. But for simpler bullets, the Unicode approach gets thousands of bullet symbols cheaply without any images.
Image bullets can use multiple colors, but standard and Unicode bullets have a single color. Standard bullets take on the color of the list text. Unicode bullet colors are set by CSS and can differ from the list text. Image bullet colors are set once in the image, so if you need multiple bullets of different colors, you need multiple bullet images.
Image bullet sizes are fixed when the images are created. Standard bullet sizes match that of the list text. Unicode bullet sizes are set in CSS and can be larger or smaller than the neighboring text.
Since standard bullets and Unicode bullets are symbol characters in a font, they scale up and down smoothly. They are all anti-aliased and are crisp at any size. Image bullets, however, don't scale, and won't print as crisply.
Comparing sizes
The table below summarizes the size of a list with one bullet for each method. Image bullets add an image, of course, plus about 250 bytes for a HTTP response header sent by the web server along with the image file. Not surprisingly, image bullets have a bigger total size. But a few hundred bytes is too little to worry about.
| Type of data | Standard bullet | Image bullet | Unicode bullet |
|---|---|---|---|
| Compressed HTML | 86 | 91 | 104 |
| Compressed CSS | 0 | 0 | 119 |
| Compressed PNG (7 x 7) | 0 | 100 | 0 |
| HTTP response for image | 0 | 250 | 0 |
| TOTAL | 86 | 441 | 223 |
Comparing load times
To load a web page, the browser asks for the page's files, waits for a response, then reads their bytes off the network. Network latency increases the wait time, while low bandwidth increases the read time. The ideal network has zero latency and infinite bandwidth. In the real world, latencies are about 1/10th of a second between a US home and a US web site. Overseas visitors to the same site may see 1/5th of a second in latency, and a cell phone may pause for 1/2 second or more. Bandwidths vary from about 500 kilobytes/second for a US home, down to just 30 kilobytes/second for a cell phone.
The table below uses these numbers to estimate the load time impact of a list with just one bullet.
| Standard bullet | Image bullet | Unicode bullet | |
|---|---|---|---|
| Connection | Latency + Download | Latency + Download | Latency + Download |
| US home to US server 500 KB/s, 100ms latency |
none + 0.0002 = 0.0002 | 0.1 + 0.0011 = 0.1011 | none + 0.0005 = 0.0005 |
| International home to US server 100 KB/s, 200ms latency |
none + 0.0009 = 0.0009 | 0.2 + 0.0054 = 0.2054 | none + 0.0022 = 0.0022 |
| Cell phone to US server 30 KB/s, 500ms latency |
none + 0.0029 = 0.0029 | 0.5 + 0.0178 = 0.5178 | none + 0.0074 = 0.0074 |
Since the number of bytes for each method is tiny, the time spent reading them is trivial. It's the latency part of the load time that matters here, not the download time.
Custom image bullets require an external image file, while the other methods do not. The time spent waiting for the network to deliver that file is 100 times longer than it takes to read the file's bytes. If the page has lots of custom bullet images, this can have a noticable impact on the total page load time. Because Unicode bullets do not have external files to load, they have no latency delays. This makes them hundreds of times faster than image bullets.
These load times are just estimates. The real world is more complicated. Bandwidths and latencies vary from moment to moment based upon network and web server load. The latency on a cell phone can vary from 1/2 second to 3 seconds or more, depending upon signal strength. Pipelining, keep alives, caches, and parallel downloads also affect the results.
Conclusions
For today's Internet connections, latency is a bigger problem than bandwidth. Latency-friendly design reduces page load times by reducing the number of files required by a page. Pages load faster and demand less of the visitor's network connection and the web site's server.
Unicode bullets are less flexible than image bullets. But there are still thousands of Unicode bullet symbols to choose from, the method is simple, it avoids latency costs to download bullet images, and it has faster page load times.
Clearly, the bullet images can be cached. But recent performance studies by Yahoo! found that visitors rarely arrive with your content already in their cache. Instead, they have to download it again on every visit. For that initial download, the Unicode bullets are much faster. For subsequent page loads, the methods are all about the same.
Appendix: Gallery of bullets
There are literally thousands of Unicode symbol characters that could be used as bullets. Here are a few:
| Circles | Stars | Triangles | Arrows | Chess pieces |
| ◉ ◉ | ★ ★ | ▲ ▲ | ↝ ↝ | ♔ ♔ |
| ○ ○ | ☆ ☆ | △ △ | ⇉ ⇉ | ♕ ♕ |
| ◌ ◌ | ⚙ ⚙ | ▴ ▴ | ⇝ ⇝ | ♖ ♖ |
| ◎ ◎ | ✡ ✡ | ▵ ▵ | ⇢ ⇢ | ♗ ♗ |
| ● ● | ✢ ✢ | ▶ ▶ | ⇨ ⇨ | ♘ ♘ |
| ◐ ◐ | ✣ ✣ | ▸ ▸ | ⇰ ⇰ | ♙ ♙ |
| ◑ ◑ | ✤ ✤ | ▹ ▹ | ➔ ➔ | ♚ ♚ |
| ◒ ◒ | ✥ ✥ | ► ► | ➙ ➙ | ♛ ♛ |
| ◓ ◓ | ✦ ✦ | ▻ ▻ | ➛ ➛ | ♜ ♜ |
| ◦ ◦ | ✧ ✧ | ▼ ▼ | ➜ ➜ | ♝ ♝ |
| ◯ ◯ | ✩ ✩ | ▽ ▽ | ➝ ➝ | ♞ ♞ |
| ◴ ◴ | ✪ ✪ | ▾ ▾ | ➞ ➞ | ♟ ♟ |
| ◵ ◵ | ✫ ✫ | ▿ ▿ | ➟ ➟ | |
| ◶ ◶ | ✬ ✬ | ◀ ◀ | ➠ ➠ | Card suits |
| ◷ ◷ | ✭ ✭ | ◂ ◂ | ➡ ➡ | ♠ ♠ |
| ☉ ☉ | ✮ ✮ | ◃ ◃ | ➢ ➢ | ♣ ♣ |
| ♁ ♁ | ✯ ✯ | ◄ ◄ | ➣ ➣ | ♥ ♥ |
| ⚆ ⚆ | ✰ ✰ | ◅ ◅ | ➤ ➤ | ♦ ♦ |
| ⚇ ⚇ | ✱ ✱ | ◢ ◢ | ➥ ➥ | ♤ ♤ |
| ⚈ ⚈ | ✲ ✲ | ◣ ◣ | ➦ ➦ | ♧ ♧ |
| ⚉ ⚉ | ✳ ✳ | ◤ ◤ | ➧ ➧ | ♡ ♡ |
| ⚪ ⚪ | ✴ ✴ | ◥ ◥ | ➨ ➨ | ♢ ♢ |
| ⚫ ⚫ | ✵ ✵ | ◭ ◭ | ➩ ➩ | |
| ⚬ ⚬ | ✶ ✶ | ◮ ◮ | ➪ ➪ | Weather |
| ❍ ❍ | ✷ ✷ | ➫ ➫ | ☀ ☀ | |
| ○ ○ | ✸ ✸ | Checks | ➬ ➬ | ☼ ☼ |
| ✹ ✹ | ⎷ ⎷ | ➭ ➭ | ☽ ☽ | |
| Squares | ✺ ✺ | ⍻ ⍻ | ➮ ➮ | ☾ ☾ |
| ⌑ ⌑ | ✻ ✻ | ☑ ☑ | ➯ ➯ | ☁ ☁ |
| ■ ■ | ✼ ✼ | ✓ ✓ | ➱ ➱ | ☂ ☂ |
| □ □ | ✽ ✽ | ✔ ✔ | ➲ ➲ | ☃ ☃ |
| ▢ ▢ | ✾ ✾ | ➳ ➳ | ||
| ▣ ▣ | ✿ ✿ | X marks | ➵ ➵ | Fun |
| ▪ ▪ | ❀ ❀ | ☒ ☒ | ➸ ➸ | ⌚ ⌚ |
| ▫ ▫ | ❁ ❁ | ✕ ✕ | ➺ ➺ | ⌛ ⌛ |
| ◘ ◘ | ❂ ❂ | ✖ ✖ | ➻ ➻ | ⎈ ⎈ |
| ◙ ◙ | ❃ ❃ | ✗ ✗ | ➼ ➼ | ☄ ☄ |
| ◧ ◧ | ❄ ❄ | ✘ ✘ | ➽ ➽ | ☎ ☎ |
| ◨ ◨ | ❅ ❅ | ➾ ➾ | ☏ ☏ | |
| ◩ ◩ | ❆ ❆ | Hands | ☔ ☔ | |
| ◪ ◪ | ❇ ❇ | ☚ ☚ | Music | ☕ ☕ |
| ◰ ◰ | ❈ ❈ | ☛ ☛ | ♩ ♩ | ☘ ☘ |
| ◱ ◱ | ❉ ❉ | ☜ ☜ | ♪ ♪ | ☠ ☠ |
| ◲ ◲ | ❊ ❊ | ☝ ☝ | ♫ ♫ | ☢ ☢ |
| ◳ ◳ | ❋ ❋ | ☞ ☞ | ♬ ♬ | ☣ ☣ |
| ❏ ❏ | ❖ ❖ | ☟ ☟ | ♭ ♭ | ☤ ☤ |
| ❐ ❐ | ✍ ✍ | ♮ ♮ | ☥ ☥ | |
| ❑ ❑ | Diamonds | ☮ ☮ | ||
| ❒ ❒ | ◆ ◆ | Crosses | Dice | ☯ ☯ |
| ⬒ ⬓ | ◇ ◇ | ♰ ♰ | ⚀ ⚀ | ☸ ☸ |
| ⬓ ⬓ | ◈ ◈ | ♱ ♱ | ⚁ ⚁ | ♨ ♨ |
| ⬔ ⬔ | ◊ ◊ | ✙ ✙ | ⚂ ⚂ | ♻ ♻ |
| ⬕ ⬕ | ⬖ ⬖ | ✚ ✚ | ⚃ ⚃ | ♼ ♼ |
| ⬚ ⬚ | ⬗ ⬗ | ✛ ✛ | ⚄ ⚄ | ♽ ♽ |
| ■ ■ | ⬘ ⬘ | ✜ ✜ | ⚅ ⚅ | ⚐ ⚐ |
| ⬙ ⬙ | ✝ ✝ | ⚑ ⚑ | ||
| Hexagons | ✞ ✞ | Faces | ⚛ ⚛ | |
| ⬡ ⬡ | ✟ ✟ | ☹ ☹ | ⚠ ⚠ | |
| ⬢ ⬢ | ✠ ✠ | ☺ ☺ | ⚡ ⚡ | |
| ⬣ ⬣ | ☻ ☻ | ✈ ✈ | ||
| ✉ ✉ |
Not all browsers or operating systems support all of these symbols. When a symbol isn't supported, a browser may show an empty box (Safari and Opera), a question mark (Firefox), or an incorrect character (Firefox). Currently, Safari has the best Unicode support, followed by Opera, Firefox, and Internet Explorer. Macs and Windows Vista have more complete Unicode fonts than Windows XP or Linux. But this improves with each new software update.
Further reading
- Performance Research, Part 1: What the 80/20 Rule Tells Us about Reducing HTTP Requests. The first in a series of articles from Yahoo! about increasing web site performance. This one discusses the impact of making a large number of HTTP requests for individual files, and the latency cost they incur.
- Performance Research, Part 2: Browser Cache Usage - Exposed! The second in the Yahoo! series of web site performance. This article discusses the browser cache, and how little it actually helps.
- Latency-friendly bar charts using Unicode characters. Instead of using bar chart images, use a row of Unicode block characters to create bar charts that are faster to download and scale up or down with changes to the font size.
- Latency-friendly hierarchical menus using Unicode bullets and a bit of JavaScript. Use Unicode bullets as icons for open and closed states for nested menus, and a bit of JavaScript to toggle between bullets and show and hide the corresponding menu.

Some chars does not work!
Thanks a lot for this informations... but I still with one question...
- Why some chars, like "checks" does not work?
There any solution?
Regards!
Why some characters don't work
Unicode has about 100,000 characters defined. That's a lot for fonts, browsers, and operating systems to support. Right now, nobody supports them all, but support is improving quickly.
Until all OSes and browsers support all Unicode characters, web designers will need to do browser testing. As usual, Internet Explorer is one of the worst and Opera, Firefox, and Safari are the best. Windows Vista has large Unicode fonts, but Windows XP does not. So, IE on Windows XP does worse than the same version of IE on Windows Vista.
Symbols found in standard "ding-bats" fonts are widely supported, but more obscure math, astrology, and dentistry (!) symbols are not as well supported. Since Windows XP doesn't have its own Unicode fonts, it's usually the problem. None of the check marks are supported by IE7 or earlier on XP. Firefox 2 and Safari 3 on XP support half of the check marks. All of the browsers do better on Windows Vista, and better still on Linux and Mac OS X.
Post new comment