Autoprefixer 源自 PostCSS 给 CSS 自动添加前缀插件

发布于 2021-08-03 21:12:02 字数 24880 浏览 2719 评论 0

PostCSS 插件,用于解析 CSS 并使用 Can I Use 中的值向 CSS 规则添加供应商前缀 。它被谷歌推荐并用于推特和阿里巴巴。

编写没有供应商前缀的 CSS 规则(实际上,完全忘记它们):

::placeholder {
  color: gray;
}

.image {
  background-image: url(image@1x.png);
}
@media (min-resolution: 2dppx) {
  .image {
    background-image: url(image@2x.png);
  }
}

Autoprefixer 将使用基于当前浏览器流行度和属性支持的数据为您应用前缀。您可以尝试 Autoprefixer 的 交互式演示

::-moz-placeholder {
  color: gray;
}
:-ms-input-placeholder {
  color: gray;
}
::placeholder {
  color: gray;
}

.image {
  background-image: url(image@1x.png);
}
@media (-webkit-min-device-pixel-ratio: 2),
       (min-resolution: 2dppx) {
  .image {
    background-image: url(image@2x.png);
  }
}

新闻和发布的 Twitter 帐户:@autoprefixer

浏览器

Autoprefixer 使用 Browserslist,因此您可以使用诸如 > 5% (请参阅 最佳实践)之类的查询来指定要在项目中定位的浏览器。

提供浏览器的最佳方式是 .browserslistrc 在您的项目根目录中创建一个文件,或者browserslist在您的package.json.

我们建议使用这些选项而不是将选项传递给 Autoprefixer,以便可以与其他工具共享配置,例如 babel-preset-envStylelint

有关查询、浏览器名称、配置格式和默认值,请参阅 Browserslist 文档

常问问题

Autoprefixer 是否为 IE 填充网格布局?

Autoprefixer 可用于将现代 CSS Grid 语法转换为 IE 10 和 IE 11 语法,但此 polyfill 在 100% 的情况下不起作用。这就是默认情况下禁用它的原因。

首先,您需要使用 grid: "autoplace" 选项或 /* autoprefixer grid: autoplace */ 控件注释来启用网格前缀。您也可以使用环境变量来启用 Grid: AUTOPREFIXER_GRID=autoplace npm build

其次,您需要在 IE 中使用 Grid 测试每个修复程序。它不是启用和忘记功能,但它仍然非常有用。《金融时报》和 Yandex 在生产中使用它。

第三,只有非常有限的自动放置支持。有关更多详细信息,请阅读 IE 中的 网格自动放置支持 部分。

第四,如果您不使用自动放置功能,使用 Autoprefixer 的最佳方法是使用 grid-templategrid-template-areas

.page {
  display: grid;
  grid-gap: 33px;
  grid-template:
    "head head  head" 1fr
    "nav  main  main" minmax(100px, 1fr)
    "nav  foot  foot" 2fr /
    1fr   100px 1fr;
}
.page__head {
  grid-area: head;
}
.page__nav {
  grid-area: nav;
}
.page__main {
  grid-area: main;
}
.page__footer {
  grid-area: foot;
}

也可以看看:

它是否添加了polyfills?

不。Autoprefixer 只添加前缀。

大多数新的 CSS 功能都需要客户端 JavaScript 来正确处理新行为。

根据您认为的“polyfill”,您可以查看其他一些工具和库。如果你只是在寻找语法糖,你可以看看:

  • postcss-preset-env 是一个带有 polyfills 和 Autoprefixer 的插件预设,用于在今天编写未来的 CSS。
  • Oldie,一个处理一些 IE 黑客(不透明度、rgba 等)的 PostCSS 插件。
  • postcss-flexbugs-fixes,一个用于修复 flexbox 问题的 PostCSS 插件。

为什么 Autoprefixer 不添加前缀 border-radius

开发人员常常惊讶于如今所需的前缀如此之少。如果 Autoprefixer 没有为您的 CSS 添加前缀,请检查 Can I Use 上是否仍然需要它们。

为什么 Autoprefixer 在 中使用无前缀的属性 @-webkit-keyframes

浏览器团队可以在其他前缀之前删除一些前缀,因此我们尝试使用带前缀/不带前缀的值的所有组合。

如何使用 -webkit- 仅遗留代码?

Autoprefixer 需要无前缀的属性来添加前缀。所以如果你只写-webkit-gradient没有 W3C 的gradient,Autoprefixer 不会添加其他前缀。

但是 PostCSS 有插件可以将 CSS 转换为无前缀状态。在 Autoprefixer 之前使用 postcss- unprefix。

