cssautoprefixervendor-prefix

Why people use CSS vendor-prefix although the specs clearly says don't


I wonder why everyone uses vendor-prefixes in their production builds although the CSS 2.1 specs clearly say:

Authors should avoid vendor-specific extensions (link)

And CSS 3 says:

implementations should support both vendor-prefixed and unprefixed syntaxes for the feature. (link)

So as far as I found out, vendor-prefixes are for addressing different behaviors across browsers for experimental features, And there is no point in copy-pasting a value for a specific CSS property and just adding different prefixes to it.

For example, I think it would be OK to write something like this:

-webkit-border-top-left-radius: 10px;
-webkit-border-top-right-radius: 5px;
-webkit-border-bottom-right-radius: 10px;
-webkit-border-bottom-left-radius: 5px;
border-radius: 10px 5px; 

But why people use vendor prifix for things that are consistent across browsers, like:

-webkit-transition: all 4s ease;
-moz-transition: all 4s ease;
-ms-transition: all 4s ease;
-o-transition: all 4s ease;
transition: all 4s ease; 

And why tools like autoprifixer are copy-pasting every property even if it doesn't have different behavior across browsers.


Solution

  • CSS 3 spec is newer than CSS 2.1, so let's skip what 2.1 says.

    The spec says implementations —that refers to browsers, not stylesheets— should not require vendor prefixes. That's different from whether or not they do. Some browsers do require prefixes for some styles.

    The thing is the W3C's CSS Working Group, who write the CSS spec, do not actually have power over browser developers — the browser developers have to choose to follow the spec (in part or in full). What's exciting is that more and more the main browsers are falling into line with the spec, and vendor prefixes are needed less and less.

    The vendor-prefixed properties you need to provide depends on what browsers you support. Within a given browser, the requirements often vary by version. Newer versions of browsers for the most part require fewer vendor CSS properties than older versions of the same browser.

    Snippets found online don't always age well. For example

    -webkit-transition: all 4s 
    -moz-transition: all 4s ease;
    -ms-transition: all 4s ease;
    -o-transition: all 4s ease;
    transition: all 4s ease; 
    

    would typically be considered overkill these days. Always check the date on bits of code found online. On SO, checking rep can help you distinguish between workable answers and best answers.

    There's a whole separate question of how dropping support for old browsers related to web accessibility. Won't get into that here, but there are some people who say that choosing to only support more recent and/or popular browsers is inherently problematic.

    Autoprefixer can be configured to target exactly the browsers you want to support. It adds only the vendor-specific CSS needed to meet the need you specify. By default, Autoprefixer uses the Browserlist default. With that setting, no vendor-specific code is needed to support border-radius: 10px 5px and transition: all 4s ease. You can see that by running your two rules through https://autoprefixer.github.io/, "filtered" by > 0.5%, last 2 versions, Firefox ESR, not dead. You can see which browsers that covers at https://browserl.ist/?q=%3E+0.5%25%2C+last+2+versions%2C+Firefox+ESR%2C+not+dead

    In practice, a lot of people simply do not write vendor-specific CSS, relying on Autoprefixer built into their build tooling. For example, you might have a Gulp or webpack setup that automatically runs your stylesheets through Autoprefixer. If that's new to you, a good starting point might be postcss-cli, the command line tool for PostCSS.

    npm install -g postcss-cli autoprefixer
    postcss my-styles.css --use autoprefixer --dir output-directory