Spaces:
Sleeping
Sleeping
File size: 5,440 Bytes
cc651f6 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 |
# PostCSS Is Pseudo [<img src="https://postcss.github.io/postcss/logo.svg" alt="PostCSS" width="90" height="90" align="right">][postcss]
[![NPM Version][npm-img]][npm-url]
[![CSS Standard Status][css-img]][css-url]
[<img alt="Build Status" src="https://github.com/csstools/postcss-plugins/workflows/test/badge.svg" height="20">][cli-url]
[<img alt="Discord" src="https://shields.io/badge/Discord-5865F2?logo=discord&logoColor=white">][discord]
[PostCSS Is Pseudo Class] lets you use the `:is` pseudo class function, following the
[CSS Selector] specification.
```pcss
:is(input, button):is(:hover, :focus) {
order: 1;
}
```
Becomes :
```pcss
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:
```bash
npm install @csstools/postcss-is-pseudo-class --save-dev
```
Use [PostCSS Is Pseudo Class] as a [PostCSS] plugin:
```js
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:
| [Node](INSTALL.md#node) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) |
| --- | --- | --- | --- | --- |
## Options
### preserve
The `preserve` option determines whether the original notation
is preserved. By default, it is not preserved.
```js
postcss([
postcssIsPseudoClass({ preserve: true })
]).process(YOUR_CSS /*, processOptions */);
```
```pcss
:is(input, button):is(:hover, :focus) {
order: 1;
}
```
Becomes :
```pcss
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 to 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](#specificity).
```js
postcss([
postcssIsPseudoClass({ specificityMatchingName: 'something-random' })
]).process(YOUR_CSS /*, processOptions */);
```
```pcss
:is(.button, button):hover {
order: 7;
}
```
Becomes :
```pcss
.button:hover {
order: 7;
}
button:not(.something-random):hover {
order: 7;
}
```
### onComplexSelector
Warn on complex selectors in `:is` pseudo class functions.
```js
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>`.
```js
postcss([
postcssIsPseudoClass({ onPseudoElement: 'warning' })
]).process(YOUR_CSS /*, processOptions */);
```
```css
: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](https://polypane.app/css-specificity-calculator/#selector=%3Ais(%3Ahover%2C%20%3Afocus)%3Ais(.button%2C%20button))
```pcss
:is(:hover, :focus):is(.button, button) {
order: 7;
}
```
After :
```pcss
/* 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 :
```pcss
:is(.alpha > .beta) ~ :is(:focus > .beta) {
order: 2;
}
```
After :
```pcss
.alpha > .beta ~ :focus > .beta {
order: 2;
}
```
_this is a different selector than expected as `.beta ~ :focus` matches `.beta` followed by `:focus`._<br>
_avoid these cases._<br>
_writing the selector without `:is()` is advised here_
```pcss
/* 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.
[cli-url]: https://github.com/csstools/postcss-plugins/actions/workflows/test.yml?query=workflow/test
[css-img]: https://cssdb.org/images/badges/is-pseudo-class.svg
[css-url]: https://cssdb.org/#is-pseudo-class
[discord]: https://discord.gg/bUadyRwkJS
[npm-img]: https://img.shields.io/npm/v/@csstools/postcss-is-pseudo-class.svg
[npm-url]: https://www.npmjs.com/package/@csstools/postcss-is-pseudo-class
[CSS Selector]: https://www.w3.org/TR/selectors-4/#matches
[PostCSS]: https://github.com/postcss/postcss
[PostCSS Is Pseudo Class]: https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-is-pseudo-class
|