Autoprefixer 是否添加 -epub- 前缀?

不可以,Autoprefixer 仅适用于 Can I Use 中的浏览器前缀。但是您可以使用 postcss-epub 为 ePub3 属性添加前缀。

为什么 Autoprefixer 不转换通用字体系列 system-ui

system-ui技术上不是前缀,转换也不是面向未来的。您可以使用 postcss-font-family-system-ui 转换 system-ui 为实用的字体系列列表。

用法

Gulp

在 Gulp 中,您可以将 gulp-postcssautoprefixer npm 包一起使用。

gulp.task('autoprefixer', () => {
  const autoprefixer = require('autoprefixer')
  const sourcemaps = require('gulp-sourcemaps')
  const postcss = require('gulp-postcss')

  return gulp.src('./src/*.css')
    .pipe(sourcemaps.init())
    .pipe(postcss([ autoprefixer() ]))
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest('./dest'))
})

随着 gulp-postcss 你也可以结合 Autoprefixer 其他PostCSS插件

Webpack

在的 WebPack 你可以使用 postcss 装载机与 autoprefixer其他PostCSS插件

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader", "postcss-loader"]
      }
    ]
  }
}

并创建一个 postcss.config.js

module.exports = {
  plugins: [
    require('autoprefixer')
  ]
}

CSS-in-JS

将 PostCSS 与 CSS-in-JS 结合使用的最佳方式是astroturf. 将其加载程序添加到您的 webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader', 'postcss-loader'],
      },
      {
        test: /\.jsx?$/,
        use: ['babel-loader', 'astroturf/loader'],
      }
    ]
  }
}

然后创建 postcss.config.js

module.exports = {
  plugins: [
    require('autoprefixer')
  ]
}

CLI

您可以使用 postcss-cli 从 CLI 运行 Autoprefixer:

npm install postcss-cli autoprefixer
npx postcss *.css --use autoprefixer -d build/

查看postcss -h帮助。

其他构建工具

预处理器

图形用户界面工具

JavaScript

您可以在 Node.js 应用程序中使用 Autoprefixer 和 PostCSS,或者如果您想为新环境开发 Autoprefixer 插件。

const autoprefixer = require('autoprefixer')
const postcss = require('postcss')

postcss([ autoprefixer ]).process(css).then(result => {
  result.warnings().forEach(warn => {
    console.warn(warn.toString())
  })
  console.log(result.css)
})

还有一个用于浏览器或非 Node.js 运行时的 独立构建

您可以使用 html-autoprefixer 来处理内联 CSS 的 HTML。

文本编辑器和 IDE

Autoprefixer 应该用于资产构建工具。文本编辑器插件不是一个好的解决方案,因为前缀会降低代码的可读性,并且您需要更改所有前缀属性中的值。

我建议您学习如何使用 Parcel 之类的构建工具。它们工作得更好,将为您打开一个全新的有用插件和自动化世界。

如果您无法使用构建工具,则可以使用文本编辑器插件:

警告

Autoprefixer 使用 PostCSS 警告 API 来警告 CSS 中真正重要的问题:

  • 渐变中的旧方向语法。
  • 旧的无前缀 display: box 而不是 display: flex 最新的规范版本。

您可以从 result.warnings() 以下位置收到警告:

result.warnings().forEach(warn => {
  console.warn(warn.toString())
})

每个 Autoprefixer 运行程序都应该显示这些警告。

禁用

前缀

Autoprefixer 被设计成没有界面——它只是工作。如果您需要一些特定于浏览器的 hack,只需在无前缀的属性之后写一个带前缀的属性。

a {
  transform: scale(0.5);
  -moz-transform: scale(0.6);
}

如果某些前缀生成错误,请在 GitHub 上创建 问题

特征

您可以使用这些插件选项来控制 Autoprefixer 的一些功能。

  • grid: "autoplace"将为-ms-网格布局启用前缀,包括一些有限的自动放置 支持
  • supports: false将禁用@supports参数前缀。
  • flexbox: false将禁用 flexbox 属性前缀。或者flexbox: "no-2009"只会为规范的最终版本和 IE 版本添加前缀。
  • remove: false 将禁用清理过时的前缀。

你应该像这样在插件中设置它们:

autoprefixer({ grid: 'autoplace' })

控制评论

如果您的 CSS 的某些部分不需要 Autoprefixer,您可以使用控制注释来禁用 Autoprefixer。

.a {
  transition: 1s; /* will be prefixed */
}

.b {
  /* autoprefixer: off */
  transition: 1s; /* will not be prefixed */
}

