Autoprefixer
Vendor prefixes are additions like -webkit- and -moz- in front of a property name. Browsers once used them to ship new features before standardization, and some browsers still need them. Autoprefixer is a plugin that adds the required prefixes by itself, using Can I Use data and your Browserslist list.
Setup
If you followed the config file lesson, Autoprefixer is already installed and enabled:
// postcss.config.js
import autoprefixer from 'autoprefixer';
export default {
plugins: [autoprefixer()],
};package.json contains the list "browserslist": ["defaults"].
Example
In the blog, a post excerpt fades out at the bottom, and post tags cannot be selected with the mouse. Write standard properties without prefixes:
/* styles/main.css */
.post-excerpt {
max-height: 120px;
overflow: hidden;
mask-image: linear-gradient(black 60%, transparent);
}
.post-tag {
user-select: none;
}After npx postcss styles/main.css -o css/main.css:
.post-excerpt {
max-height: 120px;
overflow: hidden;
-webkit-mask-image: linear-gradient(black 60%, transparent);
mask-image: linear-gradient(black 60%, transparent);
}
.post-tag {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}Autoprefixer added exactly the prefixes the defaults browsers need and placed them before the standard property. A browser that knows the standard applies the last declaration.
<style>
.post-excerpt {
max-height: 120px;
overflow: hidden;
-webkit-mask-image: linear-gradient(black 60%, transparent);
mask-image: linear-gradient(black 60%, transparent);
}
.post-tag {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
padding: 2px 8px;
background: #e0e7ff;
border-radius: 4px;
}
</style>
<span class="post-tag">CSS</span>
<p class="post-excerpt">
PostCSS reads CSS, passes it through a chain of plugins and writes the result.
Each plugin does one job: adds prefixes, minifies code or converts new CSS
features for older browsers. PostCSS itself changes nothing, so what it can
do depends only on the plugins you add. This paragraph fades out at the
bottom thanks to the mask-image property.
</p>The excerpt fades towards the bottom edge, and the "CSS" tag cannot be selected.
Prefixes depend on the list
If only old browsers need a prefix, Autoprefixer does not add it. With the defaults list, backdrop-filter stays as it is:
.site-header {
position: sticky;
top: 0;
backdrop-filter: blur(8px);
}Add Safari 15 to the list — "browserslist": ["defaults", "safari >= 15"] — and build again:
.site-header {
position: sticky;
top: 0;
-webkit-backdrop-filter: blur(8px);
backdrop-filter: blur(8px);
}-webkit-backdrop-filter appeared: Safari 15 understands the property only with the prefix.
Outdated prefixes are removed
Autoprefixer also removes what is no longer needed. Old code like
.post-card {
-webkit-border-radius: 8px;
border-radius: 8px;
}becomes just border-radius: 8px; — no browser in the list needs that prefix any more.
Common mistake
Writing prefixes by hand "just in case" or copying them from old articles. The code gets longer, and the set of prefixes goes stale quickly. Write only standard properties and leave prefixes to Autoprefixer. Also do not add it next to postcss-preset-env: that one already contains Autoprefixer, and the same work would be done twice.