以下内容是 Andrey Sitnik 的客座文章,他是 Autoprefixer 工具的创建者,该工具是用于处理 CSS 中供应商前缀的“后处理器”。为什么使用它而不是预处理器或其他工具?有很多原因。Andrey 将解释。
Autoprefixer 解析 CSS 文件,并使用 Can I Use 数据库向 CSS 规则添加供应商前缀,以确定需要哪些前缀。
您所要做的就是将其添加到您的资产构建工具(例如,Grunt)中,这样您就可以完全忘记 CSS 供应商前缀。只需按照最新的 W3C 规范编写常规 CSS,无需任何前缀。像这样
a {
transition: transform 1s
}
Autoprefixer 使用一个数据库,其中包含当前浏览器的流行程度和属性支持,以为您添加前缀
a {
-webkit-transition: -webkit-transform 1s;
transition: -ms-transform 1s;
transition: transform 1s
}

问题
当然,我们可以手动编写供应商 CSS 前缀,但这可能很繁琐且容易出错。
我们可以使用像 Prefixr 这样的服务和文本编辑器插件,但这仍然让人很头疼,要处理大块的重复代码。
我们可以使用带预处理器(如 Sass 的 Compass 或 Stylus 的 nib)的 mixin 库。它们解决了大量问题,但也产生了其他问题。它们迫使我们使用新的语法。它们的迭代速度远不如现代浏览器,因此稳定版本可能包含大量不必要的修饰符,有时我们还需要创建自己的 mixin。
Compass 并没有真正隐藏前缀,因为您仍然需要决定很多问题,例如:我需要为 border-radius
编写 mixin 吗?我需要用逗号分隔 +transition
的参数吗?
Lea Verou 的 -prefix-free 最接近于解决这个问题,但考虑到最终用户的性能,使用客户端库并不是一个好主意。为了避免重复工作,最好只构建一次 CSS:在资产构建或项目部署期间。
幕后
Autoprefixer 并非预处理器(如 Sass 和 Stylus),而是一个后处理器。它不使用任何特定语法,而是与通用 CSS 配合使用。Autoprefixer 可以轻松地与 Sass 和 Stylus 集成,因为它在 CSS 编译完成后运行。
Autoprefixer 基于 Rework,这是一个用于编写您自己的 CSS 后处理器的框架。Rework 将 CSS 解析为有用的 JavaScript 结构,并在进行操作后将其导出回 CSS。
每个版本的 Autoprefixer 都包含最新的 Can I Use 数据副本
- 当前浏览器及其流行程度列表。
- 为新的 CSS 属性、值和选择器所需的修饰符列表。
默认情况下,Autoprefixer 将支持主要浏览器的最新两个版本,与 Google 的做法 类似。但是,您可以通过名称(例如 “ff 21”)或模式来选择项目中支持哪些浏览器
- 使用 “last 2 versions” 的每个主要浏览器的最新两个版本。
- 使用 “> 1%” 的全球使用统计数据超过 1% 的浏览器。
- 仅较新的版本,使用 “ff > 20” 或 “ff >= 20”。
然后,Autoprefixer 会计算哪些修饰符是必需的,哪些已经过时。
当 Autoprefixer 向 CSS 添加修饰符时,它不会忘记修复语法差异。这样一来,CSS 就会根据最新的 W3C 规范生成
a {
background: linear-gradient(to top, black, white);
display: flex
}
::placeholder {
color: #ccc
}
编译成
a {
background: -webkit-linear-gradient(bottom, black, white);
background: linear-gradient(to top, black, white);
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
display: -ms-flexbox;
display: flex
}
:-ms-input-placeholder {
color: #ccc
}
::-moz-placeholder {
color: #ccc
}
::-webkit-input-placeholder {
color: #ccc
}
::placeholder {
color: #ccc
}
Autoprefixer 也会清除过时的修饰符(来自旧代码或 CSS 库,如 Bootstrap),因此以下代码
a {
-webkit-border-radius: 5px;
border-radius: 5px
}
编译成
a {
border-radius: 5px
}
因此,经过 Autoprefixer 处理后,CSS 将只包含实际的供应商前缀。在 Fotorama 从 Compass 切换到 Autoprefixer 之后,CSS 文件的大小 减少 了近 20%。
演示
如果您还没有使用任何工具来自动构建资产,请务必查看 Grunt。我强烈建议您开始使用构建工具。这将为您打开一个全新的“糖”语法、节省时间的 mixin 库和有用的图像处理工具的世界。现在,所有开发人员的生产力方法都可以为前端程序员节省大量的神经和时间(选择语言的自由、代码重用、使用第三方库的能力)。
让我们创建一个项目目录,并在 style.css
中编写简单的 CSS
a { }
对于本示例,我们将使用 Grunt。首先,我们需要使用 npm 安装 grunt-autoprefixer
npm install grunt-cli grunt-contrib-watch grunt-autoprefixer
然后,我们应该创建 Gruntfile.js
并启用 Autoprefixer
module.exports = function (grunt) {
grunt.initConfig({
autoprefixer: {
dist: {
files: {
'build/style.css': 'style.css'
}
}
},
watch: {
styles: {
files: ['style.css'],
tasks: ['autoprefixer']
}
}
});
grunt.loadNpmTasks('grunt-autoprefixer');
grunt.loadNpmTasks('grunt-contrib-watch');
};
此配置启用使用 Autoprefixer 将 style.css
编译到 build/style.css
。此外,我们将使用 grunt-contrib-watch
,以便每次style.css
发生更改时重新编译 build/style.css
。
让我们启动 Grunt 的 Watch
./node_modules/.bin/grunt watch
现在,我们将向 style.css
添加一个 CSS3 表达式并保存该文件
a {
width: calc(50% - 2em)
}
神奇的事情发生了,现在我们有了 build/style.css
文件。Grunt 检测到 style.css
中的变化并启动了 Autoprefixer 任务。Autoprefixer 发现 calc()
值单位需要 为 Safari 6 添加供应商 前缀。
a {
width: -webkit-calc(50% - 2em);
width: calc(50% - 2em)
}
现在,我们将向 style.css
添加一些更复杂的 CSS3 并保存该文件
a {
width: calc(50% - 2em);
transition: transform 1s
}
Autoprefixer 已经知道 Chrome、Safari 6 和 Opera 15 需要 为 transition
和 transform
添加前缀。但 IE 9 也需要为 transform
添加前缀,而我们将其用作 transition
中的值。
a {
width: -webkit-calc(1% + 1em);
width: calc(1% + 1em);
-webkit-transition: -webkit-transform 1s;
transition: -ms-transform 1s;
transition: transform 1s
}
Autoprefixer 旨在为您完成所有繁重的工作。它将检查 Can I Use 数据库,写入所有必需的前缀,并且它也理解规范之间的差异。欢迎进入 CSS3 的未来——不再需要供应商前缀!
下一步是什么?
- Autoprefixer 支持 Ruby on Rails、Middleman、Mincer、Grunt、Sublime Text。详细了解如何在您的环境中使用它,请查看 文档。
- 如果您的环境尚不支持 Autoprefixer,请 报告,我会尽力提供帮助。
- 关注 @autoprefixer,获取有关更新和新功能的信息。
太棒了。我总是会忘记至少一个供应商 CSS 前缀,因此这将非常有用。
它是否也会像 Compass 那样为旧版本的 IE 添加前缀?http://compass-style.org/reference/compass/css3/images/#mixin-filter-gradient
我认为 mixin 是在这种情况下“正确的方法”,只需编写几个 mixin 并将它们放在一个库中。
IE 技巧并不适合所有人,因为旧版本的 IE 运行在旧机器上,而这些技巧非常慢。例如,我更喜欢优雅降级。因此,mixin 更适合此任务。或者,您可以编写另一个后处理器(使用 Rework 非常容易)来添加这些技巧。
我喜欢 Autoprefixer。在过去的几个月里,我一直在小型项目中使用它(我在大型项目中使用 Sass on Compass),它确实节省了很多时间!我使用 Sublime Text 2 插件,但不知道它也是 Grunt 插件!
很棒的文章,感谢您的提示 :)
感谢 Sara Soueidan 关于您在 Autoprefixer 上使用体验的反馈。事实上,我在寻找基于用户体验的评价,而不仅仅是促销。可靠的省时工具也非常受欢迎。
感谢帮助我做出决定。
不错!我自己也喜欢 Sublime Text 2 中的 command-control-x 快捷键!
我刚告诉自己:“我正在使用 sass/compass。足够好了。有了不错的流程。目前不需要新的东西。”
.. 但后来我看到了 Sublime Text 的一个插件。
“好吧。拿走我的钱”。
如果您使用 Sass 和 Compass,请尝试使用 Autoprefixer 与一些构建工具(Rails、Grunt)一起使用。在使用 Sublime Text 插件后,很难阅读和编辑带前缀的 CSS。
这再次肯定了浏览器创建者没有从过去吸取教训,我们总是不得不使用棘手的工具来“修复”浏览器,进行各种 hack 才能更接近(他们自己的)标准(目前定义良好)。首先是条件注释,然后是 css hack,现在是 css 编译器和 css 修复器,它们也插入编译器中。令人难以置信的是,浏览器将永远是“beta”产品。
无论如何,很棒的工具。
马克,如果我没记错的话,浏览器使用供应商前缀是因为特定的 css 属性实际上处于该浏览器(版本)的“beta”形式,一旦他们觉得它已正确实现,他们就会允许浏览器识别未加前缀的语法。每隔一段时间,你会发现你不再需要前缀,例如最新版本中的“border-radius”。
我喜欢这个。我再也不用担心供应商前缀了。
是否可以将它集成到 Compass(Foundation)工作流程中,这样我就不用运行 Compass 和 Grunt 了?我觉得我快成功了,试图在我的 config.rb 中使用 autoprefixer-rails 和 Compass 的“on_stylesheet_saved”,但我到目前为止还没有成功。
也许在 Middleman 中运行 Sass 编译会更好(它已经支持 Autoprefixer)。也许我们可以将 Autoprefixer 添加到 Compass foundation 中,但这会有点 hacky :(。
顺便说一句,Middleman(以及其他构建工具,如 Scout)比 Compass 功能强大得多。
我很快将在 README.md 中添加 Compass 的解决方案。
完成了。Autoprefixer README 现在有一个关于与 Compass 集成的部分
require ‘autoprefixer-rails’
on_stylesheet_saved do |file|
css = File.read(file)
File.open(file, ‘w’) { |io| io << AutoprefixerRails.compile(css) }
end
https://github.com/ai/autoprefixer#javascript
“您可以在浏览器中使用 Autoprefixer”
有人可以解释一下如何做到这一点吗?将您的 CSS 加载到浏览器窗口中并作为书签运行?从包含您 CSS 的网页运行?
我做了很多项目,我的工作流程要求我修改一个 CSS 文件,然后上传到服务器。
Autoprefixer 现在没有在浏览器中工作的最终用户工具。如果您添加 独立 JS,它只会创建一个
window.autoprefixer.compile()
函数,您需要手动调用它 :(。尝试使用 Sublime Text 的 Autoprefixer 插件,或者尝试将 Grunt(或类似工具)添加到您的工作流程中(因为有很多很酷的工具)。
谢谢安德烈。我真的很感谢你创建了这个工具并免费发布给公众。我确实希望有一种比安装多个命令行工具或切换到另一个文本编辑器更直接的使用方法。
你是否考虑过像 Prefixr 那样把它发布为网络服务? http://prefixr.com
不幸的是,我不喜欢网络服务(和文本编辑器插件)的想法。你只处理一次 CSS,然后你就会忘记你的文件,它们就会变得过时。前缀只会过时几个月。如果新浏览器开始支持该属性,你将不会添加新的前缀。
如果你使用构建工具,你只需要更新你的库(比如只用一个命令
bundle update
或npm update
),你就可以确保所有样式都是最新的。但如果你想创建这个网络服务,你可以创建它(轻松获得社区尊重和受欢迎程度,就像其他 Autoprefixer 插件开发人员一样)。
有没有办法让它在 CodeKit 上运行?
现在没有,但您可以支持这个 issue https://github.com/bdkjones/CodeKit/issues/653
正如布莱恩 所说,它将被添加。
有人试过这个吗? http://leaverou.github.io/prefixfree/
Lea 的 -prefix-free 是一个很酷的工具,如果您可以使用资产构建工具,它是一个不错的选择。但它只在浏览器中工作,对客户端性能非常不好,因为它将在最终用户的浏览器中处理 CSS,而不是在部署时只处理一次 CSS。
非常棒的工具,安德烈。干得好。
关于 prefixfree… 我已经在几个项目中使用过它,没有发现任何性能问题。有没有图表或基准测试显示这种“糟糕的客户端性能”?
性能问题在于 CSS。用户无法立即看到你的页面,因为页面 CSS 只有在 JS 完成工作后才能准备好。但不幸的是,没有基准测试(对 CSS 加载过程进行基准测试并不容易)。
对于像旧版线性渐变和具有特定角度的径向渐变(这些角度在相同的值下有很大差异)这样的东西,Autopreixer 会考虑这些吗?
是的,Autoprefixer 可以对数字进行数学运算,并非常灵活地更改语法。
但不要相信我,请查看测试 :) 从 → 到
嗨,安德烈,
这似乎是我一直在寻找的工具。有没有关于如何在 mac os 上安装和启动它的简单教程 - 我刚刚阅读了 github 上的 readme,但我不知道如何开始,比如命令行之类的东西...
您需要安装 Homebrew,然后安装 Node.js 和 npm。试试这个 Changelog 上的不错的 How To。
使用 npm,您可以通过 CSS Tricks 文章中的 How To 安装 Grunt 和 Autoprefixer。
有趣的是,flexbox 在示例中被使用 - 如何混合旧版和新版 flexbox,它不会删除过时的,但依赖的前缀吗?
Autoprefixer 将删除过时的 flexbox 属性(但现在它有一个 问题,即
-webkit-
2009 规范前缀对 Autoprefixer 来说并不过时)。此外,Autoprefixer 不会使您的前缀加倍。
我理解你的问题吗?:)
我还没有真正使用 flexbox,但我的问题是基于这里发布的混合使用旧版和新版 flexbox 的想法 https://css-tricks.org.cn/using-flexbox/
我并不是想贬低这个明显很棒的想法,只是好奇!
是的,Autoprefixer 为您修复规范。您只需使用最新的 W3C 规范编写 CSS,而无需添加前缀,然后忘记其他 flexbox 规范。Autoprefixer 将为所有旧规范重新编写属性。
哇。这在很棒的等级中排名很高!
我们不能只使用 SCSS 和 Bourbon.io 吗?
这将要求您在每次前缀更改时更新您的 mixin。
因为您需要始终思考,在哪些地方需要使用 mixin,在哪些地方不需要使用 mixin。此外,Bourbon 的开发周期比浏览器更新要慢得多。请参阅文章中关于 Compass 的所有要点,它们与 Bourbon 相同。
不错!
谢谢,克里斯。
哦!抱歉…
谢谢安德烈 :)
从未见过作者像您一样跟进自己的帖子并回复所有问题。您的 CSS 后处理器工具看起来确实很酷。我一定会密切关注它的发展。
我只想说,感谢 Andrey 使它对我们可用。
很棒的文章,但我建议您更改一下。当您安装 Grunt(`npm install grunt-cli ...`)时,您不会全局安装它。
一般来说,最好全局安装 Grunt(使用 `npm install -g grunt-cli` 而不是),因为它可以防止您必须引用本地项目的 Grunt 安装(就像您在这里所做的那样,使用 `./node_modules/.bin/grunt watch`)。
好文章,很高兴看到 Grunt 生态系统扩展到包括可以使我们生活更轻松的工具。感谢 Andrey。
如果某个项目需要一个版本的 npm 包,而另一个项目需要另一个版本,您将如何处理?
在 Ruby 世界中,我们使用 Bundler,它为每个项目锁定库。因此,我尝试在节点中也使用这种方式。我将所有项目的依赖项存储在项目目录中(但不在 git 中,当然)。
但是您的方法也是可行的:)。
Andrey,`grunt-cli` 应该全局安装,它只是一个 CLI 工具,`grunt` 作为对等依赖项在本地安装。
有人有带 autoprefixer 和 livereload 的 Gruntfile.js 的工作示例吗?
我无法让它们一起工作。当 livereload 处于活动状态时,autoprefixer 根本没有启动。
我的 Gruntfile.js:https://gist.github.com/sdvg/f0a881cfc0ae9e412e01
我不是从头开始构建这个 gruntfile 的,所以我不一定理解它的一切(我借用了现有的工作文件并进行了一些调整),但 autoprefixer 对我来说似乎有效。我使用 grunt-regarde 来监视更改,这可能有所不同。这是 gruntfile(coffeescript 语法)
https://github.com/byuweb/byu-responsive-dev/blob/eb4a269cbcd2df8d982b39db8bbd34b6ebee75e9/Gruntfile.coffee
很棒的工作。我对该工具以及适用于不同环境的各种实现印象深刻。
我使用 grunt 来构建我的 CSS,从 .scss 文件编译,在 SASS 中使用大量的 Compass。我有一些问题
**压缩输出** - 后处理的 CSS 文件在通过 autoprefixer 运行后实际上会变大一点,因为我使用的是 SASS 的压缩输出。有没有办法从 autoprefixer 启用压缩输出?
**源映射** - 这似乎更难。我已经让 SASS 除了 CSS 之外还输出源映射,以便我可以在 Chrome 开发工具中看到 .scss 源(而不是只看到 css 文件作为源)。这非常有用。在编译 SASS 后通过 autoprefixer 运行会完全破坏源映射。我想不出任何解决方法。有什么想法吗?
SASS 不是压缩 CSS 的最佳方式。尝试使用 csso:https://github.com/t32k/grunt-csso
源映射非常重要,但它需要在解析器中进行大量更改。请支持此问题:https://github.com/visionmedia/rework/issues/109
让源映射工作,我的成功率非常参差不齐。最后我找到了一个特定的 sass 和 compass 版本,它似乎可以工作,然后在 24 小时后,最新的 Chrome Canary 更新让事情变得极其不稳定,所以我放弃了。希望源映射很快就会添加到 sass 的非测试版中。
不过我会看看 autoprefixer,感谢 Andrey。Grunt 似乎也很不错,但我确实喜欢不必使用 compass.app 的命令行。
@Patrick,我同意源映射可能很麻烦。我也一直在使用 SASS 的预发布版,但一直能够坚持使用常规的 Chrome 而不是 Canary。我也希望 SASS 源映射很快进入完整发布版。在那之前,源映射的便利性足以让我忍受一些麻烦。
@Patrick:SASS 的源映射支持已经在 Chrome 稳定版中,并且已经存在两个月了!
Compass/Sass 不强迫您将过渡语法更改为使用逗号,这就是它优于 Less 的地方。您不需要写 `transition: width 1s ease`,而是写 `@include transition(width 1s ease)`。
请更新文章以更正错误。
它并没有说您必须这样做,而是建议您必须考虑是否必须这样做,而不是不必考虑它。
我的想法是,之前您需要逗号,并且其他 mixin 需要逗号。所以您需要考虑,我是否需要在 `transition` 中使用逗号?我看到了很多带有逗号的错误 Sass 代码。
在您的课程中,一些开发人员会问,为什么他们的 Sass 代码在 Compass 更新后崩溃,或者为什么他们的过渡不起作用。
那是不对的,您不必考虑在任何添加前缀的 mixin 中使用逗号。所有添加前缀的 mixin 的使用方法完全相同:您不需要写
property: some rules, some other rules;
而是写
@include property(some rules, some other rules);
您只需添加 @include 并使用括号代替冒号。但是值是逐个符号写入的,方式完全相同。任何以不同方式执行此操作的人都是错误的。
我同意 Autoprefixer 让您不必考虑它,但这并不能改变您将 Compass 的用法描述为比实际情况更难的事实。
我明白您的意思。但我是一个 compass 用户,我偶尔会考虑这个问题。文章中就是这样表达的,所以我不会更改它。
很棒的工具,Andrey。立即将其添加到我的 grunt 工作流样板中。
谢谢,老兄!
Andrey,这太棒了。我们将在 Jeet 中尽快实施它。赞扬。
我们已将此默认添加到 Jeet 中,Jeff Escalante 将其变成了一个很棒的独立 Stylus 插件:https://github.com/jenius/autoprefixer-stylus
现在您可以像这样使用它,并使用 Stylus 有效地替换 90% 的预处理器库功能
npm install -g autoprefixer-stylus
stylus -u autoprefixer-stylus -w