CSSAutoprefixer & Vendor Prefixes

Autoprefixer & Vendor Prefixes

Some CSS properties, especially newer or historically experimental ones, need a browser-specific prefix (-webkit-, -moz-, -ms-) to work in certain browser versions — see Vendor Prefixes for the fuller picture of why these exist and which browsers use which prefix. Autoprefixer is a PostCSS plugin that adds exactly the prefixed declarations your target browsers still need, automatically, based on real usage data — so you almost never have to write a vendor prefix by hand again.
Write plain CSS, let the tool add prefixes

The core idea is a clean separation of concerns: you author standard, unprefixed CSS, and Autoprefixer inserts whatever prefixed variants are needed as a build step. This is dramatically more maintainable than writing prefixes by hand, for a few reasons:

  • Prefix requirements change over time as browsers gain native support — a property that needed -webkit- two years ago might not need it today. Autoprefixer's data updates independently of your code.

  • Hand-written prefixed CSS is easy to let go stale, and easy to forget when adding a new property.

  • It keeps your source CSS readable — no repeated near-duplicate declarations cluttering every rule.

Configuring target browsers with Browserslist
Autoprefixer doesn't guess which browsers to support — it reads a shared browserslist configuration that most modern JS tooling (Babel, Autoprefixer, ESLint plugins) also respects. It can live in package.json:

JSON
{
  "browserslist": [
    ">0.3%",
    "last 2 versions",
    "not dead",
    "not op_mini all"
  ]
}
Or in a standalone .browserslistrc file at the project root:

Text
# .browserslistrc
> 0.3%
last 2 versions
not dead
not op_mini all
Autoprefixer runs as a PostCSS plugin, wired into your build pipeline via postcss.config.js:

JS
module.exports = {
  plugins: {
    autoprefixer: {},
  },
}
Before and after

You write this, unprefixed:

CSS
.card {
  display: flex;
  user-select: none;
  backdrop-filter: blur(8px);
}

And, depending on the exact browsers listed in your Browserslist config, Autoprefixer emits something like this:

CSS
.card {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}

Notice the unprefixed declaration is always kept, and always written last within each property group — CSS resolves duplicate properties by using whichever one appears last, so this ordering guarantees that browsers supporting the standard property use it, while older browsers fall back to the matching prefixed version.

Autoprefixer only adds what your target list actually needs
If your Browserslist config only targets recent evergreen browsers, Autoprefixer may add few or no prefixes at all for a given property, because those browsers no longer need them. The output above assumes a Browserslist config that still includes some older browser versions — tighten the list and the prefixed output shrinks accordingly.
Never remove prefixes Autoprefixer added — and never hand-add your own
Once Autoprefixer is wired into your build, treat its output as generated code: don't hand-edit prefixed lines in compiled output, and don't add your own prefixes in source CSS (it can even remove outdated ones it finds). Update the Browserslist config instead when your supported-browser range changes — the correct prefixes will regenerate automatically on the next build.