Requested by several designers at Yahoo! for the original YSlow logo PSD to be used in promotional materials such as t-shirts, posters, flyers, etc in some events that occurred along this year, I had no idea where it was ever since I joined the Exceptional Performance Team to take care of YSlow amongst other performance tools. In order to solve this problem I decided to rebuild it from scratch because it doesn’t seem so complicated, the problem was I’m a speed freak, not a designer so inspired by the famous pure css Twitter fail whale I put my CSS muscles to work out focusing obviously on performance to provide those designers a scalable YSlow logo for their delight as well as potentially having a smaller image payload to be used on the web.

The Challenge

It was an interesting challenge from performance perspective since the less code I use the smaller the final image would be and how fast it would perform (rendering time). My goal was to achieve a one-size-fits all solution to be used in the wild on the web. Besides performance, as a frontend engineer I was also interested in how CSS3 could help solve this issue (cross-browser possibly) and the limitations imposed.

I use Chrome for development so my first goal was to make it happen for this one first before making it cross-browser compatible. It was also easy to benchmark the rendering time which was my main point of concern when talking about CSS3 background gradients, border radius, transformation, etc.

Getting my Hands Dirty with CSS3 Cooking

Having JSFiddle as my playground was really helpful because it was a trial and error task plus I could keep track of versions and share so easily. Chrome Developer Tools: Element Styles played also an important role letting me test my changes on-the-fly.

Here is my JSFiddle playground where you can see the code and final image result:

The three images on Result tab from top-down: original (250px width), pure CSS3 with 250px width and pure CSS3 with 50% width. If you’re reading this post on Chrome you’re expected to get better results. JSFiddle also allows you to fork the code and apply your own changes, be my guest.

With 21 DOM elements (22 counting the <style> block) and using uneven border-radius for geometries, background gradients to make it shiny, rounded and more realistic and some transform rotations were enough to finally get the YSlow speedometer logo without the red needle. My first attempt was to use DOM element borders to achieve a pointy triangle which works fine but unfortunately it did not scale due to percentage values not being allowed on border-width and background gradients are not applied to borders either making it not shiny as in the original image. When I hit this wall I pinged Thierry Koblentz to the rescue. He eats CSS not only for breakfast and is always up for CSS challenges. It was impressive, he came up with a very nice solution using rotated displaced DIVs hiding the undesired parts with overflow:hidden which allowed me to make it shiny through background gradient. As a plus he also included a nice transition that smoothly animates the needle to the max value when hovering.

Reached my goal for Chrome using basically W3C specification for CSS3 and a few -webkit- prefixes, it was time to attack the other browsers, so I started adding other vendors prefixes like -moz-, -o-, -ms- and filter for Internet Explorer.

Cross-Browser Results

I got very disappointed with the cross-browser results and after spending some time trying to figure out a way to fix for all browsers without increasing the CSS code or adding more HTML elements I gave up and played the John Lennon: “Imagine there’s no cross-browser issue…” (I wonder how come our honorable Performance Calendar curator hasn’t thought about such song before).

The original image (PNG24)

original YSlow logo in PNG24 format

The screenshots for the tested browsers with comments

Browser Vendor Specific CSS3 W3C CSS3 only
Chrome 15 yslow logo on chrome 15 screenshot

Best one

yslow logo w3c only on chrome 15 screenshot

Faded, bad needle

Firefox 8 yslow logo on firefox 8 screenshot

Misplaced needle

yslow logo w3c only on firefox 8 screenshot

Too faded, bad needle

Opera 11 yslow logo on opera 11 screenshot

Misplaced needle, broken glass

yslow logo w3c only on opera 11 screenshot

Too faded, broken glass

Safari 5
including iOS5
yslow logo on safari 5 screenshot

Good one

yslow logo w3c only on safari 5 screenshot

Faded, Atari 2600-like

Firefox 3 yslow logo on firefox 3 screenshot

Salvador Dali’s clock

yslow logo w3c only on firefox 3 screenshot

Too faded, Atari 2600-like

IE 6 yslow logo w3c only on internet explorer 6 screenshot

Cropped European Union flag-like

yslow logo w3c only on internet explorer 6-9 screenshot