.c {
  /* autoprefixer: ignore next */
  transition: 1s; /* will not be prefixed */
  mask: url(image.png); /* will be prefixed */
}

控制注释分为三种类型:

  • /* autoprefixer: (on|off) */:启用/禁用,那么整个块的所有Autoprefixer转换之前之后的评论。
  • /* autoprefixer: ignore next */: 仅对下一个属性或下一个规则选择器或规则参数(而不是规则/规则正文)禁用自动前缀。
  • /* autoprefixer grid: (autoplace|no-autoplace|off) */:控制 Autoprefixer 如何处理整个块的网格转换:
    • autoplace:启用具有自动放置支持的网格翻译。
    • no-autoplace: 在禁用自动放置支持的情况下启用网格转换(已弃用值的别名on)。
    • off:禁用所有网格翻译。

您还可以递归地使用注释:

/* autoprefixer: off */
@supports (transition: all) {
  /* autoprefixer: on */
  a {
    /* autoprefixer: off */
  }
}

请注意,禁用整个块的注释不应在同一块中出现两次:

/* How not to use block level control comments */

.do-not-do-this {
  /* autoprefixer: off */
  transition: 1s;
  /* autoprefixer: on */
  transform: rotate(20deg);
}

选项

函数 autoprefixer(options) 返回一个新的 PostCSS 插件。有关插件使用文档,请参阅 PostCSS API

autoprefixer({ cascade: false })

可用选项有:

  • env (string): Browserslist 的环境。
  • cascade(boolean): 如果 CSS 未压缩,Autoprefixer 应该使用 Visual Cascade。默认:true
  • add(boolean): Autoprefixer 应该添加前缀。默认为true
  • remove(boolean): Autoprefixer [remove outdated] 前缀。默认为true
  • supports(boolean): Autoprefixer 应该为@supports 参数添加前缀。默认为true
  • flexbox(boolean|string): Autoprefixer 应该为 flexbox 属性添加前缀。使用"no-2009"value Autoprefixer 将只为最终和 IE 10 版本的规范添加前缀。默认为true
  • grid(false| "autoplace"| "no-autoplace"): Autoprefixer 应该为网格布局属性添加 IE 10-11 前缀吗?
    • false (默认):防止 Autoprefixer 输出 CSS 网格翻译。
    • "autoplace":启用 Autoprefixer 网格翻译并包括自动放置支持。你也可以/* autoprefixer grid: autoplace */在你的 CSS 中使用 。
    • "no-autoplace": 启用 Autoprefixer 网格翻译但排除自动放置支持。你也可以/* autoprefixer grid: no-autoplace */在你的 CSS 中使用 。(已弃用true值的别名)
  • stats(对象):自定义使用统计> 10% in my stats 浏览器的查询。
  • overrideBrowserslist(array): 目标浏览器的查询列表。尽量不要使用它。最佳实践是使用.browserslistrcconfig 或browserslistkey inpackage.json与 Babel、ESLint 和 Stylelint 共享目标浏览器。有关 可用查询和默认值,请参阅 Browserslist 文档
  • ignoreUnknownVersions(boolean): 不要在 Browserslist 配置中的未知浏览器版本上引发错误。默认为false

插件对象具有info()用于调试目的的方法。

您可以使用 PostCSS 处理器处理多个 CSS 文件以提高性能。

环境变量

  • AUTOPREFIXER_GRID: ( autoplace| no-autoplace) Autoprefixer 应该为网格布局属性添加 IE 10-11 前缀吗?
    • autoplace:启用 Autoprefixer 网格翻译并包括自动放置支持。
    • no-autoplace: 启用 Autoprefixer 网格翻译但排除自动放置支持。

当您想更改 Autoprefixer 选项但无权访问配置文件时,环境变量很有用。Create React App 就是一个很好的例子。

在 Create React App 中使用环境变量来支持 CSS Grid 前缀

  1. 安装最新版本的 Autoprefixer 和cross-env
npm install autoprefixer@latest cross-env --save-dev
  1. 在 package.json 文件中的 "browserslist" >下 "development",添加 "last 1 ie version"
"browserslist": {
  "production": [
    ">0.2%",
    "not dead",
    "not op_mini all"
  ],
  "development": [
    "last 1 chrome version",
    "last 1 firefox version",
    "last 1 safari version",
    "last 1 ie version"
  ]
}
  1. "scripts"将 package.json 文件更新为以下内容:
"scripts": {
  "start": "cross-env AUTOPREFIXER_GRID=autoplace react-scripts start",
  "build": "cross-env AUTOPREFIXER_GRID=autoplace react-scripts build",
  "test": "cross-env AUTOPREFIXER_GRID=autoplace react-scripts test",
  "eject": "react-scripts eject"
},

