Skip to content

PostCSS Preset Env 8

Romain Menke edited this page Oct 4, 2022 · 32 revisions

We're very mindful of the impact that major releases have which is why we're trying to keep the changes well documented, well thought out and establish a good way to move forward.

As a quick summary, we're trying to achieve the following:

Closest to spec

A polyfill should be indistinguishable from the native behavior

This has been our motto for a while! We've seen that specs rarely change, but they do! And also, over time, some plugins got some features that were not spec-compliant. We've closely reviewed plugins and made corrections where needed.

Removing old CDN links

Back when all of the plugins were moved to the monorepo (see announcement) we've been enforcing a consistent style among the plugins, both in terms of code style but also in file organization. This meant that links from unpkg hinted within plugins that require browser polyfills would have stopped working. To avoid creating more breaking changes, we had some script to copy to the old placement.

This script has now been removed so you will need to use the new locations if you rely on the old ones.

Disabling side effects

As hinted back in January, we're no longer enabling plugins that require a browser polyfill by default. We've seen that those are "expected" to work but that it wasn't obvious that a separate browser polyfill was also needed. Hence, those plugins were almost never bundled and the feature almost never worked.

The end result is that a minimal config of postcss-preset-env is more correct and will work for more users and cases.

Removing per-package CLI

There were some plugins that had CLI packages distributed and some that didn't, we remediated that by creating a global CLI. While we don't recommend using the CLI as part of any pipeline, it's definitely useful when trying to quickly debug or demonstrate something.

We've removed those outliers that still kept an independent CLI so if you were relying on that, you should now migrate to use @csstools/csstools-cli.

Impacted plugins

The following plugins have been impacted:

PostCSS Blank Pseudo breaking changes

The internal CLI exposed by the package has been removed in favor of the global CLI.

The old CDN URLs have been removed.

The browser polyfill has updated the initialization which means you need to update how it's called.

Generated CSS is now also different since it prepends js-blank-pseudo to the document on initialization so CSS doesn't start applying till then.

How to migrate

  • Re-build your CSS with the new version of the library.
  • If you use a CDN url, please update it.
- <script src="https://unpkg.com/css-blank-pseudo/browser"></script>
- <script src="https://unpkg.com/css-blank-pseudo/browser.min"></script>
+ <script src="https://unpkg.com/css-blank-pseudo/dist/browser-global.js"></script>
- cssBlankPseudo(document)
+ cssBlankPseudoInit()
- cssBlankPseudo({
-  attr: false,
-  className: 'blank'
- })
+ cssBlankPseudoInit({
+  replaceWith: '.blank'
+ })

PostCSS Focus Visible breaking changes

We've changed generated classes so it prepends .js-focus-visible to them. That way CSS is applied when the polyfill is known to be running. This class is added automatically by WICG's polyfill.

Even though there's no migration needed for this change, you might have been relying on the previous behavior which is why we've flagged this release as major.

PostCSS Focus Visible breaking changes

We've changed generated classes so it prepends .js-focus-within to them. That way CSS is applied when the polyfill is known to be running. This class is added automatically by our browser polyfill which is now bundled within postcss-focus-visible as opposed to using the one from JSXTools.

How to migrate

  • Import the polyfill from the PostCSS Plugin:
import focusWithinInit from 'postcss-focus-within/browser';

focusWithinInit();

PostCSS Has Pseudo breaking changes

We have deprecated the experimental version of the plugin. All issues have been resolved in the main plugin and the experimental plugin is no longer maintained.

How to migrate

  • Re-build your CSS with the new version of the library.
  • If you were relying on @csstools/css-has-pseudo-experimental, please use css-has-pseudo.
  • If you use a CDN URL, please update it.
- <script src="https://unpkg.com/css-has-pseudo/browser"></script>
+ <script src="https://unpkg.com/css-has-pseudo/dist/browser-global.js"></script>
- <script src="https://unpkg.com/css-has-pseudo/browser.min"></script>
+ <script src="https://unpkg.com/css-has-pseudo/dist/browser-global.js"></script>

PostCSS Preset Env breaking changes

enableClientSidePolyfills now defaults to false as opposed to true. This disables by default the following plugins:

These plugins require browser polyfills and transform your CSS in ways that make you dependent on the browser polyfill. As these plugins are rarely used and can be harmful we prefer to have these disabled by default.

How to migrate

If you did rely on plugins that need a client-side polyfill now pass the option enableClientSidePolyfills as true as opposed to not needing to pass it:

postcssPresetEnv({
+  enableClientSidePolyfill: true
});

Prefers Color Scheme breaking changes

The old CDN URLs have been removed.

color-depth fallback has been removed.

The no-preference support has been dropped as this has been removed from the spec.

The old global object has been removed.

How to migrate

  • Re-build your CSS with the new version of the library.
  • If you use a CDN URL, please update it.
- <script src="https://unpkg.com/css-prefers-color-scheme/browser"></script>
+ <script src="https://unpkg.com/css-prefers-color-scheme/dist/browser-global.js"></script>
- <script src="https://unpkg.com/css-prefers-color-scheme/browser.min"></script>
+ <script src="https://unpkg.com/css-prefers-color-scheme/dist/browser-global.js"></script>
  • Use prefersColorSchemeInit to initialize the polyfill in the browser.
- initPrefersColorScheme()
+ prefersColorSchemeInit()
  • Remove @media (prefer-color-scheme: no-preference) from your CSS.

@media (prefers-color-scheme: no-preference) was removed from the specification and should be equivalent to not having any media query.

- @media (prefers-color-scheme: no-preference) {
- 	.some-selector {
- 		/* your styles ... */
- 	}
- }
+ .some-selector {
+ 	/* your styles ... */
+ }

exportTo removal

postcss-custom-selectors

The exportTo option used to specify destinations where custom selectors can be exported to, which might have been CSS, JS, and JSON files, functions, and directly passed objects.

This feature has been removed as it was outside the scope of the plugin.

postcssCustomSelectors({
	exportTo: 'path/to/file.css' // @custom-selector :--heading h1, h2, h3;
});

The replacement for this feature is PostCSS Extract.

To match the format from the removed exportTo option you can use this snippet :

const postcss = require('postcss');
const postcssCustomSelectors = require('postcss-custom-selectors');
const postcssExtract = require('@csstools/postcss-extract');

postcss([
	postcssExtract({
		queries: {
			customSelectors: 'atrule[name="custom-selector"]'
		},
		results: (results) => {
			const formatted = {}

			results.customSelectors.forEach((atRule) => {
				const splitIndex = atRule.params.indexOf(' '); // split after the custom selector name
				formatted[atRule.params.slice(0, splitIndex)] = atRule.params.slice(splitIndex+1).trim();
			});

			console.log({
				customSelectors: formatted
			});
		}
	})
	postcssCustomSelectors(/* pluginOptions */)
]).process(YOUR_CSS /*, processOptions */);
Clone this wiki locally