Cropped European Union flag-like

IE 7 yslow logo on internet explorer 7 screenshot

Micronesia flag-like

IE 8 yslow logo on internet explorer 8 screenshot

Atari 2600-like

IE 9 yslow logo on internet explorer 9 screenshot

Somewhat rounded, broken needle

Interesting how the W3C only versions fallback “gracefully”, that shows no browser is strictly following specs or either the specs are not fully defined yet by the time of this writing. Even not fully resembling the original, with some exceptions, they all look like a speedometer gauge somehow, except er, guess who?

With that pure CSS3 image working decently at least on Chrome I was able to provide the designers what they were after and that was enough for me to start my performance benchmarking. I know one might argue it’s possible to make it work better on other browsers with more DOM elements and/or more CSS selectors/rules, but that was a time consuming task and I was working on it during my spare time, so enough with CSS and let’s see what we are here for.


In order to compare real image files versus CSS3 generated ones, I created a few pages containing only one image per page, either real files URL and data URI (&ltimg src="...">) or CSS3 (HTML + CSS <style> block in the same page).


Hosting these pages in a local Apache server I was able to fetch them with and without compression (Accept-Encoding: gzip,deflate) via curl getting the content length for the CSS3 and data URI ones and the real images URL obviously without compression. The minified with compression lengths were used as payload per page in this benchmark.


Adding a small script at the bottom of these pages that reloads the page 100 times with 1 second interval using sessionStorage for counting and with Chrome Developer Tools: Timeline Panel recording the page activity, I was able to export the logged data then with a NodeJS script I could extract and filter only the timing related to the rendering activity, cleaning the top and bottom 5% of the sample to remove some noisy data then getting the average in milliseconds.

The compared versions of YSlow logo image

Type Pros Cons Payload (bytes) Rendering (ms)
CSS3 W3C “Standard”, small Not x-browser yet, extra markup 807 4.436
CSS3 -o- Works on Opera :-) Vendor specific, extra markup 811 -
CSS3 -moz- Works on Firefox :-) Vendor specific, extra markup 815 -
CSS3 -ms- Works on IE :-) Vendor specific, extra markup 945 -
CSS3 -webkit- Works on Chrome/Safari Vendor specific, extra markup 977 11.233
CSS3 all Covers “all” browsers, small, animation Unused rules, extra markup 1400 11.238
WebP Smallest image file Not supported by all major browsers, no transparency 4066 1.769
WebP inline Smallest file Non x-browser, no transparency, non IE < 8 4175 5.701
JPG inline Smaller file, x-browser No transparency, non IE < 8 7881 3.313
JPG Smaller image file, x-browser No transparency 7926 1.768
PNG8 Small image file, x-browser, transparency Up to 256 colors 8269 1.854
PNG8 inline Small file, transparency Up to 256 colors, non IE < 8 8399 4.267
PNG24 High quality, alpha channel Large image file, buggy on IE < 7 27391 1.736
PNG24 inline High quality, alpha channel Large file, non IE < 8 27704 5.968

Which leads to the following chart:

Payload vs Rendering

CSS3 generated images can achieve smaller payloads compared to regular images either URL or data URI ones. In this YSlow logo example, the W3C standard CSS3 is roughly 34 times smaller than PNG24 image version. Data URI versions of the same image type have around the same payload after compressed, they get increased a few bytes only, interesting in this case the inline version of JPG is slightly smaller than the regular JPG image file.

On the other hand CSS3 generated images rendering time is worse than regular images, being around 6.5 times slower than the PNG24 version. The inline versions more than double the rendering time when compared to their regular image file versions. The CSS3 W3C standard version rendering performed 2.5 times faster than -webkit- or the one with all browser vendors prefixes, this doesn’t necessarily mean it’s really faster because per the screenshots results above none of them triggered all the CSS rules to render the logo properly according to the original version.

These rendering times were measured just by displaying the static images on the page without any hovering user interaction that animates the gauge needle on CSS3 versions. These numbers would likely to be increased in the case-scenario where users are allowed to hide-and-show or drag-and-drop images over the viewport triggering several repaint, reflow and restyle on these DOM elements.

Comparing apples-to-apples quality-wise, CSS3 with all prefixes or -webkit- on Chrome are comparable to the PNG24 version, both have transparency background and no pixelation. CSS3 is 34 times smaller, 6.5 times slower (in order of milliseconds) and has the advantage of keeping the same payload for different sizes while PNG would increase when resized from the original source (PSD when available) to avoid quality loss, however users are not able to save CSS3 as image without taking screenshots.

Are we there yet?

Not really, hopefully in the near future we’ll get rid of browser vendors specific prefixes and have a one-size-fits-all CSS solution that works equally in all browsers, but even when we get there, it’s a very time consuming task to create images from scratch using DOM elements and styles manually, an illustrator tool to aid drawing is high demanded for such task where one could drag over Bézier curves adjusting the control points in order to get the correspondent directives to CSS3 border-radius shaping geometric lines properly.

2012-02-07 Update: IE 6-9 screenshots and typo, according to comments below


Marcel Duran Photo

Marcel Duran is the Front End Lead for Yahoo!'s Exceptional Performance Team. He has been into web performance optimization on high traffic sites in Yahoo! Front Page and Search teams where he applied and researched web performance best practices making pages even faster. He is now dedicated to YSlow and other performance tools development, researches and evangelism. His goal is to make the web even faster and believes there is no such thing as "a few milliseconds won’t cause any harm".

