UNPKG

11 kBMarkdownView Raw
1# PostCSS Preset Env [<img src="https://postcss.github.io/postcss/logo.svg" alt="PostCSS" width="90" height="90" align="right">][postcss]
2
3[<img alt="npm version" src="https://img.shields.io/npm/v/postcss-preset-env.svg" height="20">][npm-url]
4[<img alt="build status" src="https://github.com/csstools/postcss-plugins/workflows/test/badge.svg" height="20">][cli-url]
5[<img alt="support chat" src="https://img.shields.io/badge/support-chat-blue.svg" height="20">][git-url]
6
7[PostCSS Preset Env] lets you convert modern CSS into something most browsers
8can understand, determining the polyfills you need based on your targeted
9browsers or runtime environments.
10
11```bash
12npm install postcss-preset-env
13```
14
15```pcss
16@custom-media --viewport-medium (width <= 50rem);
17@custom-selector :--heading h1, h2, h3, h4, h5, h6;
18
19:root {
20 --mainColor: #12345678;
21}
22
23body {
24 color: var(--mainColor);
25 font-family: system-ui;
26 overflow-wrap: break-word;
27}
28
29:--heading {
30 background-image: image-set(url(img/heading.png) 1x, url(img/heading@2x.png) 2x);
31
32 @media (--viewport-medium) {
33 margin-block: 0;
34 }
35}
36
37a {
38 color: rgb(0 0 100% / 90%);
39
40 &:hover {
41 color: rebeccapurple;
42 }
43}
44
45/* becomes */
46
47:root {
48 --mainColor: rgba(18, 52, 86, 0.47059);
49}
50
51body {
52 color: rgba(18, 52, 86, 0.47059);
53 color: var(--mainColor);
54 font-family: system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Droid Sans, Helvetica Neue;
55 word-wrap: break-word;
56}
57
58h1, h2, h3, h4, h5, h6 {
59 background-image: url(img/heading.png);
60}
61
62@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
63 h1, h2, h3, h4, h5, h6 {
64 background-image: url(img/heading@2x.png)
65 }
66}
67
68@media (max-width: 50rem) {
69 h1, h2, h3, h4, h5, h6 {
70 margin-top: 0;
71 margin-bottom: 0;
72 }
73}
74
75a {
76 color: rgba(0, 0, 255, 0.9)
77}
78
79a:hover {
80 color: #639;
81}
82```
83
84Without any configuration options, [PostCSS Preset Env] enables **Stage 2**
85features and supports **all** browsers.
86
87[![Transform with Preset Env][readme-transform-with-preset-env-img]][readme-transform-with-preset-env-url]
88[![Style with Preset Env][readme-style-with-preset-env-img]][readme-style-with-preset-env-url]
89
90## Usage
91
92Add [PostCSS Preset Env] to your project:
93
94```bash
95npm install postcss-preset-env --save-dev
96```
97
98Use [PostCSS Preset Env] as a [PostCSS] plugin:
99
100```js
101const postcss = require('postcss');
102const postcssPresetEnv = require('postcss-preset-env');
103
104postcss([
105 postcssPresetEnv(/* pluginOptions */)
106]).process(YOUR_CSS /*, processOptions */);
107```
108
109[PostCSS Preset Env] runs in all Node environments, with special instructions for:
110
111| [Node](INSTALL.md#node) | [PostCSS CLI](INSTALL.md#postcss-cli) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) | [Rollup](INSTALL.md#rollup) |
112| --- | --- | --- | --- | --- | --- | --- |
113
114## Options
115
116### stage
117
118The `stage` option determines which CSS features to polyfill, based upon their
119stability in the process of becoming implemented web standards.
120
121```js
122postcssPresetEnv({ stage: 0 })
123```
124
125The `stage` can be `0` (experimental) through `4` (stable), or `false`. Setting
126`stage` to `false` will disable every polyfill. Doing this would only be useful
127if you intended to exclusively use the [`features`](#features) option.
128
129Without any configuration options, [PostCSS Preset Env] enables **Stage 2**
130features.
131
132### features
133
134The `features` option enables or disables specific polyfills by ID. Passing
135`true` to a specific feature ID will enable its polyfill, while passing `false`
136will disable it. [List of IDs](https://github.com/csstools/postcss-plugins/blob/main/plugin-packs/postcss-preset-env/src/lib/plugins-by-id.js#L74)
137
138```js
139postcssPresetEnv({
140 /* use stage 3 features + css nesting rules */
141 stage: 3,
142 features: {
143 'nesting-rules': true
144 }
145})
146```
147
148Passing an object to a specific feature ID will both enable and configure it.
149
150```js
151postcssPresetEnv({
152 /* use stage 3 features + css color-mod (warning on unresolved) */
153 stage: 3,
154 features: {
155 'color-mod-function': { unresolved: 'warn' }
156 }
157})
158```
159
160Any polyfills not explicitly enabled or disabled through `features` are
161determined by the [`stage`](#stage) option.
162
163### browsers
164
165The `browsers` option determines which polyfills are required based upon the
166browsers you are supporting.
167
168[PostCSS Preset Env] supports any standard [browserslist] configuration, which
169can be a `.browserslistrc` file, a `browserslist` key in `package.json`, or
170`browserslist` environment variables.
171
172The `browsers` option should only be used when a standard browserslist
173configuration is not available.
174
175```js
176postcssPresetEnv({ browsers: 'last 2 versions' })
177```
178
179If not valid browserslist configuration is specified, the
180[default browserslist query](https://github.com/browserslist/browserslist#queries)
181will be used.
182
183### insertBefore / insertAfter
184
185The `insertBefore` and `insertAfter` keys allow you to insert other PostCSS
186plugins into the chain. This is only useful if you are also using sugary
187PostCSS plugins that must execute before or after certain polyfills.
188Both `insertBefore` and `insertAfter` support chaining one or multiple plugins.
189
190```js
191import postcssSimpleVars from 'postcss-simple-vars';
192
193postcssPresetEnv({
194 insertBefore: {
195 'all-property': postcssSimpleVars
196 }
197})
198```
199
200### autoprefixer
201
202[PostCSS Preset Env] includes [autoprefixer] and [`browsers`](#browsers) option
203will be passed to it automatically.
204
205Specifying the `autoprefixer` option enables passing
206[additional options](https://github.com/postcss/autoprefixer#options)
207into [autoprefixer].
208
209```js
210postcssPresetEnv({
211 autoprefixer: { grid: true }
212})
213```
214
215Passing `autoprefixer: false` disables autoprefixer.
216
217### preserve
218
219The `preserve` option determines whether all plugins should receive a
220`preserve` option, which may preserve or remove otherwise-polyfilled CSS. By
221default, this option is not configured.
222
223```js
224postcssPresetEnv({
225 preserve: false // instruct all plugins to omit pre-polyfilled CSS
226});
227```
228
229### importFrom
230
231The `importFrom` option specifies sources where variables like Custom Media,
232Custom Properties, Custom Selectors, and Environment Variables can be imported
233from, which might be CSS, JS, and JSON files, functions, and directly passed
234objects.
235
236```js
237postcssPresetEnv({
238 /*
239 @custom-media --small-viewport (max-width: 30em);
240 @custom-selector :--heading h1, h2, h3;
241 :root { --color: red; }
242 */
243 importFrom: 'path/to/file.css'
244});
245```
246
247Multiple sources can be passed into this option, and they will be parsed in the
248order they are received. JavaScript files, JSON files, functions, and objects
249will use different namespaces to import different kinds of variables.
250
251```js
252postcssPresetEnv({
253 importFrom: [
254 /*
255 @custom-media --small-viewport (max-width: 30em);
256 @custom-selector :--heading h1, h2, h3;
257 :root { --color: red; }
258 */
259 'path/to/file.css',
260
261 /* module.exports = {
262 customMedia: { '--small-viewport': '(max-width: 30em)' },
263 customProperties: { '--color': 'red' },
264 customSelectors: { ':--heading': 'h1, h2, h3' },
265 environmentVariables: { '--branding-padding': '20px' }
266 } */
267 'and/then/this.js',
268
269 /* {
270 "custom-media": { "--small-viewport": "(max-width: 30em)" }
271 "custom-properties": { "--color": "red" },
272 "custom-selectors": { ":--heading": "h1, h2, h3" },
273 "environment-variables": { "--branding-padding": "20px" }
274 } */
275 'and/then/that.json',
276
277 {
278 customMedia: { '--small-viewport': '(max-width: 30em)' },
279 customProperties: { '--color': 'red' },
280 customSelectors: { ':--heading': 'h1, h2, h3' },
281 environmentVariables: { '--branding-padding': '20px' }
282 },
283 () => {
284 const customMedia = { '--small-viewport': '(max-width: 30em)' };
285 const customProperties = { '--color': 'red' };
286 const customSelectors = { ':--heading': 'h1, h2, h3' };
287 const environmentVariables = { '--branding-padding': '20px' };
288
289 return { customMedia, customProperties, customSelectors, environmentVariables };
290 }
291 ]
292});
293```
294
295### exportTo
296
297The `exportTo` option specifies destinations where variables like Custom Media,
298Custom Properties, Custom Selectors, and Environment Variables can be exported
299to, which might be CSS, JS, and JSON files, functions, and directly passed
300objects.
301
302```js
303postcssPresetEnv({
304 /*
305 @custom-media --small-viewport (max-width: 30em);
306 @custom-selector :--heading h1, h2, h3;
307 :root { --color: red; }
308 */
309 exportTo: 'path/to/file.css'
310});
311```
312
313Multiple destinations can be passed into this option as well, and they will be
314parsed in the order they are received. JavaScript files, JSON files, and
315objects will use different namespaces to import different kinds of variables.
316
317```js
318const cachedObject = {};
319
320postcssPresetEnv({
321 exportTo: [
322 /*
323 @custom-media --small-viewport (max-width: 30em);
324 @custom-selector :--heading h1, h2, h3;
325 :root { --color: red; }
326 */
327 'path/to/file.css',
328
329 /* module.exports = {
330 customMedia: { '--small-viewport': '(max-width: 30em)' },
331 customProperties: { '--color': 'red' },
332 customSelectors: { ':--heading': 'h1, h2, h3' },
333 environmentVariables: { '--branding-padding': '20px' }
334 } */
335 'and/then/this.js',
336
337 /* {
338 "custom-media": { "--small-viewport": "(max-width: 30em)" }
339 "custom-properties": { "--color": "red" },
340 "custom-selectors": { ":--heading": "h1, h2, h3" },
341 "environment-variables": { "--branding-padding": "20px" }
342 } */
343 'and/then/that.json',
344
345 cachedObject,
346 variables => {
347 if ('customProperties' in variables) {
348 // do something special with customProperties
349 }
350
351 Object.assign(cachedObject, variables);
352 }
353 ]
354});
355```
356
357[cli-img]: https://github.com/csstools/postcss-plugins/workflows/test/badge.svg
358[cli-url]: https://github.com/csstools/postcss-plugins/actions/workflows/test.yml?query=workflow/test
359[git-img]: https://img.shields.io/badge/support-chat-blue.svg
360[git-url]: https://gitter.im/postcss/postcss
361[npm-img]: https://img.shields.io/npm/v/postcss-preset-env.svg
362[npm-url]: https://www.npmjs.com/package/postcss-preset-env
363
364[autoprefixer]: https://github.com/postcss/autoprefixer
365[browserslist]: https://github.com/browserslist/browserslist#readme
366[caniuse]: https://caniuse.com/
367[cssdb]: https://cssdb.org/
368[PostCSS]: https://github.com/postcss/postcss
369[PostCSS Preset Env]: https://github.com/csstools/postcss-plugins/tree/main/plugin-packs/postcss-preset-env
370[readme-style-with-preset-env-img]: https://csstools.github.io/postcss-preset-env/readme-style-with-preset-env.svg
371[readme-style-with-preset-env-url]: https://codepen.io/pen?template=OZRovK
372[readme-transform-with-preset-env-img]: https://csstools.github.io/postcss-preset-env/readme-transform-with-preset-env.svg
373[readme-transform-with-preset-env-url]: https://csstools.github.io/postcss-preset-env/