4.0.6 • Published 28 days ago

@csstools/postcss-is-pseudo-class v4.0.6

Weekly downloads
-
License
MIT-0
Repository
github
Last release
28 days ago

PostCSS Is Pseudo

NPM Version CSS Standard Status

PostCSS Is Pseudo Class lets you use the :is pseudo class function, following the CSS Selector specification.

:is(input, button):is(:hover, :focus) {
	order: 1;
}

Becomes :

input:hover {
	order: 1;
}
input:focus {
	order: 1;
}
button:hover {
	order: 1;
}
button:focus {
	order: 1;
}

Usage

Add PostCSS Is Pseudo Class to your project:

npm install @csstools/postcss-is-pseudo-class --save-dev

Use PostCSS Is Pseudo Class as a PostCSS plugin:

import postcss from 'postcss';
import postcssIsPseudoClass from '@csstools/postcss-is-pseudo-class';

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

PostCSS Is Pseudo Class runs in all Node environments, with special instructions for:

NodeWebpackGulpGrunt

Options

preserve

The preserve option determines whether the original notation is preserved. By default, it is not preserved.

postcss([
  postcssIsPseudoClass({ preserve: true })
]).process(YOUR_CSS /*, processOptions */);
:is(input, button):is(:hover, :focus) {
	order: 1;
}

Becomes :

input:hover {
	order: 1;
}
input:focus {
	order: 1;
}
button:hover {
	order: 1;
}
button:focus {
	order: 1;
}
:is(input, button):is(:hover, :focus) {
	order: 1;
}

specificityMatchingName

The specificityMatchingName option allows you to change the selector 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([
  postcssIsPseudoClass({ specificityMatchingName: 'something-random' })
]).process(YOUR_CSS /*, processOptions */);
:is(.button, button):hover {
	order: 7;
}

Becomes :

.button:hover {
	order: 7;
}

button:not(.something-random):hover {
	order: 7;
}

onComplexSelector

Warn on complex selectors in :is pseudo class functions.

postcss([
  postcssIsPseudoClass({ onComplexSelector: 'warning' })
]).process(YOUR_CSS /*, processOptions */);

onPseudoElement

Warn when pseudo elements are used in :is pseudo class functions.

⚠️ Pseudo elements are always invalid and will be transformed to ::-csstools-invalid-<pseudo-name>.

postcss([
  postcssIsPseudoClass({ onPseudoElement: 'warning' })
]).process(YOUR_CSS /*, processOptions */);
:is(::after):hover {
	order: 1.0;
}

/* becomes */

::-csstools-invalid-after:hover {
	order: 1.0;
}

⚠️ Known shortcomings

Specificity

:is takes the specificity of the most specific list item. We can increase specificity with :not selectors, but we can't decrease it.

Converted selectors are ensured to have the same specificity as :is for the most important bit. Less important bits can have higher specificity that :is.

Before :

specificity: 0, 2, 0

:is(:hover, :focus):is(.button, button) {
	order: 7;
}

After :

/* specificity: [0, 2, 0] */
.button:hover {
	order: 7;
}

/* specificity: [0, 2, 1] */
/* last bit is higher than it should be, but middle bit matches */
button:not(.does-not-exist):hover {
	order: 7;
}

/* specificity: [0, 2, 0] */
.button:focus {
	order: 7;
}

/* specificity: [0, 2, 1] */
/* last bit is higher than it should be, but middle bit matches */
button:not(.does-not-exist):focus {
	order: 7;
}

Complex selectors

Before :

:is(.alpha > .beta) ~ :is(:focus > .beta) {
	order: 2;
}

After :

.alpha > .beta ~ :focus > .beta {
	order: 2;
}

this is a different selector than expected as .beta ~ :focus matches .beta followed by :focus. avoid these cases. writing the selector without :is() is advised here

/* without is */
.alpha:focus > .beta ~ .beta {
	order: 2;
}

If you have a specific pattern you can open an issue to discuss it. We can detect and transform some cases but can't generalize them into a single solution that tackles all of them.

4.0.6

28 days ago

4.0.5

2 months ago

4.0.4

4 months ago

4.0.1

8 months ago

4.0.0

10 months ago

4.0.3

7 months ago

4.0.2

7 months ago

3.2.1

11 months ago

3.2.0

1 year ago

3.1.1

1 year ago

3.1.0

1 year ago

3.0.1

1 year ago

3.0.0

1 year ago

2.0.7

2 years ago

2.0.6

2 years ago

2.0.5

2 years ago

2.0.3

2 years ago

2.0.4

2 years ago

2.0.2

2 years ago

2.0.1

2 years ago

2.0.0

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago