PrefixFree: Break Free From CSS Prefix Hell
This article is the first piece in our new series introducing new, useful and freely available tools and techniques presented and released by active members of the Web design community. Lea Verou is well-known for her experiments with CSS and JavaScript and in this post she presents her recent tool, prefixfree, which will hopefully help you break free from the CSS prefix hell.
So What’s the Problem With Prefixes?
I’m sure we all agree that CSS3 is pretty cool and that it enables us to do things that were previously impossible. But those of us who use CSS3 a lot have surely experienced prefix hell, as seen in the snippet below (from a real style sheet!):
.download {
position: absolute;
top: 1em;
left: -1.5em;
width: 6em;
height: 6em;
padding: 1em 0;
background: #80A060;
background-image: -webkit-linear-gradient(transparent, rgba(0,0,0,.3));
background-image: -moz-linear-gradient(transparent, rgba(0,0,0,.3));
background-image: -o-linear-gradient(transparent, rgba(0,0,0,.3));
background-image: -ms-linear-gradient(transparent, rgba(0,0,0,.3));
background-image: linear-gradient(transparent, rgba(0,0,0,.3));
color: white;
line-height: 1;
font-size: 140%;
text-align: center;
text-decoration: none;
text-shadow: .08em .08em .2em rgba(0,0,0,.6);
-webkit-border-radius: 50%;
-moz-border-radius: 50%;
border-radius: 50%;
-webkit-box-shadow: .1em .2em .4em -.2em black;
-moz-box-shadow: .1em .2em .4em -.2em black;
box-shadow: .1em .2em .4em -.2em black;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-ms-transform: rotate(15deg);
-webkit-transform: rotate(15deg);
-moz-transform: rotate(15deg);
-o-transform: rotate(15deg);
-ms-transform: rotate(15deg);
transform: rotate(15deg);
-webkit-animation: none;
-moz-animation: none;
animation: none;
}
I’m not saying that prefixes are bad. We need them. But the reality is that, in most cases, they cause maintenance troubles, they bloat CSS files, and they make it harder to tweak values (because you have to do it up to five times).
A Solution: prefixfree
The code I write in my live demo slides and presentations doesn’t have any prefixes, even for things like @keyframes or the transition property, which aren’t yet supported anywhere prefix-less. To be able to do this, I wrote a script that detects the prefix of the current browser and adds it where needed. Recently, I thought, why not adapt the script to process all of the CSS code on a page, so that the CSS in my style sheets is as elegant as the code in my demos? Shortly after, prefixfree was born.
The script essentially does everything in JavaScript’s power to allow you to completely forget about vendor prefixes. It processes linked style sheets (except the ones in @import rules), embedded style sheets, inline styles, even CSS added afterwards (such as in new elements, CSSOM property changes and lookups). And if, in rare cases, you want to use a different definition for a different engine (for example, because one’s implementation is buggy), you can still use prefixed CSS.
The good thing about prefixfree is that once the browser vendors drop their prefixes for CSS3 properties, you can just remove the script and your CSS will still work. Your code will continue to be valid CSS3 (so valid that it will even pass a CSS validator). Your code does not depend on it (unlike CSS preprocessors); rather, it functions more like a polyfill, smoothing out browser differences for the time being.
Another useful feature is that the script auto-detects which properties need prefixing. Its code has no property list. It detects which properties are supported and which of them are supported only with a prefix. Values, selectors and @rules are based on predefined lists, but they are still prefixed only when needed. No browser sniffing is involved; everything is based on feature detection.
Unlike other solutions, prefixfree adds the current prefix at runtime, so the user downloads a much smaller CSS file. Some might argue that pre-processed CSS is faster because no client-side processing is involved. To some extent, this is true, but in my experiments there was no significant lag. With the borderline exception of Opera, it was hardly noticeable.
Also, there are a few server-side solutions, but there are two main issues with those. Firstly, the file size of the CSS file is still huge, as it has to contain all the prefixes (and the unprefixed versions). And secondly, the server-side script has to maintain lists of properties at all times, because they cannot be automatically detected, like with prefixfree.
So, what does the rule above become with prefixfree? It becomes this beauty:
.download {
position: absolute;
top: 1em;
left: -1.5em;
width: 6em;
height: 6em;
padding: 1em 0;
background: #80A060;
background-image: linear-gradient(transparent, rgba(0,0,0,.3));
color: white;
line-height: 1;
font-size: 140%;
text-align: center;
text-decoration: none;
text-shadow: .08em .08em .2em rgba(0,0,0,.6);
border-radius: 50%;
box-shadow: .1em .2em .4em -.2em black;
box-sizing: border-box;
transform: rotate(15deg);
animation: none;
}
Isn’t It Something That’s Better Done Server-Side?
This is a valid argument, and there are advantages and disadvantages to both approaches. Using a server-side script means that:
- It has to be updated very, very often as browser support changes and prefixes aren’t needed any more. PrefixFree automatically detects what needs a prefix and what doesn’t.
- All the prefixes need to be downloaded, which adds lots of bloat. In a medium size stylesheet, that’s far more bloat than the size of prefixfree.js.
- In cases of preprocessors like LESS and SASS, you depend on their proprietary syntax, so you can’t just remove the script after a few years.
However, there are some benefits to doing it on the server-side:
- It takes longer to download, but the user doesn’t see the un-CSS3-ed version of the style at all. With PrefixFree there will be a tiny delay.
- It will work the same even when JavaScript is disabled. Although, with PrefixFree, if the JS is disabled, the user will just see the design without some CSS3, but it will still be perfectly functional. If your CSS is written correctly, the design should be functional without CSS3 anyway.
Personally, I think it boils down to a matter of personal decision and whether the advantages are more important for you than the disadvantages.
Download the Script on GitHub!
You can download prefixfree from GitHub. The minified version is less than 5 KB, which becomes less than 2 KB after Gzip’ing. Please keep in mind that it’s still a very early beta and might have bugs. You can help fix them, or at least report them in the issues tracker. Have fun!
(al)