如果您更喜欢禁用 Autoprefixer Grid 自动放置支持,请在上面的示例中替换autoplaceno-autoplace

现在,当您运行时,npm start您将看到 CSS 网格前缀自动应用于您的输出 CSS。

有关如何在项目中使用环境变量的更多示例,另请参阅Browserslist 环境变量

IE 中的网格自动放置支持

如果该grid选项设置为"autoplace",则会向 Autoprefixers 网格翻译添加有限的自动放置支持。您还可以使用/* autoprefixer grid: autoplace */控制注释或 AUTOPREFIXER_GRID=autoplace npm build环境变量。

Autoprefixer 只会在grid-template-rowsgrid-template-columns都已设置的情况下自动放置网格单元。如果grid-templategrid-template-areas已设置,Autoprefixer 将改为使用基于区域的单元格放置。

Autoprefixer 通过使用nth-childCSS 选择器支持自动放置。它创建 [列数] x [行数]nth-child选择器。因此,仅在显式网格内支持自动放置。

/* Input CSS */

/* autoprefixer grid: autoplace */

.autoplacement-example {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto auto;
  grid-gap: 20px;
}
/* Output CSS */

/* autoprefixer grid: autoplace */

.autoplacement-example {
  display: -ms-grid;
  display: grid;
  -ms-grid-columns: 1fr 20px 1fr;
  grid-template-columns: 1fr 1fr;
  -ms-grid-rows: auto 20px auto;
  grid-template-rows: auto auto;
  grid-gap: 20px;
}

.autoplacement-example > *:nth-child(1) {
  -ms-grid-row: 1;
  -ms-grid-column: 1;
}

.autoplacement-example > *:nth-child(2) {
  -ms-grid-row: 1;
  -ms-grid-column: 3;
}

.autoplacement-example > *:nth-child(3) {
  -ms-grid-row: 3;
  -ms-grid-column: 1;
}

.autoplacement-example > *:nth-child(4) {
  -ms-grid-row: 3;
  -ms-grid-column: 3;
}

当心在旧项目中启用自动放置

在之前没有使用过 Autoprefixer 的网格自动放置功能的任何已经建立的项目中启用自动放置时要小心。

如果这是您的 html:

<div class="grid">
  <div class="grid-cell"></div>
</div>

启用自动放置功能后,以下 CSS 将无法正常工作:

/* Unsafe CSS when Autoplacement is enabled */

.grid-cell {
  grid-column: 2;
  grid-row: 2;
}

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}

交换规则也不会解决问题:

/* Also unsafe to use this CSS */

.grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}

.grid-cell {
  grid-column: 2;
  grid-row: 2;
}

处理此问题的一种方法是在网格声明规则中禁用自动放置:

/* Disable autoplacement to fix the issue */

.grid {
  /* autoprefixer grid: no-autoplace */
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}

.grid-cell {
  grid-column: 2;
  grid-row: 2;
}

将自动放置集成到现有项目中的绝对最佳方法是默认关闭自动放置,然后在需要时使用控制注释启用它。这种方法不太可能导致网站上的某些内容中断。

/* Disable autoplacement by default in old projects */
/* autoprefixer grid: no-autoplace */

/* Old code will function the same way it always has */
.old-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
}
.old-grid-cell {
  grid-column: 2;
  grid-row: 2;
}

/* Enable autoplacement when you want to use it in new code */
.new-autoplace-friendly-grid {
  /* autoprefixer grid: autoplace */
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, auto);
}

请注意,grid: "no-autoplace"设置和 /* autoprefixer grid: no-autoplace */控制评论共享相同的功能的grid: true设置和/* autoprefixer grid: on */ 控制注释。无需重构旧代码来no-autoplace 代替旧的trueandon语句。

自动放置限制

必须定义列和行

自动放置仅在显式网格内有效。需要定义列和行,以便 Autoprefixer 知道nth-child要生成多少个选择器。

.not-allowed {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

.is-allowed {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(10, auto);
}

不支持重复自动适应和自动填充

repeat(auto-fit, ...)repeat(auto-fill, ...)网格功能依赖于知识约屏幕尺寸浏览器,可用网格项目的数量为它正常工作。Autoprefixer 无法访问此信息,因此不幸的是,这个小片段永远不会对 IE 友好。

.grid {
  /* This will never be IE friendly */
  grid-template-columns: repeat(auto-fit, min-max(200px, 1fr))
}

自动放置网格内不允许手动放置单元格或列/行跨度

不得在自动放置网格内手动放置元素或指定列/行跨度。仅支持最基本的自动放置网格。尽管如此,网格单元仍然可以手动放置在显式网格之外。计划在未来版本中支持在显式自动放置网格中手动放置单个网格单元。

.autoplacement-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, auto);
}

