Creating Fancy Checkmark Icons with Pure CSS3

I was recently working on a personal project where I wanted to implement some cool “checkmark” icons like you see at left to spice up my unordered lists. I could’ve done it quite easily with the list-style-image property, but I was trying to keep my images and http requests to a minimum, so I wanted to figure out another way to do it (plus, the challenge sounded kind of fun).

I had just seen Nicolas Gallagher’s awesome pure css social media icons, though, and I thought, “If he can do that, than I could certainly create a simple check icon with just css3″. I did figure it out with some experimenting and testing, and today I’m going to show you how to achieve the same effect.

The #1 Rule of CSS3 Coding

Before we start on any project, we have to remember the number one rule of CSS3 coding. Well, actually it’s two rules:

  • It must be cross-browser acceptable. I’m not talking identical, but a CSS3 technique is not very useful if it destroys the experience for users with older browsers. Use progressive enhancement.
  • No worthless markup! I know CSS3 is fun, and it’s not bad to experiment, but if you have to add a whole bunch of non-semantic junk markup just to save yourself from needing to use an image, you’ve defeated the point.

These are the two principles that I regard to be the unchangeable law for using CSS3. So anyways, enough of my rant – I just feel with all the buzz about CSS3 that it’s very important to use it in a mature and responsible way. Let’s move on with the tutorial.

The Concept

Before we can start coding, we have to figure out what approach we’re going to take to create these icons. How is it going to be done?

Taking some inspiration from Nicolas Gallagher’s work, I think the best way would be to use the :before and :after pseudoclasses to generate the round circle and the checkmark shape. By using the unicode no-break-space (\00a0) as the content attribute, and the setting the display to block and styling it, we can create a huge variety of empty shapes. A checkmark icon lays well inside the boundaries of possiblity!

Also, in order to implement surefire progressive enhancement we’re going to use the :nth-of-type selector to make sure that only CSS3 capable browsers try to display the icons (older browsers will  fall back on simple, default bullet-points). The :nth-of-type is a lifesaver and hugely useful for this, because the support for it lines up exactly with support for the border-radius and transform properties that will be necessary to render the icons.

The Code

OK, now that we’ve got the general concept figured out, we can start coding. We’ll start with the html for a basic, unordered list (copied from html-ipsum.com).

<ul>
<li>Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu. Cras consequat.</li>
<li>Phasellus ultrices nulla quis nibh. Quisque a lectus. Donec consectetuer ligula vulputate sem tristique cursus. Nam nulla quam, gravida non, commodo a, sodales sit amet, nisi.</li>
<li>Pellentesque fermentum dolor.</li>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
<li>Aliquam tincidunt mauris eu risus.</li>
<li>Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus.</li>
<li>Vestibulum auctor dapibus neque.</li>
</ul>

We’ll start with a very basic CSS style that will be applied to all browsers:

ul{
margin: 12px;
padding: 0;
}
ul li{
margin: 0 0 12px 0;
font-size: .9em;
line-height: 1em;
}

Now, onto the fun part. First, we’ll style the list items (for CSS3 browsers only) to have additional padding on the left (to make room for the icons), to be positioned relatively so that we can absolutely position the icons, and to hide the default bullets:

body:nth-of-type(1) ul li{
list-style-type:none;
padding: 0 0 0 45px;
position:relative;
}

Now, using the :before pseudoclass we’ll add a small black circle to the left of each list-item – the first half of the icon. We use before so that it will nest behind the checkmark, which will be generated using :after. Here’s the code:

body:nth-of-type(1) ul li:before{
/*fill it with a blank space*/
content:"\00a0";

/*make it a block element*/
display: block;

/*adding an 8px round border to a 0x0 element creates an 8px circle*/
border: solid 9px #000;
border-radius: 9px;
-moz-border-radius: 9px;
-webkit-border-radius: 9px;
height: 0;
width: 0;

/*Now position it on the left of the list item, and center it vertically
(so that it will work with multiple line list-items)*/
position: absolute;
left: 7px;
top: 40%;
margin-top: -8px;
}

All that’s left is to create the checkmark and put it on top of the circle. We can do that very easily by giving the :after element a white border on the bottom and left, and then rotating it 45 degrees:

body:nth-of-type(1) ul li:after{
/*Add another block-level blank space*/
content:"\00a0";
display:block;

/*Make it a small rectangle so the border will create an L-shape*/
width: 3px;
height: 6px;

/*Add a white border on the bottom and left, creating that 'L' */
border: solid #fff;
border-width: 0 2px 2px 0;

/*Position it on top of the circle*/
position:absolute;
left: 14px;
top: 40%;
margin-top: -4px;

/*Rotate the L 45 degrees to turn it into a checkmark*/
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
}