Wayne McManus
October 12th, 2011 5:38 amWow this is great. Thanks very much.
Vincent
October 12th, 2011 5:47 amI love the fact you are identifying a common maintenance problem and attempting to fix it. But I cant help shake the fact that using JS is the wrong way to solve it.
You are placing additional load on the client to process it, the server to send the bigger files and introducing another chain in the rendering of the page.
My preferred solution to this it to use LESS and LESS.APP on a mac. For .Net Builds I use DotLess on win. I assume there are similar methods for SASS, but i am not familiar with those.
This way the file is compiled by LESS on save and no overhead is introduced, it keeps your files leaner and the code cleaner, this is also the reason i avoid the JS version of LESS. On a large scale website it introduces another layer of complexity that isnt worth the effort to solve.
Lea Verou
October 12th, 2011 5:54 am“the server to send the bigger files”? How exactly does the server send bigger files? One of the core benefits of prefixfree is that unlike preprocessors and server-side solutions, it actually sends much SMALLER files.
Also, as for the strain on the client: Like I wrote in the article, the only noticeable delay in my tests was in Opera, and it still wasn’t that huge. It doesn’t really parse anything, just a few String#replace :)
Vincent
October 12th, 2011 6:05 amSorry it was my mis-understanding that you had to create the bigger file first. I have just been re-reading the code and I understand my error :-)
Out of curiosity did you notice any strain on the server with large css files vs smaller ones? I would expect it to increase as the size of the file does, but if as you stated it isnt causing a large issue in any way my other concern has been addressed.
Please don’t mistake me for a troll I genuinely appreciate the effort you have gone to!
Stu
October 12th, 2011 8:42 amIt’s sending one much larger file — prefixfree.js.
Even if your vendor prefixes are more than 5K (which is a lot), the client has to establish a connection to your server, parse the javascript, detect which properties are supported, then alter the page. You might not notice it on a desktop, but on a mobile, or using a 3G connection you certainly will.
The place to do this is server side. Sniff the user agent if you need to.
John Faulds
October 12th, 2011 6:05 amYep, LESS and SASS ftw. With the right mixins you can save yourself so much time.
UpWorks
October 12th, 2011 5:47 amThis is very interesting, I’ll definitely be taking it for a spin.
Thank you @leaverou
janis
October 12th, 2011 6:01 amwell i do it like this.. i think this is better..
div id=”nextcheck” class=”links modal gray menuitem corner15em shadow2px showdowtext1px cpointer” onclick=”checkBoxNextValue();”>Stap >> </div
.gray{
background: #a1a1a1; /* for non-css3 browsers */
background:linear-gradient(top, #ebebeb, #a1a1a1); /* for css3 browsers */
background: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#a1a1a1)); /* for webkit browsers */
background: -moz-linear-gradient(top, #ebebeb, #a1a1a1); /* for firefox 3.6+ */
-pie-background:linear-gradient(top, #ebebeb, #a1a1a1); /* css for ie browsers */
behavior: url(ie8fixcss/PIE.htc);
}
.corner15em{
border-radius: .15em;
-khtml-border-radius: .15em;
-webkit-border-radius: .15em;
-moz-border-radius: .15em;
behavior: url(ie8fixcss/PIE.htc);
}
etc….
Lea Verou
October 12th, 2011 6:44 amYou are using presentational classes, which is universally considered a bad practice. If you ever want to redesign, you will have to change your HTML as well.
Also, the un-prefixed version should be last, not first, so that it overrides the others if both are supported.
Alexander Nastase
October 12th, 2011 6:04 amThis is amazingly helpful, in the past I used something calls CSS3-Finalized but didn’t work anymore and wasn’t this efficient I think…anyway amazing job thank you!!!
Han Lin Yap
October 12th, 2011 8:20 amCSS3 Finalize still works..
Chris
October 12th, 2011 6:04 amOr you could make your own Less mixins? http://lesscss.org/
Marco Barbosa
October 12th, 2011 6:05 amNo offence but I think this is a very bad idea..
CSS should never depend on JS for presentation purposes. Specially “just” because of vendor prefixes facilitation.
Maybe an ant script with regex or a small Mac cocoa script would fit this better. LESS seems to do a good job with this as well (with the MAC app).
Nothing personal Lea, I love your work! :)
Paul
October 12th, 2011 6:28 amI have to say I agree with Marco. This undermines the separation of concerns that we have with JS / CSS / HTML. We used to include style information in pages (font tag, anyone?) but we broke it out with CSS. Introducing a dependency like this just doesn’t make sense to me.
Lea Verou
October 12th, 2011 11:35 amSo you’re against Modernizr as well? Or CSS3PIE?
Or any other script that helps with CSS?
If so, PrefixFree is not your problem…
Paul
October 13th, 2011 12:27 amI’m not against Modernizr particularly. The reason is that the CSS can still function completely without it, so in effect it allows a developer to augment what’s in the CSS.
When you make your HTML or CSS dependent on JS to any degree it’s bad; where JS augments the HTML and CSS that’s good. Modernizr augments, PrefixFree is a dependency, and that’s why I am comfortable with the former and not the latter.
Ejaz
October 14th, 2011 9:18 pmI think we are missing a point here, as Lea mentioned in the article “It will work the same even when JavaScript is disabled. Although, with PrefixFree, if the JS is disabled, the user will just see the design without some CSS3, but it will still be perfectly functional.”
It suggest that your CSS or presentation layer would work just fine and would not depend on javascript. But CSS3 features would not work if the JS is disabled.
IMO, the person who has intentionally disabled JS would not mind missing some fancy features because he understands the cost of disabling JS.
Julia
November 25th, 2011 6:12 am[quote]
So you’re against Modernizr as well? Or CSS3PIE?
Or any other script that helps with CSS?
If so, PrefixFree is not your problem…
[/quote]
I fully agree.
It’s not about the merits.
Julia
A.
November 25th, 2011 6:04 amCSS should not depend on JS, you say?
I see it differently: if the user deactivates JS then they get the purest standards-compliant CSS code there is, without vendor-specific workarounds. What’s wrong with that?
In the end, it’s up to the browser makers to catch up. Why don’t we force their hand a little?
I’m sick and tired of CSS preprocessing.
Bard
February 14th, 2012 12:58 pmIt’s not a worse idea than vendor prefixes was. And it still degrades just fine. Don’t get hung up on standards just for the sake of standards, man.
Alex Hall
October 12th, 2011 6:05 amFor the most part I’m pretty much happy to just use the standard CSS3 properties in my CSS. The only hassle are things like gradients and I don’t find it too bad to add one or two extra variants just in those cases. Had I found this script a year ago I’m sure I’d be using it right now!
Lea Verou
October 12th, 2011 6:11 amUsing only 2 prefixes in gradients isn’t good: You’re leaving out Opera and IE. In general, adding prefixes yourself almost always means you’ll forget some, as proven in this case.
billy bob
November 4th, 2011 10:00 amNah. I typically leave out IE on purpose – Microsoft needs to conform to industry standards – the industry doesn’t need to conform to Microsoft.
I check IE enough to make certain the interface isn’t broken and the content is acessible – the end.
daniel
October 12th, 2011 6:11 amThis is really exciting! For those who prefer not loading another javascript, you could possibly supply the Prefixfree as a server side service. We upload our prefix-less CSS and download back a correctly prefixed CSS. But then you have 2 versions of the same CSS: one is the source for editing and the other for linking on the web page.
Stefan Bergfeldt
October 12th, 2011 6:12 amI love that you solve a common problem, but just like Vincent I’m uncomfortable with relying on Javascript for the design to work.
Sure, most clients have Javascript support, and enabled, but still there are the few that doesn’t, and in some (in my case, almost every) cases you have to think about them as well.
Lea Verou
October 12th, 2011 6:27 amIf you’re relying on CSS3 for the design to work, you’re going to have issues with old IE anyway.
Neil
October 12th, 2011 7:05 pmIt’s not an issue with just IE. There’s people who prefer to disable JavaScript for other reasons. They are not a huge chunk, but they’re there. For example, the NoScript add-on for Fireofx has over a two million downloads. Nonetheless, this is a great idea. I might try it out on my personal site.
Lea Verou
October 14th, 2011 8:43 amI think you misunderstood what I’m saying. The site will display just fine to those without JS, it just won’t have some CSS3 fanciness (and only the experimental kind of CSS fanciness that’s only supported with a prefix). If the site is correctly designed, it’s fine without those as well.
Francis Thibault
March 20th, 2012 11:52 am2 millions downloads means nothing btw what if all people downloaded but did not used it or like me are web designers and downloaded to test their website without javascript ;)
Mike Fowler
October 12th, 2011 6:13 amInteresting. Will definitely give this a go and do some tests.
My current solution to ‘prefix hell’ is just writing SASS mixins for all the CSS3 properties I frequently use:
.myClass {
@include radius(3px);
@include gradient(#eeeeee, #cccccc);
@include box-shadow(1px, 1px, 5px, rgba(0, 0, 0, .2);
}
Etcetera, etcetera…
John Polling
October 12th, 2011 7:03 am@Mike, why don’t you used Compass that has all these mixins already there, plus so much more.
Mike Fowler
October 12th, 2011 8:28 amHow I wish I had more time to explore every framework out there. I’m sure you know what I mean ;)
On my laundry list of tools to try out.
Torkil Johnsen
October 16th, 2011 1:07 pmMike, Compass uses SASS, so it’ll be like SASS, but with a lot of other goodies. Well worth investigating.
TJ
October 31st, 2011 6:34 pmew lol you should check out Stylus, no funky syntax:
box-shadow: 1px 1px 5px rgba(0,0,0,.2);
can be defined as a transparent mixin if you use the nib extensions lib http://visionmedia.github.com/nib/
likewise things like border-radius, gradients etc are written as regular CSS properties
Andy Pasztirak
October 12th, 2011 6:13 amI like the idea, however I have to agree with Vincent, I prefer running SASS+Compass in a CI environment to process my CSS files mainly because this solution while it might not have a huge effect on performance, it’s definitely a bigger hit than having a few lines extra in the prefixed CSS (which should be minified in the production environment anyway so aesthetics have little to do with them?), and it’s a hit on both the client and the server side too.
Benoit
October 12th, 2011 6:17 amI agree with Vincent. I also use LESS with less.php, thus preprocessing on the server-side.
When the browser downloads the page, if it encounters a script file, it stops rendering to process the js file, that’s why now we put JS at the bottom of the page. But CSS is in the head section, thus the browser renders the original css sheet, encounters the script and changes the rendering, this causes a kind of flickering on the screen…
A most important problem you are forgeting is that some css3 properties are different between browsers:
-moz-border-radius-topleft // -webkit-border-top-left-radius !
Another big problem is the difference of the values between the browsers:
-webkit-gradient(linear, left top, right top, color-stop(0%, #f00), color-stop(100%, #00f))
is different from
-webkit-linear-gradient(left, #f00 0%, #00f 100%)
How do you solve these ?
For me, the solution is LESS/SASS mixins.
Lea Verou
October 12th, 2011 6:39 amYou can still use prefixed properties/values/anything, and PrefixFree will not change them in any way.
Benoit
October 12th, 2011 7:04 amFine, I can use your snippet and don’t use it… With this I’m still stuck with one solution for some properties, and I have to find another one for other properties… not very productive: different technics (on both server and client side), more files, maintenance conflicts are coming…
Sorry, I don’t subscribe.
LESS/SASS mixins solve all CSS3 compatibility problems, not only the prefixes but also what I enlightened (different property names, different values for same properties etc.
Have a look here : http://lesselements.com/, even if it’s not the most achieved.
Jason
October 12th, 2011 6:19 amI’m with the rest that think this is a very bad idea. Presentation shouldn’t depend on JS to work, ever.
Nice try, but you can’t just fix everything with JavaScript.
Lea Verou
October 12th, 2011 6:29 amIt’s only the CSS3 that depends on JavaScript, and only some of it. If your design relies on CSS3 to show properly, you’ll have bigger problems anyway :)
zach
March 11th, 2012 6:41 amI’m with Lea on this one. “Presentation shouldn’t depend on vendor-prefixed css to work, ever” – FTFY. If your site breaks without css3 support than you’re doing it wrong.
Pokepoke
October 12th, 2011 6:24 amYou should check out Turbine. It does the same and more, also with a css-reset rule default etcetc. If you like prefixfree, you will love Turbine.
(i dont work for turbine, i work with turbine)
Jitendra Vyas
October 12th, 2011 6:29 amThis is a good Idea for the maintenance and if you are already using HTML5 Shim, jQuery, Modernizer. then what is the problem of using it. If website is being viewed on browser where JavaScript is turned off. I think that users will also be not interested to see Advance CSS3 stuff.
Great Work Lea Verou
Lea Verou
October 12th, 2011 6:36 amThanks!
austrys
October 12th, 2011 6:29 amDoes it work with Less or Sass?
Lea Verou
October 12th, 2011 6:37 amLESS/SASS are usually on the server-side and PrefixFree works on the client side. I don’t see why there would be a conflict. :)
Pete Boere
October 12th, 2011 6:36 amIn CSS Crush (google it) — a PHP based, not client side preprocessor — there is an aliases file specifically for handling the vendor prefix problem.
I prefer the power, reliability and efficiency you get with server-side preprocessing, though if there was a client side version of CSS Crush it would function a lot like PrefixFree
Robert Picard
October 12th, 2011 6:47 amI’d also recommend trying out http://prefixr.com/
Lea Verou
October 12th, 2011 6:54 amIt’s linked in the article, haha :)
MatthewSchenker
October 12th, 2011 6:48 amThanks for writing about this. I like the idea of simplifying the process of creating and managing my CSS files. I also like that the CSS will just work the way it is once we all get away from needing prefixes.
But what about those situations where the whole syntax, not only the prefix, is different for each vendor?
Thanks,
Matthew
Lea Verou
October 12th, 2011 7:02 amHi Matthew,
Nailed it! I think that’s the most valid argument and it’s troubling me as well. For now, I recommend using prefixed properties as well in those cases. However, the problem is that since the nonprefixed version will get a prefix on runtime, the prefixed version will have to be after it, which isn’t good.
A VERY hacky solution would be to take advantage of the kinda intentional PrefixFree bug that properties like “property : value” (space between property name and colon) aren’t processed by PrefixFree.
But, I’m pondering potential solutions for this issue. If you have any ideas, I’d love to hear them.
Grigory V
October 12th, 2011 10:46 amYou should turn this bug into a feature by documenting it :-)
Lea Verou
October 14th, 2011 8:46 amI don’t really like it though, it makes the code unreadable. It’s not clear as to why some properties have a space between them and the colon and some don’t. And it doesn’t solve the issue with values, selectors and @-rules.
I need to come up with a more general way to opt-out of prefixing for only some cases.
Bradley Grzesiak
October 12th, 2011 6:54 amCheck out Compass, which is a framework for frameworks on top of SASS. While it can certainly pull in Blueprint, 960.gs, etc (and use them semantically, no less), I tend to simply use the core-functionality, which is split into 3 areas: CSS3, Typography, and Utilities.
As an example of its power, check out the example for CSS3 gradients: http://compass-style.org/examples/compass/css3/gradient/
Be sure to click the SCSS, SASS, and CSS tabs above the code example on the right to see the differences.
While born as a Ruby project, it’s gaining traction in the PHP world.
Kai Chan Vong
October 12th, 2011 7:03 amFor mocking something up super quick/throw away code. Great!
But for serious work, this is bad. I’d much rather use SASS or an alternative with mixins to cover this problem.
Global Warming
October 12th, 2011 7:21 amThis is definitely something better done server side. What does prefixfree do when JS is off? It fails and the website looks awful.
Not just that, but think about all the extra computing power being wasted by clients to do what is essentially a redundant operation that could have been done once server side and cached. Bandwidth difference is negligible if you are using gzip (you should).
Calculate the power wasted for all those clients. Our planet is dying a death of a thousand cuts. Every little bit you waste is gradually destroying it further. If you aren’t part of the solution, you’re part of the problem.
Lea Verou
October 12th, 2011 7:38 amPlease read the article, all your concerns are addressed there.
If your design looks awful without CSS3, you’re not doing progressive degradation correctly and you’ll have problems with IE8 as well.
Daniel Hug
February 1st, 2012 9:52 amIt’s funny that you say “progressive degradation”. We usually hear of “progressive enhancement”, and “graceful degradation”. Funny how you mixed em. :)
Varemenos
October 12th, 2011 7:34 amΠολυ ωραιο και εξυπνο. Τι γινεται ομως με το θεμα αποδοσης?
translated: Very nice & smart. What about performance though?
Lea Verou
October 12th, 2011 7:40 amIn my tests, it’s only Opera that had a noticeable lag (like a second). But it depends on CSS size and HTML size (since it’s processed upon DOMContentLoaded).
But it does need more rigorous stress testing. I’m hoping the community will help with that.
Lea Verou
October 14th, 2011 8:48 amBtw it’s not only done on DOMContentLoaded any more (with the latest update), so no lag due to HTML size and very smaller FOUC (hardly noticeable). :)
cancel bubble
October 12th, 2011 7:47 amWhat I think is cool about this: It only sets the needed prefixes based on your browser.
What I don’t think is cool about this: It’s dependent on JavaScript.
Seems like LESS/SASS is the way to go, IMO. Although those include every vendor prefix, I’m not so sure file size difference is that big of a deal. Especially if you’re minifying/gzipping.
Another thing, stylesheets are cached – this method has to reiterate on every single page load.
The Frosty
October 12th, 2011 8:02 amThat is super awesome.
Neo
October 12th, 2011 8:04 amGreat work Lea,
I had one issue in FF 7.0.1 and that was for border-image. The script negated my browser prefix altogether and degraded. Really looking forward to using this ; )
Lea Verou
October 12th, 2011 10:04 amCan you please report this bug in the issues tracker with a reduced testcase? https://github.com/LeaVerou/prefixfree/issues
Thank you!
Han Lin Yap
October 12th, 2011 8:24 amI have made a similar script a year ago that works exactly like this one. https://github.com/codler/jQuery-Css3-Finalize
CSS3 Finalize
Matt
October 12th, 2011 8:33 amYeah, I gotta go with Less or SASS to deal with issues like this. I like that this attempts to keep your CSS DRY, but relying on JS for basic presentation doesn’t work for me. I understand the graceful degradation argument, but why should my site degrade in browsers that fully support the vendor prefixes but don’t have JS turned on? JS isn’t meant for presentation, and I get nervous whenever I see JS shims used for things that really can be solved with pure CSS. If you have duplication, get a CSS preprocessor that supports mixins. Plus you get all of the other awesomeness like variables, etc.
Lea Verou
October 12th, 2011 10:07 amThe problem with these solutions, is that you rely on proprietary syntax forever. With PrefixFree, it’s just standard CSS3 syntax.
But I agree with you about the other awesomeness, if you want to use variables, preprocessors are the only way.
DRoss
October 12th, 2011 8:40 amFor some reason it’s removing all the background images on a site I’m working on. (Chrome Mac – latest version – 14.0.835.202) – Just checked Firefox as well – same thing.
This is how I generally write my background property – background: url(../img/header-bg.png) repeat-x;
Lea Verou
October 12th, 2011 10:08 amCan you please file a bug? https://github.com/LeaVerou/prefixfree/issues
Thanks a lot for trying it out!
Scott
October 12th, 2011 8:57 amNice idea, although I disagree with your assertion that doing this on the server-side creates a larger file. You could browser-detect and send only the necessary CSS.
Also, do you really save that much download time? Your script is about 5,000 bytes, you need *a lot* of CSS3 to make up the savings.
Lea Verou
October 12th, 2011 10:09 amIn an average website, I’ve noticed that the CSS3 vendor prefixes add much more than 5KB. But, again, that’s me and I probably use more CSS3 than most people. :)
You’ll be surprised at how little code can add up to 5KB. :)
Btw, if gzipped, it’s less than 2KB.
Scott
October 12th, 2011 3:47 pmYes, on further calculation it may only take 20-50 CSS3 properties to create 5KB more CSS than necessary. To be honest, I haven’t used much advanced CSS3 yet (transitions, gradients etc) since it’s only recently gained enough browser support to bother with (IMO). But I think this could be a pretty nice tool for now and in the future.
(P.S. love your CSS3 stripes post, only just found it yesterday!)
Lea Verou
October 13th, 2011 7:30 amThank you!
Actually, it was primarily my gradients technique that motivated me to make this: I realized that I wouldn’t use CSS for some patterns, because the resulting file size with all the prefixes was bigger than a corresponding image file. Not any more! :)
Ferdy
October 12th, 2011 9:55 amKudos for the creative approach and good write-up, but to me it seems like an unwanted cure for a non-existing problem. If you do have a problem with prefixes there are existing, better methods to solve it (LESS).
Lea Verou
October 12th, 2011 11:29 amBetter how?
TJ
October 31st, 2011 6:31 pmstylus handles this wayyyy better than less does, you can write it just like regular CSS:
border-radius: 5px 10px
etc, instead of:
.border-radius(5px, 10px)
Grigory V
October 12th, 2011 10:43 amOh wow. A while ago I tried eCSStender and it was quite big… over 20 kb of JS is much more than a few kb of prefixed properties… and I thought people who turn off JS care about rounded corners. So I made a server-side script: Then I was using more of CleverCSS/SASS/LESS/Stylus and they handled it for me.
Now, 5 kb might be less than all the prefixed properties if there are many… Also, this is much better for prototyping w/ just a text editor and a browser. And the greatest benefit? Not downloading prefixed CSS nor the script on old IEs – like, if (!Modernizr.cssgradients) don’t_download_it().
Also, did you really write it while at the airport? You’re awesome!
Lea Verou
October 12th, 2011 11:32 amHaha, thank you!
I started it at the airport (I had 6 hours waiting time) and finished it during the conference. But I had some code written already, for my slide demos, so I did have a starting point.
Hilde
October 12th, 2011 11:17 amYou were right during lunch today, Lea: I DO love this! ;)
Keep up the good work!
Lea Verou
October 12th, 2011 11:37 amThank you Hilde! It was great meeting you :)
bcw
October 12th, 2011 2:01 pmIn general, I think that the concerns about Javascript being disabled are way overblown. On the Yahoo! Developer Network blog, there is an article about this from last fall. While doing some analytics on the Yahoo! homepage, their developers crunched the numbers, and worldwide “found a consistent rate of JavaScript-disabled requests hovering around 1% of the actual visitor traffic.” The number in the US was around 2%.
They conclude, that “from a planning standpoint, it makes sense to spend more time on the experience that the largest numbers of users receive.”
That said, they are quick to point out that in the unusual case of the Yahoo! homepage, they get 300 million user visits per month – so for them, the 6 million users who have Javascript disabled are not trivial.
However, for most web designers, it seems that planning your site around the roughly 1%-2% of users who may have Javascript disabled is an unnecessary burden. How many modern web applications are being designed with a priority being that they are supported by IE 5?
I think using Javascript to make the experience more efficient for the designers, and at the same time, better for 99% of users is just fine.
quentin
October 12th, 2011 3:11 pmThis kind of (or blatantly) goes against the concerns raised in the list apart article you included. Saying you believe that they are needed, and supporting that with another article that does a good job of explaining why solutions like this are not really solutions at all, and then essentially removing all utility they have (and actually inserting more unnecessary issues by now requiring prefixfree to have it’s own set of hacks to account for syntax differences) seems quite odd, and a bit backwards.
I hate having to type things tons of times too, but the list apart article did a pretty good job of making sense out of why it’s necessary.
Lea Verou
October 12th, 2011 3:21 pmPlease read the other comments. I’ve already mentioned that it’s possible to use prefixed properties along with prefixfree, when it’s really necessary. So, it doesn’t really go against the spirit of vendor prefixes, no.
Spadar Shut
October 12th, 2011 3:35 pmLea, I really appreciate all of your ingenious ideas, but I think that the only noticeable advantage of this script is that it only saves a developer from writing the same lines of code several times, which is also rather vague, to be honest.
The argument that the size of the CSS file without prefixes will be smaller is mitigated by the fact that CSS files with and without prefixes will be almost identical in size when sent gziped (which you should do anyway) and thus adding such a script is not worth the overhead of requesting another js file, then running it in the browser to parse CSS, and not to mention all the issues with mixing concerns, disabled JS and the added complexity of site code.
Lea Verou
October 13th, 2011 2:22 amVague how? Is it, or is it not a real problem that developers have to write the same things multiple times?
The filesize is not identical at all after gzipping. Try it out yourself, I just did.
Lemon
October 12th, 2011 7:55 pmNice one!
Whenever I am building a site in which I can forget about the people who have javascript disabled I will be sure to use this (Which is almost every single website I build, the only exception being an intranet for a company which I didn’t use CSS3 on anyway because they still use IE6…)
I use LESS anyway so I could take care of everything with that, but using this script will be nice as well just because I won’t have to worry about removing vendor prefixes later on; not to mention that when I use CSS3 on some larger sites, the CSS can become quite large in a short amount of time; especially when using things like animations.
And hey, if I’m relying on individual browser support for presentation purposes with CSS3 at the moment, then, provided I don’t have to worry about javascript being turned off, why not rely on javascript too…
Don Elliott
October 12th, 2011 9:30 pmI’m new to using LESS or SASS, but am I mistaken in the understanding that you essentially need to create a separate style sheet for every browser in order for the server-side solutions to work? Any article links for noobs to SASS would be appreciated…
However, if I am right, then it seems that Prefix is ideal for firms which are building sites for small to medium sized businesses, where every 15minutes of development time actually matter. For example, a website that costs $2,000 to build, and has a client who needs to go back and forth with multiple variations…. Whereas an enterprise level site at $200,000 with dozens of thousands of hits or more a day, interacting on multiple levels, where page load times being decreased by milliseconds actually makes a difference, SASS may be a better option.
Am I correct in this assessment? It seems prefix vs Sass comes down to upfront development time vs page load time.
On another note, it’s worth re-reading the editors note in this article. I love the concept of this series and give major kudos to Lea for being the first pioneer here! Cheers to you.
Dimitris Borbotsialos
October 13th, 2011 1:52 amWell done Lea, great job!
Once again you’re one step ahead (well probably more than one)
Συγχαρητήρια!
Roel
October 13th, 2011 2:04 amI made a LessCSS library for this problem. It’s called More.less (http://roel.vanhintum.eu/more-less/). Where possible there are fallbacks for older browsers available.
Personally I like the server side (or on release) processing, to make sure the page loads faster.
Ioannis Cherouvim
October 13th, 2011 8:45 amOK, it may not be useful for all situations but the execution is superb.
Scott
October 13th, 2011 8:54 amRelying on JS for styling of content is inherently a bad idea. If you use tools such as http://css3generator.com/, generating vendor prefixes is quick and easy. Any performance increase from your CSS file being a few K smaller is negligible at best.
A.
November 25th, 2011 5:47 amYou don’t mean it, do you?
I don’t have time for this.
Stop beating up on Lea will u. If u don’t like the script then don’t use it. It’s optional, ok?
It makes me sick reading your glorified sermons about Less, sass and all that mess. It’s nice in theory, but I refuse to believe that all of you are going through CSS preprocessing when working on a client site. You wouldn’t have time to fume about JS-dependency of CSS stylesheets.
Personally, I think Lea’s script is great.
All those JS-purists must be living on a different planet. Unless u r coding the Yahoo website, who gives a damn about your perfect prefixes?
Salman Abbas
October 13th, 2011 11:30 amWhat about caching the prefixed stylesheet in localStorage, like LESS.js does?
Lea Verou
October 13th, 2011 2:53 pmThat’s a very cool idea, I might do that, thanks!
Enes
October 13th, 2011 6:00 pmgood idea I like it, but since I have to support some older browsers (like those<IE9), I am unable to use a lot of CSS3 features. So this is another js snippet to put on ice right now. but thanks in advance for your effort!
Jo
October 14th, 2011 7:50 amThis is good if you want to fix the prefix “problem” with javascript . . and for small fun projects.
Really, this is very bad practice to use, this should never be used as a serious solution!
Instead, use sass or less.
Adam Dehnel
October 14th, 2011 11:47 amlove it and will use it immediately! the minified version link on github goes to the non-minified version. might want to change that.
Nick Van der Vreken
October 16th, 2011 1:18 pmHi Lea,
when implementing your script in a Drupal installation I get a list of errors in Firebug, copied the record below. I assume it’s caused by invalid HTML, but it might be a good addition to include error handling in there.
Fout: uncaught exception: [Exception... "Node was not found" code: "8" nsresult: "0x80530008 (NS_ERROR_DOM_NOT_FOUND_ERR)" location: "/sites/all/themes/dancecool/js/prefixfree.min.js?r Line: 8"]
Like the script otherwise, it is working nicely and with no delays!
Cheers,
Lea Verou
October 17th, 2011 1:30 pmThis bug was fixed yesterday. Try the new version. :)
Jay
October 19th, 2011 2:12 pmSo, basically it’s taking the exact same idea that http://prefixr.com/ had (and was posted about on net.tutsplus.com back on August 3rd), and made it JS?
Lea Verou
October 19th, 2011 6:47 pmNot at all. -prefix-free *detects* which features need a prefix and only adds it when necessary. prefixr (which is linked in the original article, so it’s not a discovery on your part), like every preprocessor, needs to add them all or add only some based on the current state of implementations. What -prefix-free does is impossible to do with any preprocessor.
simonleung
November 6th, 2011 9:56 amI made a suggestion on http://hacks.mozilla.org/2011/09/taking-steps-with-css-animations/ about the idea of prefix free.
Prefix free is a good idea but you must be careful that the prefixed CSS properties are not stable at all.
Danz
October 19th, 2011 9:06 pmWonderful article Lea. Simple and clean.
To be honest, I really don’t see the fuss as to why you cannot use this method. While most argue the “what is they disable JavaScript” mantra, most who use the net don’t even know what JavaScript is let alone disable it.
It also comes in handy for those who are starting out or don’t know how to install SASS/LESS. Definitely useful!
FYI, I think caching in localStorage is a good idea.
Brian Enriquez
October 20th, 2011 9:19 pmLea,
Awesome. My favorite part of the article is you responding to damn near every single comment for days, hahaha. You tell ‘em, sister. Keep pushing the envelope. When I went on your site for the first time after the CSSsummit and pressed your nav buttons I flipped out. After that I bought like 3 CSS3 books, the whole A List Apart series and never went to sleep.
You’re awesome. Thanks.
Jerome
October 25th, 2011 7:21 amGood work!
TJ
October 31st, 2011 6:29 pmeven better than SASS/LESS is http://learnboost.github.com/stylus/
you can use transparent mixins to keep CSS as regular CSS, check out the little demo here http://learnboost.github.com/stylus/try.html
Richard Lomas
November 2nd, 2011 7:41 amAm I the only one that has the Prefix-Free site looking atrocious on IE 8?
Can’t even use the Test Drive page!?
It’s me, right?
(No i’m not an IE8 user, but I was curious and loaded up the test drive page in it).
Looks like this:
1. http://cl.ly/2Z3f3J3v1Z1u1U0b0D09
2. http://cl.ly/3y1d3V0y1j170N0w1S26
Lea Verou
November 15th, 2011 2:44 pmThat doesn’t have anything to do with -prefix-free. I just didn’t add fallbacks because it’s a site aimed at developers and the percentage of developers that use IE8 is effectively 0%.
Steve Schrab
November 4th, 2011 10:34 amI love this so far. If you’ve been using a lot of CSS Gradients, this makes the madness go away. Plus you get to truly write CSS standards-based code. No more vendor non-sense.
Boutros AbiChedid
November 8th, 2011 5:46 amEven though I usually like to keep CSS and JS separate. But I like the code, especially there is a fallback when JavaScript is disabled.
I am sure that eventually, someone will find a better way to do it, but that’s how code goes, it is always in progression until the next better version…
So For now Lea’s code is much more efficient than the original version.
Thanks Leah for this post and stirring developers minds to find better ways to write code.
grunghi
November 18th, 2011 7:46 amGreat script, but there is one problem with it, Im working on a large project with multiple stylesheets (for layout, typo, colors etc.) and prefix-free breaks firebug / chrome dev consoles ability to point me to the right line in right stylesheet – all css properties are displayed as if they were inline on the current page (but they obviously aren’t), this is a big problem especially for bigger projects with more css files in development phase…
das182
December 21st, 2011 4:36 am“If your CSS is written correctly, the design should be functional without CSS3 anyway.” VS. box-sizing: border-box;
T
December 21st, 2011 6:03 pmI like this a lot. I have no issues with JavaScript helping render CSS. I actually prefer it to server-side processing. I like that it is similar to stylus’ transparent mixins versus the LESS syntax and doesn’t require a new mime type. However, it seems excessive to use both LESS and prefixfree. If it included more functionality, then I would probably switch. LESS does a lot more than just prefixes; it does variables, single line comments, and lets you support IE8, which is still a large user base, with CSS3 PIE tricks.
mario
January 14th, 2012 2:20 pmOh, god. I feel so stupid now. Just wasted a whole yesterday on writing something crude and brute-force like this: http://userscripts.org/scripts/source/123108.user.js
Obviously I’m going to use prefixfree now. Love the logo! And I do have an actual need for this. (Server-preprocessing not available. And anyway, client-side issues should be fixed… client-side.)
Just hope this becomes available on Googles CDN soon. I feel this is a crucial step to bring browser development and actual standardization forward (the stalling doesn’t help anyone).
sushil bharwani
January 24th, 2012 10:57 pmThis is absolutely great. And improves a lot of maintenace efforts. Otherwise just copying similiar values for different browsers is so troublesome. Thanks for thinking and writing it.
Sergej Jevsejev
July 21st, 2012 7:00 amYou can look at http://sjevsejev.blogspot.com/2012/07/lessjs-function-generates-prefixes-for.html
It can be even easier:
.pf(‘transition’,'all 1s ease-in-out’);
.pf(‘border-radius’,3px);
.pf(‘box-shadow’,’2px 2px 5px 0 rgba(0,0,0,.6)’);
.pf(‘flex’, 1);
Jarod
July 23rd, 2012 4:23 pmstellar, thanks!! ^_^
do you intend on adding support for ‘filter’ anytime soon?
Frank Talk
August 31st, 2012 3:05 amFor anyone using SASS i would recommend http://thoughtbot.com/bourbon/
which is incredible helpful dealing with all those vendor prefixes.
Mike Edward Moras (e-sushi™)
September 12th, 2012 3:40 amJust a note to all the people that say CSS and javascript don’t hug each other… what do you thing is the backbone language of browsers like Firefox? JS! Tsss…
Nicole M
February 6th, 2013 1:00 pmThis is absolutely awesome, great work!