/* Grid cells placed inside the explicit grid
   will break the layout in IE */
.not-permitted-grid-cell {
  grid-column: 1;
  grid-row: 1;
}

/* Grid cells placed outside the
   explicit grid will work in IE */
.permitted-grid-cell {
  grid-column: 1 / span 2;
  grid-row: 4;
}

如果需要手动放置单元格,我们建议使用grid-templategrid-template-areas代替:

.page {
  display: grid;
  grid-gap: 30px;
  grid-template:
      "head head"
      "nav  main" minmax(100px, 1fr)
      "foot foot" /
      200px 1fr;
}
.page__head {
  grid-area: head;
}
.page__nav {
  grid-area: nav;
}
.page__main {
  grid-area: main;
}
.page__footer {
  grid-area: foot;
}

不要创建::before::after伪元素

假设你有这个 HTML:

<div class="grid">
  <div class="grid-cell"></div>
</div>

然后你写了这个 CSS:

.grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto;
}

.grid::before {
  content: 'before';
}

.grid::after {
  content: 'after';
}

这将是输出:

.grid {
  display: -ms-grid;
  display: grid;
  -ms-grid-columns: 1fr 1fr;
  grid-template-columns: 1fr 1fr;
  -ms-grid-rows: auto;
  grid-template-rows: auto;
}

.grid > *:nth-child(1) {
  -ms-grid-row: 1;
  -ms-grid-column: 1;
}


.grid > *:nth-child(2) {
  -ms-grid-row: 1;
  -ms-grid-column: 2;
}

.grid::before {
  content: 'before';
}

.grid::after {
  content: 'after';
}

IE 将放置.grid-cell,::before::after第 1 行第 1 列。另一方面,现代浏览器将放置::before在第 1 行第 1 列、 .grid-cell第 1::after行第 2 列和第 2 行第 1 列。

请参阅此CodePen以查看问题的可视化。在现代浏览器和 IE 中查看 CodePen 以查看差异。

请注意,只要您手动将它们放置在显式网格之外,您仍然可以创建::before::after元素。

更改 grid gap 值时,必须重新声明列和行

如果您希望更改 a 的大小 grid-gap,则需要重新声明网格列和行。

.grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto;
  grid-gap: 50px;
}

/* This will *NOT* work in IE */
@media (max-width: 600px) {
  .grid {
    grid-gap: 20px;
  }
}

/* This will *NOT* work in IE */
.grid.small-gap {
  grid-gap: 20px;
}
.grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto;
  grid-gap: 50px;
}

/* This *WILL* work in IE */
@media (max-width: 600px) {
  .grid {
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto;
    grid-gap: 20px;
  }
}

/* This *WILL* work in IE */
.grid.small-gap {
  grid-template-columns: 1fr 1fr;
  grid-template-rows: auto;
  grid-gap: 20px;
}

调试

npx autoprefixer --info在您的项目目录中运行以检查选择了哪些浏览器以及哪些属性将被添加前缀:

$ npx autoprefixer --info
Browsers:
  Edge: 16

These browsers account for 0.26% of all users globally

At-Rules:
  @viewport: ms

Selectors:
  ::placeholder: ms

Properties:
  appearance: webkit
  flow-from: ms
  flow-into: ms
  hyphens: ms
  overscroll-behavior: ms
  region-fragment: ms
  scroll-snap-coordinate: ms
  scroll-snap-destination: ms
  scroll-snap-points-x: ms
  scroll-snap-points-y: ms
  scroll-snap-type: ms
  text-size-adjust: ms
  text-spacing: ms
  user-select: ms

JS API 也可用:

console.log(autoprefixer().info())

安全联系人

要报告安全漏洞,请使用 Tidelift 安全联系人。Tidelift 将协调修复和披露。

企业用

作为 Tidelift 订阅的一部分提供。

的维护者 autoprefixer 和成千上万的其他包与Tidelift合作,为您用于构建应用程序的开源依赖商业支持和维护。节省时间、降低风险并改善代码健康状况,同时为您使用的确切依赖项的维护人员付费。了解更多。

项目地址:https://github.com/postcss/autoprefixer

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

0 文章
0 评论
84960 人气
更多

推荐作者

漫雪独思

文章 0 评论 0

垂暮老矣

文章 0 评论 0

鹊巢

文章 0 评论 0

萌酱

文章 0 评论 0

雨说

文章 0 评论 0

冰葑

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文