Skip to content

Latest commit

 

History

History
173 lines (120 loc) · 4.97 KB

README-POSTCSS.md

File metadata and controls

173 lines (120 loc) · 4.97 KB

EXPERIMENTAL : CSS Has Pseudo for PostCSS

NPM Version Discord

Warning

Experimental version of CSS Has Pseudo

EXPERIMENTAL CSS Has Pseudo lets you style elements relative to other elements in CSS, following the Selectors Level 4 specification.

body:has(:focus) {
	background-color: yellow;
}

/* becomes */

[csstools-has-2q-33-2s-3d-1m-2w-2p-37-14-1m-2u-33-2r-39-37-15]:not(does-not-exist) {
	background-color: yellow;
}

body:has(:focus) {
	background-color: yellow;
}

EXPERIMENTAL CSS Has Pseudo duplicates rules using the :has pseudo-class with a [has] attribute selector. The preservation of the original :has rule can be disabled using the preserve option.

Usage

Add EXPERIMENTAL CSS Has Pseudo to your project:

npm install @csstools/css-has-pseudo-experimental --save-dev

Use EXPERIMENTAL CSS Has Pseudo as a PostCSS plugin:

const postcss = require('postcss');
const cssHasPseudoExperimental = require('@csstools/css-has-pseudo-experimental');

postcss([
	cssHasPseudoExperimental(/* pluginOptions */)
]).process(YOUR_CSS /*, processOptions */);

EXPERIMENTAL CSS Has Pseudo runs in all Node environments, with special instructions for:

Node PostCSS CLI Webpack Gulp Grunt

Options

preserve

The preserve option defines whether the original selector should remain. By default, the original selector is preserved.

cssHasPseudoExperimental({ preserve: false });
body:has(:focus) {
	background-color: yellow;
}

/* becomes */

[csstools-has-2q-33-2s-3d-1m-2w-2p-37-14-1m-2u-33-2r-39-37-15]:not(does-not-exist) {
	background-color: yellow;
}

specificityMatchingName

The specificityMatchingName option allows you to change to selector that is used to adjust specificity. The default value is does-not-exist. If this is an actual class, id or tag name in your code, you will need to set a different option here.

See how :not is used to modify specificity.

postcss([
	cssHasPseudoExperimental({ specificityMatchingName: 'something-random' })
]).process(YOUR_CSS /*, processOptions */);

specificity 1, 2, 0

Before :

.x:has(> #a:hover) {
	order: 11;
}

After :

specificity 1, 2, 0

[csstools-has-1a-3c-1m-2w-2p-37-14-1q-w-z-2p-1m-2w-33-3a-2t-36-15]:not(#does-not-exist):not(.does-not-exist) {
	order: 11;
}

⚠️ Known shortcomings

Specificity

:has transforms will result in at least one tag selector with specificity 0, 1, 0. If your selector has only tags we won't be able to match the original specificity.

Before :

specificity 0, 0, 2

figure:has(> img)

After :

specificity 0, 1, 2

[csstools-has-2u-2x-2v-39-36-2t-1m-2w-2p-37-14-1q-w-2x-31-2v-15]:not(does-not-exist):not(does-not-exist)

Plugin order

As selectors are encoded this plugin (or postcss-preset-env) must be run after any other plugin that transforms selectors.

For postcss-preset-env we take care to handle this for you.

If other plugins are used you need to place these in your config before postcss-preset-env or css-has-pseudo.

Please let us know if you have issues with plugins that transform selectors. Then we can investigate and maybe fix these.

PostCSS Preset Env

When you use postcss-preset-env you must disable the regular plugin.

The experimental plugin must be added after any other plugin that modifies selectors.

plugins: [
	// other plugins
	postcssPresetEnv({
		features: {
			'css-has-pseudo': false
		}
	}),
	// other plugins
	cssHasPseudoExperimental(), // last
]