26 Responses to “Pure CSS3 images? Hmm, maybe later”

  1. Alexandre Morgaut

    I’d be curious to see how it would compare to a SVG version which might be more adapted than CSS for such purpose ;-)

    Still, this exercise was very informative. On my Safari 5.1.1, the result looks like the best one. So yes there is hope for better support soon :-)

  2. Joacim Boive

    Great stuff!

    An additional benefit of generating images (or what-have-U) with code, is that they don’t deteriorate if/when the users zoom in on the page (to increase text-size for instance).

    Not everyone is a 20-year old with 20/20 vision… ;-)


  3. Adventskalender vom 11. Dezember « F-LOG-GE

    [...] Der Performancekalender hat einen sehr interessanten Artikel für CSS-Spezialisten parat. Der Autor erstellt das Logo von YSlow mittels HTML und CSS und vergleicht das Ergebnis auf vielen Ebenen. Er zeigt die Optik ohne Vendor-Prefixes und mit [...]

  4. Tony Gentilcore

    +1 to Alexandre’s comment. Excellent methodology, but probably barking up the wrong tree. SVG is designed for this; CSS is not. All the modern HTML5ey browsers support SVG-in-HTML, so I’d be really interested in any follow up work comparing SVG to PNG performance.

  5. Michael Howell

    Agree with Morguat. Every advantage CSS images have, SVGs have.

  6. Jo

    Thanks for the tests. Wonder to know how long does it take you to convert the images into CSS3.

  7. Rafael Hengles

    Why do you have the same image from IE 6 to 9? That’s a bit misleading.

    Here’s what I got on IE9:

  8. Dan

    Really interesting (and entertaining) article – but I’m sad to say I’ve become too skeptical to believe that these features of CSS3 will ever be usable in my lifetime. It’s all very clever, but I get the feeling that the only people pushing the boundaries with it will be this generation’s equivalent to ASCI artists (or the hobbyists who build working engines out of paperclips and egg cartons).

    We’re waiting on unreleased browsers to make this work, so we’ll have to wait for all of the current ones to die out. I dread to think how long that will take, I’ve spent 10yrs waiting for IE6 to drop dead! I really want full CSS3 support to happen sooner rather than later (I need column-span in my life), I just can’t see the light. Am I just being a pessimist?

  9. Marcel Duran

    Alexandre, Tony, Michael and Dan:
    You’re right, SVG is more suitable for this task but I have no experience with it. I thought this would be an interesting personal/frontend challenge reminding me my good ol’ times of BBS designing cool ASCII Art logos, like Dan said.

    It took me around 6-8 hours.

    Sorry, it’s supposed to be IE6-7 I don’t even have IE8-9 in my WinXP box, thanks for the screenshot.

  10. Imagine / Stoyan's

    [...] Challenged by Marcel and inspired by another idea by Nicholas (upcoming, stay tuned!) here's the beginning. [...]

  11. Performance Calendar » Beyond Bandwidth: UI Performance

    [...] Pure CSS3 images? Hmm, maybe later (Marcel Duran) – pure CSS3 images are awesome but perhaps impractical, as they trade less bandwidth for decreased rendering speed (it turns out that images render faster) [...]

  12. Lennie

    Typo in paragraph title: “Getting my Hands Dirt with CSS3 Cooking” I think you mean dirtY. :-)

  13. Jordan Terry

    Brilliant article!
    Like you say, maybe later. Would be great to use it in Client work thought!

  14. Beyond Bandwidth: UI Performance | 13fqcs

    [...] Pure CSS3 images? Hmm, maybe later (Marcel Duran) – pure CSS3 images are awesome but perhaps impractical, as they trade less bandwidth for decreased rendering speed (it turns out that images render faster) [...]

  15. Perfection kills » Profiling CSS for fun and profit. Optimization notes.

    [...] Timeline tab allows you to export data as JSON. First time I’ve seen this done was by Marcel Duran in this year’s Performance Calendar. Marcel used node.js and a script to parse and extract [...]

  16. Otavio Dias

    Images in css3? My images are created with milk with pear and ovomaltimo. Hahaha. My best regards to you, my friend. []s

  17. Profiling CSS for fun and profit. Optimization notes. | 13fqcs

    [...] Timeline tab allows you to export data as JSON. First time I’ve seen this done was by Marcel Duran in this year’s Performance Calendar. Marcel used node.js and a script to parse and extract [...]

  18. JSSpy » Profiling css for fun and profit. optimization notes.

    [...] Timeline tab allows you to export data as JSON. First time I’ve seen this done was by Marcel Duran in this year’s Performance Calendar. Marcel used node.js and a script to parse and extract [...]

  19. 复杂应用的 CSS 性能分析和优化建议 | Z.J.T Blog

    [...] JSON 格式的数据,我第一次看到这样功能是在今年的 Performance Calendar 上,由Marcel Duran 完成的,他用 node.js [...]

  20. lonalily

    i like it thnkans

  21. Profiling CSS for fun and profit. Optimization notes. | InfoLogs

    […] Timeline tab allows you to export data as JSON. First time I’ve seen this done was by Marcel Duran in this year’s Performance Calendar. Marcel used node.js and a script to parse and extract […]

  22. 有益 | 复杂应用的 CSS 性能分析和优化建议

    […] JSON 格式的数据,我第一次看到这样功能是在今年的 Performance Calendar 上,由Marcel Duran 完成的,他用 node.js […]

  23. 10 Principles of Sustainable Virtual Design VI – WPO that helps, not hurts, Sustainability | Sustainable Virtual Design

    […] SVG vector graphics are more efficient than bitmaps, as are images created completely in CSS. […]

  24. Sabina

    Sem falar nos projetos resikdenciais quue acabam fazendo
    com que o cliente sinta-se em sua casa dos sonhos, j. Behind my back, my
    friends say: que sou fria e metida – That I am stuck up.
    o para determinados tipos de empresas, por exemplo, as multinacionais com sede em v.


    Need for Speed: Rivals mettra en vedette un jeux similaire à un besoin de 2010 Need for Speed: Hot Pursuit titre
    dans la franchise Need for Speed avec des voitures exotiques et de la police poursuites à haute vitesse.
    Les joueurs prennent le rôle d’un coureur ou un flic, avec de
    chaque côté de la loi offrant son propre ensemble
    de défis, les risques et les récompenses. Rivals mettra
    en vedette onze gadgets évolutifs tels que les PGE,
    ondes de choc et la possibilité de faire
    appel à des barrages routiers. Le jeu se déroule dans le une ville nomme ‘Redview County’, une zone de monde ouvert qui est l’hôte de déchets entre police et aux voleurs.
    Le monde ouvert mettra en vedette une structure similaire à un besoin de 2012
    for Speed: Most Wanted, avec plusieurs sauts, des pièges de vitesse et les voitures à débloquer.

Leave a Reply

You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>
And here's a tool to convert HTML entities