We’re finsished! Here’s what the final product looks like:

All that remains now is to integrate it into your design (changing the border colors of the before/after elements if need be)!

Some Thoughts

So that’s it. In closing I have a few thoughts about this technique:

On the downside, relying on the :nth-of-type selector is a bit risky, since a browser that recognized that selector but didn’t support CSS rounded corners and rotation would end up rendering a distorted version of the icon. Some older versions of Opera have this problem. I think that’s a pretty small issue, though, since I’m not aware of any browsers (and certainly not any with more than negligible market share) that fit that description. Also, it could be argued that it’s not worth it just to avoid using one small checkmark image. I don’t think that’s necessarily true, but it is something to consider (for reference, the css code that created the icons is .57kb when compressed).

Overall, though, I think it’s a stylish, imageless touch that could fit well into a lot of design situations. It’s a creative use of CSS3, it doesn’t require extra markup, and it degrades with near perfect gracefulness, so overall I’m proud of the idea and think it’s pretty robust.

What are your thoughts? Do you think it’s a good idea? I’m looking forward to your feedback!

Written By Nick Parsons

Nick is the editor of Webitect and a developer + designer from Houston TX.

52 Comments

  1. Jay

    June 15th, 2010 at 06:59 pm

    Awesome technique. As always so unselfish, thanks for sharing. J

  2. Bill

    June 15th, 2010 at 07:10 pm

    Fun Stuff. The code example is missing a comment block terminator on the “position it on top of the circle”

  3. Nick Parsons

    June 15th, 2010 at 07:29 pm

    @Jay – Thanks, man, glad you enjoyed!

    @Bill – Good catch, it’s fixed now.

  4. Bill

    June 15th, 2010 at 07:40 pm

    It’s cool and twisted. If it were class based, it could be used with red x’s, or blank and checked, for applications…

  5. Designers' HQ » Creating Fancy Checkmark Icons with Pure CSS3

    June 16th, 2010 at 01:58 am

    [...] View full post… var a2a_config = a2a_config || {}; a2a_config.linkname="Creating Fancy Checkmark Icons with Pure CSS3"; a2a_config.linkurl="http://designershq.net/web-design/creating-fancy-checkmark-icons-with-pure-css3"; [...]

  6. Fecundvs

    June 16th, 2010 at 04:13 am

    I like this, although I think in practice I would just use an image for this type of list (one single image for all items). I agree with Bill that it becomes more useful with classes to have different icons and it would be even better for a numbered list where images for each item becomes impractical (1, 2, 3 or 10, 20, 30 or A, B, C etc) especially if you want numbers out of order (3, 4, 1, 2 for example).

    Thanks.

  7. Jacob

    June 16th, 2010 at 08:25 am

    That’s pretty slick. Nice work. I can definitely think of a few ways to mod this to meet my ‘needs’. Thanks.

  8. Catherine Azzarello

    June 16th, 2010 at 10:45 am

    Really cool puzzle solving! Isn’t CSS a fun game? :)

  9. ErnieChiara

    June 16th, 2010 at 11:23 am

    I agree with Fecundvs. While the realm of possibilities has continued to expand through CSS3 (which is exciting), IMHO using a simple image of only a few kb in this instance would not only suffice, but could be made as ‘fancy’ as you like and be viewed in all browsers. Thus is really nice work, though, and could be very useful for numbered lists, etc. as Fecundvs points out. Thanks for sharing! Keep up the good work!

  10. Cosmin Negoita

    June 16th, 2010 at 12:19 pm

    I’m actually loving this tutorial. It’s simple but still effecting and good looking. Thank you!

  11. B. Moore

    June 16th, 2010 at 01:22 pm

    No live demo?
    I see you have check marks on your site here but they are not the css3 version.
    What better demo than using it on your own site…

  12. Nick Parsons

    June 16th, 2010 at 01:32 pm

    @Bill – That’s a great idea. I might post a follow up with some more varieties included.

    @Fecundvs and @ErnieChiara – You’re absolutely right. It’s an interesting possibility, but in a some cases would just not be worth the trouble. I’m glad you liked the idea, though!

    @Catherine Azzarello – Sure is! I love seeing all the cool things that can be done with it.

    @B. Moore – I actually created this for a ThemeForest template I’m working on, so you’ll be able to check it out live once I get that finished.

  13. Jae Xavier

    June 16th, 2010 at 05:43 pm

    Cool tutorial. Can’t wait to try it out.

    Thanks :)

  14. Beben

    June 16th, 2010 at 11:07 pm

    i am agree with B.Moore, its not work in HTML Editor my friend (what’s wrong?)
    may be..:D

  15. Webstandard-Blog

    June 17th, 2010 at 02:20 am

    The pure css social media icons of Nicolas Gallagher are awesome, that’s true. But 20KB (CSS-File) only for some icons? That’s a little bit to much, or not? Sprite-Grafic for the Icons and some CSS-lines, is definitely less than 20KB.

  16. 160 Awesome Fresh Articles for Designers and Developers | tripwire magazine

    June 18th, 2010 at 12:41 am

    [...] Creating Fancy Checkmark Icons with Pure CSS3 [...]

  17. Jaap

    June 18th, 2010 at 09:25 am

    Why didn’t you use some UTF8 special characters? Most browsers should be OK with that now, that way, you can delete the whole :after thing at the end and just use this: (Hope it correctly displays this in the comment.)

    body:nth-of-type(1) ul li:before{
    /*fill it with a check mark*/
    content:"✔";
    color: snow;
    background-color: black;
    padding: 4px;

    /*make it a block element*/
    display: block;

    border-radius: 25px;
    -moz-border-radius: 25px;
    -webkit-border-radius: 25px;

    /*Now position it on the left of the list item, and center it vertically
    (so that it will work with multiple line list-items)*/
    position: absolute;
    left: 7px;
    top: 40%;
    margin-top: -8px;
    }

  18. Jaap

    June 18th, 2010 at 09:31 am

    One additional remark I forgot to make in my previous comment: you can then use either ✓ or ✔ as checkmark. And it also gives you the option to create an additional class which shows a (red) mark, for instance one of these: ✗, ✖, ✕.

    (I was a bit shocked to see that you were doing so much work just to create a check mark, nonetheless, it is very creatively thought of and made!)

  19. Nick Parsons

    July 2nd, 2010 at 12:03 pm

    @Webstandard-Blog – I wasn’t suggesting that Gallagher’s icons were good for practical use, merely stating that they were a creative experiment. You’re right, they’re rather overboard for real-life use when an image would be much smaller and would work cross-browser.

    @Jaap – That’s an excellent point, I’m not sure why I didn’t think of that. Guess I just had one of those “duh” moments. Thanks for mentioning it! That certainly makes the technique a lot more widely useful. Good thinking :)

  20. Joomla Web Developers

    July 20th, 2010 at 11:27 pm

    good stuff of css but the code is bit long for the 20 KB thing..can any body make it little bit less lines of coding for me here…

  21. June’s Best Resources for CSS3

    July 23rd, 2010 at 01:35 pm

    [...] 39. Creating Fancy Checkmark Icons with pure CSS3 [...]

  22. Drupal Web Developers

    July 26th, 2010 at 07:13 am

    Thanks for the coding jaap,i was looking for some one to answer differently you made it here,i learnt how to implement some special characters into the coding part..

  23. The Ultimate Roundup of 55+ CSS3 Tutorials

    August 9th, 2010 at 04:05 pm

    [...] 56. Creating Fancy Checkmark Icons with Pure CSS3 [...]

  24. The Ultimate Roundup of 55+ CSS3 Tutorials | luLUXE

    August 11th, 2010 at 03:50 pm

    [...] 56. Creating Fancy Checkmark Icons with Pure CSS3 [...]

  25. The Ultimate Roundup of 55+ CSS3 Tutorials « qeqnes | Designing. jQuery, Ajax, PHP, MySQL and Templates

    August 15th, 2010 at 01:20 pm

    [...] 56. Creating Fancy Checkmark Icons with Pure CSS3 [...]

  26. cathy tibbles

    August 17th, 2010 at 10:56 am

    Very good tutorial and easy to follow. Thankyou. (Not sure its practical, but who cares?) :)

  27. Justin

    August 18th, 2010 at 01:30 pm

    AWESOME tut. Just discovered this site and I think I will take a look around. :)

  28. Scott

    September 4th, 2010 at 07:25 am

    Ha, this first thing I thought when I started reading was “why not use UTF8?” As Jaap pointed out there are several “Wingdings” in Unicode. The first port of call any time you want to insert a symbol like that should be your Character Map ;)

    In addition to ✓ and ✔ there are even “ready-boxed” checks: ☑ and ☒

    Peace out y’all ☮

  29. harryplusk

    September 4th, 2010 at 07:40 am

    *p.s. The HTML code of the reference part is “Unordered list: Short items” and look like this (i deleted the signs):
    ul
    li Bethel Park schools: Readin’ and writin’ and iPads [post-gazette.com] /li
    li Explore Space with NASA HD for iPad [mashable] /li
    /ul

  30. Cory

    September 4th, 2010 at 10:21 am

    Excellent article and inspiring. Based on some of the comments, I took my shot at extending it and it appears to work rather well.

    http://corydorning.com/blog/creating-list-icons-pure-css3

  31. Creating Fancy Checkmark Icons with Pure CSS3 | Webitect » Web Design

    September 4th, 2010 at 09:03 pm

    [...] Creating Fancy Checkmark Icons with Pure CSS3 | Webitect [...]

  32. Thomas

    September 5th, 2010 at 06:53 am

    While I like digging into new techniques such this one, I would consider list-style-image as better choice to create this effect. Less risky, less code and after all much simpler to use.

  33. Jessicashen

    September 17th, 2010 at 01:38 am

    AWESOME tut. Just discovered this site and I think I will take a look around. Fun Game,isn’t it ?

    there is a good website to buy your favoruite sports shoes amd branded clothes
    http://www.ajfshoes.com

  34. Robert Tobys

    September 20th, 2010 at 10:21 am

    Great tut. This was just what I needed. Thanks for sharing!

  35. Creating List Icons with Pure CSS3

    September 26th, 2010 at 11:42 pm

    [...] waking up this morning, I came across a wonderful article about Creating Fancy Checkmark Icons with Pure CSS3, and wanted to extend the functionality beyond just checkmarks. After all, what if I want to show [...]

  36. thomas

    January 25th, 2011 at 07:41 am

    No live demo? :(

  37. 30 примеров того, что можно сделать при помощи CSS3

    January 26th, 2011 at 05:30 am

    [...] 14. Красивый список [...]

  38. Aufzählungen & Listen – Webdesign liegt im Detail « Blog « Advitum Webdesign

    February 1st, 2011 at 02:12 pm

    [...] Creating Fancy Checkmark Icons with Pure CSS3 [...]

  39. Faraz

    March 20th, 2011 at 04:07 am

    I like the way of explaining in this tutorial,very resourceful and useful post for css beginners and even experts.

  40. Raju

    May 2nd, 2011 at 07:36 am

    Really super posting…

  41. Lance

    May 8th, 2011 at 01:06 pm

    The ✗ ✖ ✕ ✓ or ✔ Jaap suggests is more elegant. Another step would be to attach a custom font containing just the few bullet characters. In that case you could even redefine x and y as ✗ and ✓. The extra file weight would be minimal especially in you used the technique for other icons.

    body:nth-of-type(1) ul li:before{
    content:”x”;
    font-family: “MyIcons”;
    display: block;
    border: solid 9px #000;
    border-radius: 9px;
    -moz-border-radius: 9px;
    -webkit-border-radius: 9px;
    height: 0;
    width: 0;
    position: absolute;
    left: 7px;
    top: 40%;
    margin-top: -8px;
    }

  42. Creating List Icons with Pure CSS3 | Cory Dorning

    May 9th, 2011 at 02:42 pm

    [...] waking up this morning, I came across a wonderful article about Creating Fancy Checkmark Icons with Pure CSS3, and wanted to extend the functionality beyond just checkmarks. After all, what if I want to show [...]

  43. designarti

    July 25th, 2011 at 12:22 am

    So many characters to use and get wonderful effects with the rotate option…
    Excellent technique!

  44. 109 interesantes tutoriales y recursos CSS3 | Digisolnet Blog

    July 30th, 2011 at 06:47 am

    [...] Creación de puntos de fantasía con CSS3 [...]

  45. Luke

    August 15th, 2011 at 03:11 pm

    Amazing what can be done with css now ie has stopped holding back web development.

  46. CSS3 Tutorial and Resources | Avazio

    August 17th, 2011 at 09:58 am

    [...] UI – avoid recutting UI graphics for mobile •  Flexible mobile first layouts with CSS3 •  Creating fancy bullet points with pure CSS3 •  Get the best out of CSS3 •  CSS3 – to infinity and beyond •  Push your web design [...]

  47. Bryan Salva

    August 19th, 2011 at 11:20 am

    Neither these icons or Gallagher’s social icons are practical yet (except possibly in some mobile applications) thanks to browser differences. That being said they look great, are coded well and make for an awesome concept. Good work!

  48. Mark

    March 22nd, 2012 at 09:27 am

    Great demo. It’s amazing how a few simple images can clean up the page design.

  49. Derek

    April 8th, 2012 at 06:23 pm

    One item to note–when I tried this in IE9, the checkmark wasn’t rotated. After adding “-ms-transform: rotate(45deg);”, everything worked like a charm.

  50. Agência de comunicação Sonna Creative

    April 26th, 2012 at 04:31 pm

    Great! Very interesting!

  51. bellakristen

    April 30th, 2012 at 03:37 am

    I Love the way you designed.Really impressive.Good!

  52. Gautam Lakum

    May 12th, 2012 at 05:29 am

    Really helpful. I was bored using default check icons. will try this :)

What Do You Think?