Autoprefixer
Autoprefixer is a PostCSS plugin that automatically adds vendor prefixes to CSS rules, using data from Can I Use. It lets you write standard CSS and handles browser compatibility automatically.
What Problem Does It Solve?
Different browsers require different vendor prefixes for CSS properties.
Without Autoprefixer
css/* You have to write all vendor prefixes manually */ .box { -webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); -ms-transform: rotate(45deg); -o-transform: rotate(45deg); transform: rotate(45deg); -webkit-transition: all 0.3s ease; -moz-transition: all 0.3s ease; -o-transition: all 0.3s ease; transition: all 0.3s ease; display: -webkit-box; display: -webkit-flex; display: -moz-box; display: -ms-flexbox; display: flex; }
With Autoprefixer
css/* You write clean, standard CSS */ .box { transform: rotate(45deg); transition: all 0.3s ease; display: flex; } /* Autoprefixer outputs (based on your browser targets): */ .box { -webkit-transform: rotate(45deg); transform: rotate(45deg); transition: all 0.3s ease; display: -webkit-box; display: flex; }
Installation
With PostCSS
bashnpm install -D autoprefixer postcss
Configuration
javascript// postcss.config.js module.exports = { plugins: { autoprefixer: {} } }
With Tailwind CSS
javascript// postcss.config.js module.exports = { plugins: { tailwindcss: {}, autoprefixer: {}, } }
Browser Targets
Use browserslist to specify which browsers to support.
package.json
json{ "browserslist": [ "> 1%", "last 2 versions", "not dead" ] }
.browserslistrc
# Browsers that we support
> 1%
last 2 versions
not dead
not IE 11
Common Queries
# Modern browsers only
last 2 Chrome versions
last 2 Firefox versions
last 2 Safari versions
last 2 Edge versions
# Include older browsers
> 0.5%
last 4 versions
# Exclude browsers
not dead
not IE 11
not op_mini all
# Specific versions
iOS >= 12
Chrome >= 90
Integration Examples
Vite
javascript// vite.config.js import autoprefixer from 'autoprefixer'; export default { css: { postcss: { plugins: [ autoprefixer() ] } } }
Webpack
javascript// webpack.config.js module.exports = { module: { rules: [ { test: /\.css$/, use: [ 'style-loader', 'css-loader', { loader: 'postcss-loader', options: { postcssOptions: { plugins: [ require('autoprefixer') ] } } } ] } ] } }
Next.js
Autoprefixer is included by default in Next.js.
javascript// postcss.config.js (if you need custom config) module.exports = { plugins: { 'postcss-flexbugs-fixes': {}, 'postcss-preset-env': { autoprefixer: { flexbox: 'no-2009' }, stage: 3, features: { 'custom-properties': false } } } }
Gulp
javascriptconst gulp = require('gulp'); const postcss = require('gulp-postcss'); const autoprefixer = require('autoprefixer'); gulp.task('css', () => { return gulp.src('src/*.css') .pipe(postcss([ autoprefixer() ])) .pipe(gulp.dest('dist')); });
What Gets Prefixed
Transforms
css/* Input */ .element { transform: scale(1.5); transform-origin: center; } /* Output */ .element { -webkit-transform: scale(1.5); transform: scale(1.5); -webkit-transform-origin: center; transform-origin: center; }
Flexbox
css/* Input */ .container { display: flex; align-items: center; justify-content: space-between; } /* Output */ .container { display: -webkit-box; display: flex; -webkit-box-align: center; align-items: center; -webkit-box-pack: justify; justify-content: space-between; }
Grid
css/* Input */ .grid { display: grid; grid-template-columns: repeat(3, 1fr); grid-gap: 20px; } /* Output (for older browsers) */ .grid { display: -ms-grid; display: grid; -ms-grid-columns: 1fr 1fr 1fr; grid-template-columns: repeat(3, 1fr); grid-gap: 20px; }
Gradients
css/* Input */ .gradient { background: linear-gradient(to bottom, #fff, #000); } /* Output */ .gradient { background: -webkit-linear-gradient(top, #fff, #000); background: linear-gradient(to bottom, #fff, #000); }
User Select
css/* Input */ .no-select { user-select: none; } /* Output */ .no-select { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }
Options and Configuration
Grid Support
javascript// postcss.config.js module.exports = { plugins: { autoprefixer: { grid: 'autoplace' // or true, 'no-autoplace', false } } }
Flexbox Support
javascriptmodule.exports = { plugins: { autoprefixer: { flexbox: 'no-2009' // or true, false } } }
Remove Outdated Prefixes
javascriptmodule.exports = { plugins: { autoprefixer: { remove: true // Remove outdated prefixes } } }
Ignore Properties
css/* Control autoprefixer with comments */ /* Ignore next declaration */ /* autoprefixer: off */ -webkit-box-sizing: border-box; box-sizing: border-box; /* autoprefixer: on */ /* Ignore entire block */ /* autoprefixer: ignore next */ .block { display: flex; }
CLI Usage
bash# Install CLI npm install -g postcss-cli autoprefixer # Process file postcss input.css -o output.css -u autoprefixer # With options postcss input.css -o output.css -u autoprefixer --autoprefixer.grid autoplace
Checking Browser Support
Using browserslist
bash# Install npm install -g browserslist # Check what your config targets npx browserslist # Output example: # and_chr 119 # chrome 119 # chrome 118 # edge 119 # firefox 120 # ios_saf 17.1 # safari 17.1
Using Can I Use
Visit caniuse.com to check browser support for specific features.
Common Prefixes
css/* Appearance */ appearance: none; -webkit-appearance: none; -moz-appearance: none; /* Backdrop Filter */ backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); /* Clip Path */ clip-path: circle(50%); -webkit-clip-path: circle(50%); /* Mask */ mask-image: url(mask.svg); -webkit-mask-image: url(mask.svg); /* Position: Sticky */ position: sticky; position: -webkit-sticky; /* Text Fill Color */ -webkit-text-fill-color: transparent; /* Background Clip */ background-clip: text; -webkit-background-clip: text;
Real-World Example
css/* Source CSS */ .card { display: flex; flex-direction: column; transform: translateY(0); transition: transform 0.3s ease; user-select: none; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); } .card:hover { transform: translateY(-5px); } /* Compiled with autoprefixer (for broader browser support) */ .card { display: -webkit-box; display: flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; flex-direction: column; -webkit-transform: translateY(0); transform: translateY(0); -webkit-transition: -webkit-transform 0.3s ease; transition: -webkit-transform 0.3s ease; transition: transform 0.3s ease; transition: transform 0.3s ease, -webkit-transform 0.3s ease; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; background: -webkit-gradient(linear, left top, right bottom, from(#667eea), to(#764ba2)); background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); } .card:hover { -webkit-transform: translateY(-5px); transform: translateY(-5px); }
Benefits
- Write cleaner code: No manual prefixing needed
- Stay updated: Uses current Can I Use database
- Remove outdated prefixes: Keeps your CSS lean
- Flexible targeting: Control browser support via browserslist
- Saves time: No need to remember which properties need prefixes
- Reduces errors: Automatic and consistent
Best Practices
- Use browserslist to define your target browsers
- Keep autoprefixer updated for latest browser data
- Don't disable autoprefixer for production builds
- Let autoprefixer handle prefixes, don't add them manually
- Review the output occasionally to understand what's being added
- Use with other PostCSS plugins for comprehensive CSS processing
- Test on actual target browsers
Alternatives and Related Tools
- PostCSS Preset Env: Includes autoprefixer plus modern CSS features
- cssnano: CSS minification (often used with autoprefixer)
- postcss-normalize: Include normalize.css with browserslist support