diff --git a/package-lock.json b/package-lock.json
index 1a4a9509c..e32328135 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -7092,6 +7092,9 @@
"dependencies": {
"postcss-selector-parser": "^6.0.10"
},
+ "devDependencies": {
+ "puppeteer": "^15.1.1"
+ },
"engines": {
"node": "^12 || ^14 || >=16"
},
@@ -11380,7 +11383,8 @@
"postcss-focus-visible": {
"version": "file:plugins/postcss-focus-visible",
"requires": {
- "postcss-selector-parser": "^6.0.10"
+ "postcss-selector-parser": "^6.0.10",
+ "puppeteer": "^15.1.1"
}
},
"postcss-focus-within": {
diff --git a/plugin-packs/postcss-preset-env/test/basic.autoprefixer.expect.css b/plugin-packs/postcss-preset-env/test/basic.autoprefixer.expect.css
index 67c580e48..04a386918 100644
--- a/plugin-packs/postcss-preset-env/test/basic.autoprefixer.expect.css
+++ b/plugin-packs/postcss-preset-env/test/basic.autoprefixer.expect.css
@@ -248,11 +248,7 @@
word-wrap: break-word;
}
-.test-focus-visible-pseudo-class.focus-visible {
- order: 26;
-}
-
-.test-focus-visible-pseudo-class:focus-visible {
+.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible {
order: 26;
}
diff --git a/plugin-packs/postcss-preset-env/test/basic.autoprefixer.false.expect.css b/plugin-packs/postcss-preset-env/test/basic.autoprefixer.false.expect.css
index 67c580e48..04a386918 100644
--- a/plugin-packs/postcss-preset-env/test/basic.autoprefixer.false.expect.css
+++ b/plugin-packs/postcss-preset-env/test/basic.autoprefixer.false.expect.css
@@ -248,11 +248,7 @@
word-wrap: break-word;
}
-.test-focus-visible-pseudo-class.focus-visible {
- order: 26;
-}
-
-.test-focus-visible-pseudo-class:focus-visible {
+.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible {
order: 26;
}
diff --git a/plugin-packs/postcss-preset-env/test/basic.ch38.expect.css b/plugin-packs/postcss-preset-env/test/basic.ch38.expect.css
index 8662f17da..a5705715b 100644
--- a/plugin-packs/postcss-preset-env/test/basic.ch38.expect.css
+++ b/plugin-packs/postcss-preset-env/test/basic.ch38.expect.css
@@ -168,11 +168,7 @@
overflow-wrap: break-word;
}
-.test-focus-visible-pseudo-class.focus-visible {
- order: 26;
-}
-
-.test-focus-visible-pseudo-class:focus-visible {
+.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible {
order: 26;
}
diff --git a/plugin-packs/postcss-preset-env/test/basic.ch88-ff78-saf10.expect.css b/plugin-packs/postcss-preset-env/test/basic.ch88-ff78-saf10.expect.css
index aa72d3538..e2e988048 100644
--- a/plugin-packs/postcss-preset-env/test/basic.ch88-ff78-saf10.expect.css
+++ b/plugin-packs/postcss-preset-env/test/basic.ch88-ff78-saf10.expect.css
@@ -167,11 +167,7 @@ h1.test-custom-selectors,h2.test-custom-selectors,h3.test-custom-selectors,h4.te
overflow-wrap: break-word;
}
-.test-focus-visible-pseudo-class.focus-visible {
- order: 26;
-}
-
-.test-focus-visible-pseudo-class:focus-visible {
+.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible {
order: 26;
}
diff --git a/plugin-packs/postcss-preset-env/test/basic.ch88-ff78.expect.css b/plugin-packs/postcss-preset-env/test/basic.ch88-ff78.expect.css
index 13a393a42..1bacd82cf 100644
--- a/plugin-packs/postcss-preset-env/test/basic.ch88-ff78.expect.css
+++ b/plugin-packs/postcss-preset-env/test/basic.ch88-ff78.expect.css
@@ -160,11 +160,7 @@ h1.test-custom-selectors,h2.test-custom-selectors,h3.test-custom-selectors,h4.te
overflow-wrap: break-word;
}
-.test-focus-visible-pseudo-class.focus-visible {
- order: 26;
-}
-
-.test-focus-visible-pseudo-class:focus-visible {
+.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible {
order: 26;
}
diff --git a/plugin-packs/postcss-preset-env/test/basic.ch88-ff78.no-is-pseudo.expect.css b/plugin-packs/postcss-preset-env/test/basic.ch88-ff78.no-is-pseudo.expect.css
index beeba4b2b..f952bd095 100644
--- a/plugin-packs/postcss-preset-env/test/basic.ch88-ff78.no-is-pseudo.expect.css
+++ b/plugin-packs/postcss-preset-env/test/basic.ch88-ff78.no-is-pseudo.expect.css
@@ -160,11 +160,7 @@ h1.test-custom-selectors,h2.test-custom-selectors,h3.test-custom-selectors,h4.te
overflow-wrap: break-word;
}
-.test-focus-visible-pseudo-class.focus-visible {
- order: 26;
-}
-
-.test-focus-visible-pseudo-class:focus-visible {
+.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible {
order: 26;
}
diff --git a/plugin-packs/postcss-preset-env/test/basic.expect.css b/plugin-packs/postcss-preset-env/test/basic.expect.css
index 55763624e..e11ceebf5 100644
--- a/plugin-packs/postcss-preset-env/test/basic.expect.css
+++ b/plugin-packs/postcss-preset-env/test/basic.expect.css
@@ -271,11 +271,7 @@
word-wrap: break-word;
}
-.test-focus-visible-pseudo-class.focus-visible {
- order: 26;
-}
-
-.test-focus-visible-pseudo-class:focus-visible {
+.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible {
order: 26;
}
diff --git a/plugin-packs/postcss-preset-env/test/basic.ff49.expect.css b/plugin-packs/postcss-preset-env/test/basic.ff49.expect.css
index 34b0a3fa7..ffefaebfe 100644
--- a/plugin-packs/postcss-preset-env/test/basic.ff49.expect.css
+++ b/plugin-packs/postcss-preset-env/test/basic.ff49.expect.css
@@ -164,11 +164,7 @@
overflow-wrap: break-word;
}
-.test-focus-visible-pseudo-class.focus-visible {
- order: 26;
-}
-
-.test-focus-visible-pseudo-class:focus-visible {
+.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible {
order: 26;
}
diff --git a/plugin-packs/postcss-preset-env/test/basic.ff66.expect.css b/plugin-packs/postcss-preset-env/test/basic.ff66.expect.css
index 37806912a..750ac0a92 100644
--- a/plugin-packs/postcss-preset-env/test/basic.ff66.expect.css
+++ b/plugin-packs/postcss-preset-env/test/basic.ff66.expect.css
@@ -152,11 +152,7 @@
overflow-wrap: break-word;
}
-.test-focus-visible-pseudo-class.focus-visible {
- order: 26;
-}
-
-.test-focus-visible-pseudo-class:focus-visible {
+.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible {
order: 26;
}
diff --git a/plugin-packs/postcss-preset-env/test/basic.ie10.expect.css b/plugin-packs/postcss-preset-env/test/basic.ie10.expect.css
index 3c2fbd479..04aa57af0 100644
--- a/plugin-packs/postcss-preset-env/test/basic.ie10.expect.css
+++ b/plugin-packs/postcss-preset-env/test/basic.ie10.expect.css
@@ -278,12 +278,7 @@
word-wrap: break-word;
}
-.test-focus-visible-pseudo-class.focus-visible {
- -ms-flex-order: 26;
- order: 26;
-}
-
-.test-focus-visible-pseudo-class:focus-visible {
+.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible {
-ms-flex-order: 26;
order: 26;
}
diff --git a/plugin-packs/postcss-preset-env/test/basic.nesting.false.expect.css b/plugin-packs/postcss-preset-env/test/basic.nesting.false.expect.css
index 12dca7cf3..ffb44f222 100644
--- a/plugin-packs/postcss-preset-env/test/basic.nesting.false.expect.css
+++ b/plugin-packs/postcss-preset-env/test/basic.nesting.false.expect.css
@@ -269,11 +269,7 @@ h1.test-custom-selectors,h2.test-custom-selectors,h3.test-custom-selectors,h4.te
word-wrap: break-word;
}
-.test-focus-visible-pseudo-class.focus-visible {
- order: 26;
-}
-
-.test-focus-visible-pseudo-class:focus-visible {
+.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible {
order: 26;
}
diff --git a/plugin-packs/postcss-preset-env/test/basic.op_mini.expect.css b/plugin-packs/postcss-preset-env/test/basic.op_mini.expect.css
index 57e75c092..b49914b31 100644
--- a/plugin-packs/postcss-preset-env/test/basic.op_mini.expect.css
+++ b/plugin-packs/postcss-preset-env/test/basic.op_mini.expect.css
@@ -255,11 +255,7 @@ h1.test-custom-selectors,h2.test-custom-selectors,h3.test-custom-selectors,h4.te
word-wrap: break-word;
}
-.test-focus-visible-pseudo-class.focus-visible {
- order: 26;
-}
-
-.test-focus-visible-pseudo-class:focus-visible {
+.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible {
order: 26;
}
diff --git a/plugin-packs/postcss-preset-env/test/basic.preserve.true.expect.css b/plugin-packs/postcss-preset-env/test/basic.preserve.true.expect.css
index 4e01ebd91..a1f0d0dd7 100644
--- a/plugin-packs/postcss-preset-env/test/basic.preserve.true.expect.css
+++ b/plugin-packs/postcss-preset-env/test/basic.preserve.true.expect.css
@@ -495,7 +495,7 @@ h1.test-custom-selectors,h2.test-custom-selectors,h3.test-custom-selectors,h4.te
word-wrap: break-word;
}
-.test-focus-visible-pseudo-class.focus-visible {
+.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible {
-webkit-box-ordinal-group: 27;
-webkit-order: 26;
-moz-box-ordinal-group: 27;
diff --git a/plugin-packs/postcss-preset-env/test/basic.safari15.expect.css b/plugin-packs/postcss-preset-env/test/basic.safari15.expect.css
index 725600ff5..34fb267d8 100644
--- a/plugin-packs/postcss-preset-env/test/basic.safari15.expect.css
+++ b/plugin-packs/postcss-preset-env/test/basic.safari15.expect.css
@@ -137,11 +137,7 @@
overflow-wrap: break-word;
}
-.test-focus-visible-pseudo-class.focus-visible {
- order: 26;
-}
-
-.test-focus-visible-pseudo-class:focus-visible {
+.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible {
order: 26;
}
diff --git a/plugin-packs/postcss-preset-env/test/basic.stage0-ff49.expect.css b/plugin-packs/postcss-preset-env/test/basic.stage0-ff49.expect.css
index a58b488f0..819fa1807 100644
--- a/plugin-packs/postcss-preset-env/test/basic.stage0-ff49.expect.css
+++ b/plugin-packs/postcss-preset-env/test/basic.stage0-ff49.expect.css
@@ -169,11 +169,7 @@ h1.test-custom-selectors,h2.test-custom-selectors,h3.test-custom-selectors,h4.te
overflow-wrap: break-word;
}
-.test-focus-visible-pseudo-class.focus-visible {
- order: 26;
-}
-
-.test-focus-visible-pseudo-class:focus-visible {
+.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible {
order: 26;
}
diff --git a/plugin-packs/postcss-preset-env/test/basic.stage0-ff66.expect.css b/plugin-packs/postcss-preset-env/test/basic.stage0-ff66.expect.css
index 26f9a3fee..6c3310c42 100644
--- a/plugin-packs/postcss-preset-env/test/basic.stage0-ff66.expect.css
+++ b/plugin-packs/postcss-preset-env/test/basic.stage0-ff66.expect.css
@@ -157,11 +157,7 @@ h1.test-custom-selectors,h2.test-custom-selectors,h3.test-custom-selectors,h4.te
overflow-wrap: break-word;
}
-.test-focus-visible-pseudo-class.focus-visible {
- order: 26;
-}
-
-.test-focus-visible-pseudo-class:focus-visible {
+.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible {
order: 26;
}
diff --git a/plugin-packs/postcss-preset-env/test/basic.stage0.expect.css b/plugin-packs/postcss-preset-env/test/basic.stage0.expect.css
index 57e734eae..2b9efb7d1 100644
--- a/plugin-packs/postcss-preset-env/test/basic.stage0.expect.css
+++ b/plugin-packs/postcss-preset-env/test/basic.stage0.expect.css
@@ -276,11 +276,7 @@ h1.test-custom-selectors,h2.test-custom-selectors,h3.test-custom-selectors,h4.te
word-wrap: break-word;
}
-.test-focus-visible-pseudo-class.focus-visible {
- order: 26;
-}
-
-.test-focus-visible-pseudo-class:focus-visible {
+.test-focus-visible-pseudo-class.focus-visible.js-focus-visible, .js-focus-visible .test-focus-visible-pseudo-class.focus-visible {
order: 26;
}
diff --git a/plugin-packs/postcss-preset-env/test/client-side-polyfills.stage-1.expect.css b/plugin-packs/postcss-preset-env/test/client-side-polyfills.stage-1.expect.css
index ba171663b..eb3e1fa8a 100644
--- a/plugin-packs/postcss-preset-env/test/client-side-polyfills.stage-1.expect.css
+++ b/plugin-packs/postcss-preset-env/test/client-side-polyfills.stage-1.expect.css
@@ -2,7 +2,7 @@
order: 1;
}
-.focus-visible {
+.focus-visible.js-focus-visible, .js-focus-visible .focus-visible {
order: 2;
}
diff --git a/plugin-packs/postcss-preset-env/test/client-side-polyfills.stage-2.expect.css b/plugin-packs/postcss-preset-env/test/client-side-polyfills.stage-2.expect.css
index f72e02255..557e9e2a1 100644
--- a/plugin-packs/postcss-preset-env/test/client-side-polyfills.stage-2.expect.css
+++ b/plugin-packs/postcss-preset-env/test/client-side-polyfills.stage-2.expect.css
@@ -2,7 +2,7 @@
order: 1;
}
-.focus-visible {
+.focus-visible.js-focus-visible, .js-focus-visible .focus-visible {
order: 2;
}
diff --git a/plugin-packs/postcss-preset-env/test/layers-basic.expect.css b/plugin-packs/postcss-preset-env/test/layers-basic.expect.css
index 88a4963f9..a51a04d89 100644
--- a/plugin-packs/postcss-preset-env/test/layers-basic.expect.css
+++ b/plugin-packs/postcss-preset-env/test/layers-basic.expect.css
@@ -445,15 +445,7 @@ h1.test-custom-selectors:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):n
word-wrap: break-word;
}
-.test-focus-visible-pseudo-class.focus-visible:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) {
- -webkit-box-ordinal-group: 27;
- -webkit-order: 26;
- -moz-box-ordinal-group: 27;
- -ms-flex-order: 26;
- order: 26;
-}
-
-.test-focus-visible-pseudo-class:focus-visible:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) {
+.test-focus-visible-pseudo-class.focus-visible.js-focus-visible:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#), .js-focus-visible:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) .test-focus-visible-pseudo-class.focus-visible {
-webkit-box-ordinal-group: 27;
-webkit-order: 26;
-moz-box-ordinal-group: 27;
diff --git a/plugin-packs/postcss-preset-env/test/layers-basic.preserve.true.expect.css b/plugin-packs/postcss-preset-env/test/layers-basic.preserve.true.expect.css
index 47a28fae3..d007c24b5 100644
--- a/plugin-packs/postcss-preset-env/test/layers-basic.preserve.true.expect.css
+++ b/plugin-packs/postcss-preset-env/test/layers-basic.preserve.true.expect.css
@@ -506,7 +506,7 @@ h1.test-custom-selectors:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):n
word-wrap: break-word;
}
-.test-focus-visible-pseudo-class.focus-visible:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) {
+.test-focus-visible-pseudo-class.focus-visible.js-focus-visible:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#), .js-focus-visible:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) .test-focus-visible-pseudo-class.focus-visible {
-webkit-box-ordinal-group: 27;
-webkit-order: 26;
-moz-box-ordinal-group: 27;
diff --git a/plugins/css-blank-pseudo/src/index.ts b/plugins/css-blank-pseudo/src/index.ts
index 62b01afda..4a870374a 100644
--- a/plugins/css-blank-pseudo/src/index.ts
+++ b/plugins/css-blank-pseudo/src/index.ts
@@ -2,7 +2,7 @@ import type { PluginCreator } from 'postcss';
import parser from 'postcss-selector-parser';
import isValidReplacement from './is-valid-replacement.mjs';
-type pluginOptions = { color?: string, preserve?: boolean };
+type pluginOptions = { preserve?: boolean, replaceWith?: string };
const creator: PluginCreator = (opts?: pluginOptions) => {
const options = Object.assign(
diff --git a/plugins/postcss-focus-visible/.gitignore b/plugins/postcss-focus-visible/.gitignore
index 17847a362..7172b04f1 100644
--- a/plugins/postcss-focus-visible/.gitignore
+++ b/plugins/postcss-focus-visible/.gitignore
@@ -1,12 +1,6 @@
node_modules
-dist
package-lock.json
yarn.lock
-*.log*
*.result.css
*.result.css.map
-!.editorconfig
-!.gitignore
-!.rollup.js
-!.tape.js
-!.travis.yml
+dist/*
diff --git a/plugins/postcss-focus-visible/.tape.mjs b/plugins/postcss-focus-visible/.tape.mjs
index 4b1596d6d..fcacb0d33 100644
--- a/plugins/postcss-focus-visible/.tape.mjs
+++ b/plugins/postcss-focus-visible/.tape.mjs
@@ -8,7 +8,7 @@ postcssTape(plugin)({
'basic:replacewith': {
message: 'supports { replaceWith: "[focus-visible]" } usage',
options: {
- replaceWith: '[focus-visible]'
+ replaceWith: '[data-focus-visible-added]'
}
},
'basic:preserve': {
@@ -24,4 +24,22 @@ postcssTape(plugin)({
preserve: false
}
},
+ 'browser': {
+ message: 'css for browser tests',
+ },
+ 'examples/example': {
+ message: 'minimal example',
+ },
+ 'examples/example:preserve-false': {
+ message: 'minimal example',
+ options: {
+ preserve: false
+ }
+ },
+ 'examples/example:replacewith': {
+ message: 'minimal example',
+ options: {
+ replaceWith: '[focus-visible]'
+ }
+ },
});
diff --git a/plugins/postcss-focus-visible/CHANGELOG.md b/plugins/postcss-focus-visible/CHANGELOG.md
index 534c3c904..5b54bba01 100644
--- a/plugins/postcss-focus-visible/CHANGELOG.md
+++ b/plugins/postcss-focus-visible/CHANGELOG.md
@@ -1,5 +1,10 @@
# Changes to PostCSS Focus Visible
+### Unreleased (major)
+
+- Breaking: Changed generated classes so it prepends `.js-focus-visible` to the
+generated class so CSS is applied when the polyfill is known to be running.
+
### 6.0.4 (February 5, 2022)
- Improved `es module` and `commonjs` compatibility
diff --git a/plugins/postcss-focus-visible/README.md b/plugins/postcss-focus-visible/README.md
index 22022bcf9..6f1f2c3e5 100644
--- a/plugins/postcss-focus-visible/README.md
+++ b/plugins/postcss-focus-visible/README.md
@@ -1,63 +1,50 @@
# PostCSS Focus Visible [
][postcss]
-[
][npm-url]
-[
][css-url]
-[
][cli-url]
-[
][discord]
+[
][npm-url] [
][css-url] [
][cli-url] [
][discord]
-[PostCSS Focus Visible] lets you use the `:focus-visible` pseudo-class in
-CSS, following the [Selectors Level 4 specification].
+[PostCSS Focus Visible] lets you use the `:focus-visible` pseudo-class in CSS,
+following the [Selectors Level 4 specification].
-It is the companion to the [focus-visible polyfill].
+It is the companion to the [focus-visible polyfill]. Note that this plugin
+alone **is not** sufficient to polyfill for `:focus-visible` and that you need
+the browser's polyfill as well.
[](https://caniuse.com/#feat=css-focus-visible)
```css
+
+```pcss
:focus:not(:focus-visible) {
- outline: none;
+ outline: none;
}
/* becomes */
-:focus:not(.focus-visible) {
- outline: none;
-}
-
-:focus:not(:focus-visible) {
- outline: none;
+:focus:not(.focus-visible).js-focus-visible, .js-focus-visible :focus:not(.focus-visible) {
+ outline: none;
}
```
[PostCSS Focus Visible] duplicates rules using the `:focus-visible` pseudo-class
with a `.focus-visible` class selector, the same selector used by the
-[focus-visible polyfill]. This replacement selector can be changed using the
-`replaceWith` option. Also, the preservation of the original `:focus-visible`
-rule can be disabled using the `preserve` option.
+[focus-visible polyfill].
## Usage
Add [PostCSS Focus Visible] to your project:
```bash
-npm install postcss-focus-visible --save-dev
-```
-
-Use [PostCSS Focus Visible] to process your CSS:
-
-```js
-const postcssFocusVisible = require('postcss-focus-visible');
-
-postcssFocusVisible.process(YOUR_CSS /*, processOptions, pluginOptions */);
+npm install postcss postcss-focus-visible --save-dev
```
-Or use it as a [PostCSS] plugin:
+Use it as a [PostCSS] plugin:
```js
const postcss = require('postcss');
const postcssFocusVisible = require('postcss-focus-visible');
postcss([
- postcssFocusVisible(/* pluginOptions */)
+ postcssFocusVisible(/* pluginOptions */)
]).process(YOUR_CSS /*, processOptions */);
```
@@ -71,22 +58,27 @@ instructions for:
### preserve
-The `preserve` option defines whether the original selector should remain. By
-default, the original selector is preserved.
+The `preserve` option determines whether the original notation
+is preserved. By default, it is not preserved.
```js
-focusVisible({ preserve: false });
+postcssFocusVisible({ preserve: true })
```
-```css
+```pcss
:focus:not(:focus-visible) {
- outline: none;
+ outline: none;
}
/* becomes */
-:focus:not(.focus-visible) {
- outline: none;
+.foo {
+ color: blue;
+ color: red;
+}
+
+.baz {
+ color: green;
}
```
@@ -96,34 +88,39 @@ The `replaceWith` option defines the selector to replace `:focus-visible`. By
default, the replacement selector is `.focus-visible`.
```js
-focusVisible({ replaceWith: '[focus-visible]' });
+postcssFocusVisible({ replaceWith: '[data-focus-visible-added]' })
```
-```css
+```pcss
:focus:not(:focus-visible) {
- outline: none;
+ outline: none;
}
/* becomes */
-:focus:not([focus-visible]) {
- outline: none;
+.foo {
+ color: blue;
+ color: red;
}
-:focus:not(:focus-visible) {
- outline: none;
+.baz {
+ color: green;
}
```
+Note that if you want to keep using [focus-visible polyfill], the only
+acceptable value would be `[data-focus-visible-added]`,
+given that the polyfill does not support arbitrary values.
+
[cli-url]: https://github.com/csstools/postcss-plugins/actions/workflows/test.yml?query=workflow/test
[css-url]: https://cssdb.org/#focus-visible-pseudo-class
[discord]: https://discord.gg/bUadyRwkJS
[npm-url]: https://www.npmjs.com/package/postcss-focus-visible
-[focus-visible polyfill]: https://github.com/WICG/focus-visible
[Gulp PostCSS]: https://github.com/postcss/gulp-postcss
[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss
[PostCSS]: https://github.com/postcss/postcss
-[PostCSS Focus Visible]: https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-focus-visible
[PostCSS Loader]: https://github.com/postcss/postcss-loader
+[PostCSS Focus Visible]: https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-focus-visible
[Selectors Level 4 specification]: https://www.w3.org/TR/selectors-4/#the-focus-visible-pseudo
+[focus-visible polyfill]: https://github.com/WICG/focus-visible
diff --git a/plugins/postcss-focus-visible/docs/README.md b/plugins/postcss-focus-visible/docs/README.md
new file mode 100644
index 000000000..def195d90
--- /dev/null
+++ b/plugins/postcss-focus-visible/docs/README.md
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+[] lets you use the `:focus-visible` pseudo-class in CSS,
+following the [Selectors Level 4 specification].
+
+It is the companion to the [focus-visible polyfill]. Note that this plugin
+alone **is not** sufficient to polyfill for `:focus-visible` and that you need
+the browser's polyfill as well.
+
+[](https://caniuse.com/#feat=css-focus-visible)
+
+```css
+
+```pcss
+
+
+/* becomes */
+
+
+```
+
+[PostCSS Focus Visible] duplicates rules using the `:focus-visible` pseudo-class
+with a `.focus-visible` class selector, the same selector used by the
+[focus-visible polyfill].
+
+
+
+
+
+## Options
+
+### preserve
+
+The `preserve` option determines whether the original notation
+is preserved. By default, it is not preserved.
+
+```js
+({ preserve: true })
+```
+
+```pcss
+
+
+/* becomes */
+
+
+```
+
+### replaceWith
+
+The `replaceWith` option defines the selector to replace `:focus-visible`. By
+default, the replacement selector is `.focus-visible`.
+
+```js
+({ replaceWith: '[data-focus-visible-added]' })
+```
+
+```pcss
+
+
+/* becomes */
+
+
+```
+
+Note that if you want to keep using [focus-visible polyfill], the only
+acceptable value would be `[data-focus-visible-added]`,
+given that the polyfill does not support arbitrary values.
+
+
+[Selectors Level 4 specification]:
+[focus-visible polyfill]: https://github.com/WICG/focus-visible
diff --git a/plugins/postcss-focus-visible/package.json b/plugins/postcss-focus-visible/package.json
index 8c12e8a2a..43325819d 100644
--- a/plugins/postcss-focus-visible/package.json
+++ b/plugins/postcss-focus-visible/package.json
@@ -2,7 +2,17 @@
"name": "postcss-focus-visible",
"description": "Use the :focus-visible pseudo-selector in CSS",
"version": "6.0.4",
- "author": "Jonathan Neal ",
+ "contributors": [
+ {
+ "name": "Antonio Laguna",
+ "email": "antonio@laguna.es",
+ "url": "https://antonio.laguna.es"
+ },
+ {
+ "name": "Romain Menke",
+ "email": "romainmenke@gmail.com"
+ }
+ ],
"license": "CC0-1.0",
"funding": {
"type": "opencollective",
@@ -33,15 +43,19 @@
"peerDependencies": {
"postcss": "^8.2"
},
+ "devDependencies": {
+ "puppeteer": "^15.1.1"
+ },
"scripts": {
"build": "rollup -c ../../rollup/default.js",
"clean": "node -e \"fs.rmSync('./dist', { recursive: true, force: true });\"",
- "docs": "node ../../.github/bin/generate-docs/install.mjs",
+ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs",
"lint": "npm run lint:eslint && npm run lint:package-json",
"lint:eslint": "eslint ./src --ext .js --ext .ts --ext .mjs --no-error-on-unmatched-pattern",
"lint:package-json": "node ../../.github/bin/format-package-json.mjs",
"prepublishOnly": "npm run clean && npm run build && npm run test",
"test": "node .tape.mjs && npm run test:exports",
+ "test:browser": "node ./test/_browser.mjs",
"test:exports": "node ./test/_import.mjs && node ./test/_require.cjs",
"test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs"
},
@@ -80,8 +94,10 @@
"trackpad"
],
"csstools": {
+ "cssdbId": "focus-visible-pseudo-class",
"exportName": "postcssFocusVisible",
- "humanReadableName": "PostCSS Focus Visible"
+ "humanReadableName": "PostCSS Focus Visible",
+ "specUrl": "https://www.w3.org/TR/selectors-4/#the-focus-visible-pseudo"
},
"volta": {
"extends": "../../package.json"
diff --git a/plugins/postcss-focus-visible/src/index.ts b/plugins/postcss-focus-visible/src/index.ts
index 492ccfd4f..6b7151141 100644
--- a/plugins/postcss-focus-visible/src/index.ts
+++ b/plugins/postcss-focus-visible/src/index.ts
@@ -1,57 +1,109 @@
-
import parser from 'postcss-selector-parser';
import type { PluginCreator } from 'postcss';
-const creator: PluginCreator<{ preserve?: boolean, replaceWith?: string }> = (opts?: { preserve?: boolean, replaceWith?: string }) => {
- opts = Object(opts);
- const preserve = Boolean('preserve' in opts ? opts.preserve : true);
- const replaceWith = String(opts.replaceWith || '.focus-visible');
- const replacementAST = parser().astSync(replaceWith);
+type pluginOptions = { preserve?: boolean, replaceWith?: string };
+
+const POLYFILL_READY_CLASSNAME = 'js-focus-visible';
+const PSEUDO = ':focus-visible';
+
+const creator: PluginCreator = (opts?: pluginOptions) => {
+ const options = Object.assign(
+ // Default options
+ {
+ preserve: false,
+ replaceWith: '.focus-visible',
+ },
+ // Provided options
+ opts,
+ );
+
+ const replacementAST = parser().astSync(options.replaceWith);
return {
postcssPlugin: 'postcss-focus-visible',
Rule(rule, { result }) {
- if (!rule.selector.includes(':focus-visible')) {
+ if (!rule.selector.includes(PSEUDO)) {
return;
}
- let modifiedSelector;
+ const selectors = rule.selectors.flatMap((selector) => {
+ if (!selector.includes(PSEUDO)) {
+ return [selector];
+ }
- try {
- const modifiedSelectorAST = parser((selectors) => {
- selectors.walkPseudos((pseudo) => {
- if (pseudo.value !== ':focus-visible') {
- return;
- }
+ let selectorAST;
- if (pseudo.nodes && pseudo.nodes.length) {
- return;
- }
+ try {
+ selectorAST = parser().astSync(selector);
+ } catch (_) {
+ rule.warn(result, `Failed to parse selector : ${selector}`);
+ return selector;
+ }
- pseudo.replaceWith(replacementAST.clone({}));
- });
- }).processSync(rule.selector);
+ if (typeof selectorAST === 'undefined') {
+ return [selector];
+ }
- modifiedSelector = String(modifiedSelectorAST);
- } catch (_) {
- rule.warn(result, `Failed to parse selector : ${rule.selector}`);
- return;
- }
+ let containsPseudo = false;
+ selectorAST.walkPseudos((pseudo) => {
+ if (pseudo.value !== PSEUDO) {
+ return;
+ }
- if (typeof modifiedSelector === 'undefined') {
- return;
- }
+ if (pseudo.nodes && pseudo.nodes.length) {
+ return;
+ }
+
+ containsPseudo = true;
+ pseudo.replaceWith(replacementAST.clone({}));
+ });
+
+ if (!containsPseudo) {
+ return [selector];
+ }
+
+ const selectorASTClone = selectorAST.clone();
+
+ // html > .foo:focus-visible
+ // becomes:
+ // html.js-focus-visible > .foo:focus-visible,
+ // .js-focus-visible html > .foo:focus-visible
+ {
+ if (selectorAST.nodes?.[0]?.nodes?.length) {
+ for (let i = 0; i < selectorAST.nodes[0].nodes.length; i++) {
+ const node = selectorAST.nodes[0].nodes[i];
+ if (node.type === 'combinator' || parser.isPseudoElement(node)) {
+ // Insert the class before the first combinator or pseudo element.
+ selectorAST.nodes[0].insertBefore(node, parser.className({ value: POLYFILL_READY_CLASSNAME }));
+ break;
+ }
- if (modifiedSelector === rule.selector) {
+ if (i === selectorAST.nodes[0].nodes.length - 1) {
+ // Append the class to the end of the selector if not combinator or pseudo element was found.
+ selectorAST.nodes[0].append(parser.className({ value: POLYFILL_READY_CLASSNAME }));
+ break;
+ }
+ }
+ }
+
+ if (selectorAST.nodes?.[0]?.nodes) {
+ // Prepend a space combinator and the class to the beginning of the selector.
+ selectorASTClone.nodes[0].prepend(parser.combinator({ value: ' ' }));
+ selectorASTClone.nodes[0].prepend(parser.className({ value: POLYFILL_READY_CLASSNAME }));
+ }
+ }
+
+ return [selectorAST.toString(), selectorASTClone.toString()];
+ });
+
+ if (selectors.join(',') === rule.selectors.join(',')) {
return;
}
- const clone = rule.clone({ selector: modifiedSelector });
+ rule.cloneBefore({ selectors: selectors });
- if (preserve) {
- rule.before(clone);
- } else {
- rule.replaceWith(clone);
+ if (!options.preserve) {
+ rule.remove();
}
},
};
@@ -60,3 +112,4 @@ const creator: PluginCreator<{ preserve?: boolean, replaceWith?: string }> = (op
creator.postcss = true;
export default creator;
+
diff --git a/plugins/postcss-focus-visible/test/_browser.html b/plugins/postcss-focus-visible/test/_browser.html
new file mode 100644
index 000000000..66b359cc4
--- /dev/null
+++ b/plugins/postcss-focus-visible/test/_browser.html
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/plugins/postcss-focus-visible/test/_browser.mjs b/plugins/postcss-focus-visible/test/_browser.mjs
new file mode 100644
index 000000000..dd294a04d
--- /dev/null
+++ b/plugins/postcss-focus-visible/test/_browser.mjs
@@ -0,0 +1,97 @@
+/* global window */
+import puppeteer from 'puppeteer';
+import http from 'http';
+import { promises as fsp } from 'fs';
+
+(async () => {
+ const requestListener = async function (req, res) {
+
+ const parsedUrl = new URL(req.url, 'http://localhost:8080');
+ const pathname = parsedUrl.pathname;
+
+ switch (pathname) {
+ case '':
+ case '/':
+ res.setHeader('Content-type', 'text/html');
+ res.writeHead(200);
+ res.end(await fsp.readFile('test/_browser.html', 'utf8'));
+ break;
+ case '/test/browser.expect.css':
+ res.setHeader('Content-type', 'text/css');
+ res.writeHead(200);
+ res.end(await fsp.readFile('test/browser.expect.css', 'utf8'));
+ break;
+ default:
+ res.setHeader('Content-type', 'text/plain' );
+ res.writeHead(404);
+ res.end('Not found');
+ break;
+ }
+ };
+
+ // Use different servers for HTML/CSS/JS to trigger CORS
+ const server = http.createServer(requestListener);
+ server.listen(8080);
+
+ if (!process.env.DEBUG) {
+ const browser = await puppeteer.launch({
+ headless: true,
+ });
+
+ const page = await browser.newPage();
+ page.on('pageerror', (msg) => {
+ throw msg;
+ });
+
+ // Default
+ {
+ await page.goto('http://localhost:8080');
+
+ // None of the elements should have styles
+ await page.evaluate(async () => window.checkElement('default', 'a', false));
+ await page.evaluate(async () => window.checkElement('default', 'b', false));
+ await page.evaluate(async () => window.checkElement('default', 'c', false));
+
+ await page.keyboard.press('Tab');
+ await page.evaluate(async () => window.checkElement('default', 'a', true));
+ await page.evaluate(async () => window.checkElement('default', 'b', false));
+ await page.evaluate(async () => window.checkElement('default', 'c', false));
+
+ await page.keyboard.press('Tab');
+ await page.evaluate(async () => window.checkElement('default', 'a', false));
+ await page.evaluate(async () => window.checkElement('default', 'b', true));
+ await page.evaluate(async () => window.checkElement('default', 'c', false));
+
+ await page.keyboard.press('Tab');
+ await page.evaluate(async () => window.checkElement('default', 'a', false));
+ await page.evaluate(async () => window.checkElement('default', 'b', false));
+ await page.evaluate(async () => window.checkElement('default', 'c', true));
+ }
+
+ // Clicking
+ {
+ await page.goto('http://localhost:8080');
+
+ // None of the elements should have styles
+ await page.evaluate(async () => window.checkElement('click', 'a', false));
+ await page.evaluate(async () => window.checkElement('click', 'b', false));
+ await page.evaluate(async () => window.checkElement('click', 'c', false));
+
+ await page.click('#a');
+ await page.evaluate(async () => window.checkElement('click', 'a', true));
+
+ await page.click('#b');
+ await page.evaluate(async () => window.checkElement('click', 'b', true));
+
+ // Clicking on a non-input element should not trigger focus-visible if not with keyboard
+ await page.click('#c');
+ await page.evaluate(async () => window.checkElement('click', 'c', false));
+ }
+
+ await browser.close();
+
+ await server.close();
+ } else {
+ console.log('visit : http://localhost:8080');
+ }
+})();
diff --git a/plugins/postcss-focus-visible/test/basic.css b/plugins/postcss-focus-visible/test/basic.css
index 6b5c0b5f6..a2ac10d1a 100644
--- a/plugins/postcss-focus-visible/test/basic.css
+++ b/plugins/postcss-focus-visible/test/basic.css
@@ -6,6 +6,7 @@
:focus-visible test,
test :focus-visible,
test test:focus-visible,
+html[dir="rtl"] :focus-visible,
test :focus-visible test,
test test:focus-visible test,
test :focus-visible :focus-visible test,
@@ -36,3 +37,43 @@ test :matches(test :focus-visible :focus-visible test) test {
.escaped\:times\:two:focus-visible {
order: 5;
}
+
+html :focus-visible {
+ order: 6;
+}
+
+html:focus-visible {
+ order: 6.1;
+}
+
+:not(:focus-visible) {
+ order: 7;
+}
+
+html :not(:focus-visible) {
+ order: 8;
+}
+
+:focus-visible::before {
+ order: 10.0;
+}
+
+:focus-visible .foo {
+ order: 10.1;
+}
+
+:focus-visible > .foo {
+ order: 10.2;
+}
+
+::before:focus-visible {
+ order: 10.3;
+}
+
+.foo :focus-visible {
+ order: 10.4;
+}
+
+.foo > :focus-visible {
+ order: 10.5;
+}
diff --git a/plugins/postcss-focus-visible/test/basic.expect.css b/plugins/postcss-focus-visible/test/basic.expect.css
index 1635ac6ae..3fed12a64 100644
--- a/plugins/postcss-focus-visible/test/basic.expect.css
+++ b/plugins/postcss-focus-visible/test/basic.expect.css
@@ -1,41 +1,37 @@
-.focus-visible {
+.focus-visible.js-focus-visible, .js-focus-visible .focus-visible {
order: 1;
}
-:focus-visible {
- order: 1;
-}
-
-.focus-visible,.focus-visible test,
-test .focus-visible,
-test test.focus-visible,
-test .focus-visible test,
-test test.focus-visible test,
-test .focus-visible .focus-visible test,
-test :matches(.focus-visible) test,
-test :matches(.focus-visible test) test,
-test :matches(test .focus-visible) test,
-test :matches(test test.focus-visible) test,
-test :matches(test .focus-visible test) test,
-test :matches(test test.focus-visible test) test,
-test :matches(test .focus-visible .focus-visible test) test {
- order: 2;
-}
-
-:focus-visible,
-:focus-visible test,
-test :focus-visible,
-test test:focus-visible,
-test :focus-visible test,
-test test:focus-visible test,
-test :focus-visible :focus-visible test,
-test :matches(:focus-visible) test,
-test :matches(:focus-visible test) test,
-test :matches(test :focus-visible) test,
-test :matches(test test:focus-visible) test,
-test :matches(test :focus-visible test) test,
-test :matches(test test:focus-visible test) test,
-test :matches(test :focus-visible :focus-visible test) test {
+.focus-visible.js-focus-visible,
+.js-focus-visible .focus-visible,
+.focus-visible.js-focus-visible test,
+.js-focus-visible .focus-visible test,
+test.js-focus-visible .focus-visible,
+.js-focus-visible test .focus-visible,
+test.js-focus-visible test.focus-visible,
+.js-focus-visible test test.focus-visible,
+html[dir="rtl"].js-focus-visible .focus-visible,
+.js-focus-visible html[dir="rtl"] .focus-visible,
+test.js-focus-visible .focus-visible test,
+.js-focus-visible test .focus-visible test,
+test.js-focus-visible test.focus-visible test,
+.js-focus-visible test test.focus-visible test,
+test.js-focus-visible .focus-visible .focus-visible test,
+.js-focus-visible test .focus-visible .focus-visible test,
+test.js-focus-visible :matches(.focus-visible) test,
+.js-focus-visible test :matches(.focus-visible) test,
+test.js-focus-visible :matches(.focus-visible test) test,
+.js-focus-visible test :matches(.focus-visible test) test,
+test.js-focus-visible :matches(test .focus-visible) test,
+.js-focus-visible test :matches(test .focus-visible) test,
+test.js-focus-visible :matches(test test.focus-visible) test,
+.js-focus-visible test :matches(test test.focus-visible) test,
+test.js-focus-visible :matches(test .focus-visible test) test,
+.js-focus-visible test :matches(test .focus-visible test) test,
+test.js-focus-visible :matches(test test.focus-visible test) test,
+.js-focus-visible test :matches(test test.focus-visible test) test,
+test.js-focus-visible :matches(test .focus-visible .focus-visible test) test,
+.js-focus-visible test :matches(test .focus-visible .focus-visible test) test {
order: 2;
}
@@ -52,14 +48,49 @@ test :matches(test :focus-visible :focus-visible test) test {
.escaped\:focus-visible,
.escaped\:times\:two\:focus-visible,
-.escaped\:focus-visible.focus-visible,
-.escaped\:times\:two.focus-visible {
+.escaped\:focus-visible.focus-visible.js-focus-visible,
+.js-focus-visible .escaped\:focus-visible.focus-visible,
+.escaped\:times\:two.focus-visible.js-focus-visible,
+.js-focus-visible .escaped\:times\:two.focus-visible {
order: 5;
}
-.escaped\:focus-visible,
-.escaped\:times\:two\:focus-visible,
-.escaped\:focus-visible:focus-visible,
-.escaped\:times\:two:focus-visible {
- order: 5;
+html.js-focus-visible .focus-visible, .js-focus-visible html .focus-visible {
+ order: 6;
+}
+
+html.focus-visible.js-focus-visible, .js-focus-visible html.focus-visible {
+ order: 6.1;
+}
+
+:not(.focus-visible).js-focus-visible, .js-focus-visible :not(.focus-visible) {
+ order: 7;
+}
+
+html.js-focus-visible :not(.focus-visible), .js-focus-visible html :not(.focus-visible) {
+ order: 8;
+}
+
+.focus-visible.js-focus-visible::before, .js-focus-visible .focus-visible::before {
+ order: 10.0;
+}
+
+.focus-visible.js-focus-visible .foo, .js-focus-visible .focus-visible .foo {
+ order: 10.1;
+}
+
+.focus-visible.js-focus-visible > .foo, .js-focus-visible .focus-visible > .foo {
+ order: 10.2;
+}
+
+.js-focus-visible::before.focus-visible, .js-focus-visible ::before.focus-visible {
+ order: 10.3;
+}
+
+.foo.js-focus-visible .focus-visible, .js-focus-visible .foo .focus-visible {
+ order: 10.4;
+}
+
+.foo.js-focus-visible > .focus-visible, .js-focus-visible .foo > .focus-visible {
+ order: 10.5;
}
diff --git a/plugins/postcss-focus-visible/test/basic.preserve.expect.css b/plugins/postcss-focus-visible/test/basic.preserve.expect.css
index 56f3d0a59..3fed12a64 100644
--- a/plugins/postcss-focus-visible/test/basic.preserve.expect.css
+++ b/plugins/postcss-focus-visible/test/basic.preserve.expect.css
@@ -1,20 +1,37 @@
-.focus-visible {
+.focus-visible.js-focus-visible, .js-focus-visible .focus-visible {
order: 1;
}
-.focus-visible,.focus-visible test,
-test .focus-visible,
-test test.focus-visible,
-test .focus-visible test,
-test test.focus-visible test,
-test .focus-visible .focus-visible test,
-test :matches(.focus-visible) test,
-test :matches(.focus-visible test) test,
-test :matches(test .focus-visible) test,
-test :matches(test test.focus-visible) test,
-test :matches(test .focus-visible test) test,
-test :matches(test test.focus-visible test) test,
-test :matches(test .focus-visible .focus-visible test) test {
+.focus-visible.js-focus-visible,
+.js-focus-visible .focus-visible,
+.focus-visible.js-focus-visible test,
+.js-focus-visible .focus-visible test,
+test.js-focus-visible .focus-visible,
+.js-focus-visible test .focus-visible,
+test.js-focus-visible test.focus-visible,
+.js-focus-visible test test.focus-visible,
+html[dir="rtl"].js-focus-visible .focus-visible,
+.js-focus-visible html[dir="rtl"] .focus-visible,
+test.js-focus-visible .focus-visible test,
+.js-focus-visible test .focus-visible test,
+test.js-focus-visible test.focus-visible test,
+.js-focus-visible test test.focus-visible test,
+test.js-focus-visible .focus-visible .focus-visible test,
+.js-focus-visible test .focus-visible .focus-visible test,
+test.js-focus-visible :matches(.focus-visible) test,
+.js-focus-visible test :matches(.focus-visible) test,
+test.js-focus-visible :matches(.focus-visible test) test,
+.js-focus-visible test :matches(.focus-visible test) test,
+test.js-focus-visible :matches(test .focus-visible) test,
+.js-focus-visible test :matches(test .focus-visible) test,
+test.js-focus-visible :matches(test test.focus-visible) test,
+.js-focus-visible test :matches(test test.focus-visible) test,
+test.js-focus-visible :matches(test .focus-visible test) test,
+.js-focus-visible test :matches(test .focus-visible test) test,
+test.js-focus-visible :matches(test test.focus-visible test) test,
+.js-focus-visible test :matches(test test.focus-visible test) test,
+test.js-focus-visible :matches(test .focus-visible .focus-visible test) test,
+.js-focus-visible test :matches(test .focus-visible .focus-visible test) test {
order: 2;
}
@@ -31,7 +48,49 @@ test :matches(test .focus-visible .focus-visible test) test {
.escaped\:focus-visible,
.escaped\:times\:two\:focus-visible,
-.escaped\:focus-visible.focus-visible,
-.escaped\:times\:two.focus-visible {
+.escaped\:focus-visible.focus-visible.js-focus-visible,
+.js-focus-visible .escaped\:focus-visible.focus-visible,
+.escaped\:times\:two.focus-visible.js-focus-visible,
+.js-focus-visible .escaped\:times\:two.focus-visible {
order: 5;
}
+
+html.js-focus-visible .focus-visible, .js-focus-visible html .focus-visible {
+ order: 6;
+}
+
+html.focus-visible.js-focus-visible, .js-focus-visible html.focus-visible {
+ order: 6.1;
+}
+
+:not(.focus-visible).js-focus-visible, .js-focus-visible :not(.focus-visible) {
+ order: 7;
+}
+
+html.js-focus-visible :not(.focus-visible), .js-focus-visible html :not(.focus-visible) {
+ order: 8;
+}
+
+.focus-visible.js-focus-visible::before, .js-focus-visible .focus-visible::before {
+ order: 10.0;
+}
+
+.focus-visible.js-focus-visible .foo, .js-focus-visible .focus-visible .foo {
+ order: 10.1;
+}
+
+.focus-visible.js-focus-visible > .foo, .js-focus-visible .focus-visible > .foo {
+ order: 10.2;
+}
+
+.js-focus-visible::before.focus-visible, .js-focus-visible ::before.focus-visible {
+ order: 10.3;
+}
+
+.foo.js-focus-visible .focus-visible, .js-focus-visible .foo .focus-visible {
+ order: 10.4;
+}
+
+.foo.js-focus-visible > .focus-visible, .js-focus-visible .foo > .focus-visible {
+ order: 10.5;
+}
diff --git a/plugins/postcss-focus-visible/test/basic.replacewith.expect.css b/plugins/postcss-focus-visible/test/basic.replacewith.expect.css
index 1b9240bf7..a5162561f 100644
--- a/plugins/postcss-focus-visible/test/basic.replacewith.expect.css
+++ b/plugins/postcss-focus-visible/test/basic.replacewith.expect.css
@@ -1,41 +1,37 @@
-[focus-visible] {
+[data-focus-visible-added].js-focus-visible, .js-focus-visible [data-focus-visible-added] {
order: 1;
}
-:focus-visible {
- order: 1;
-}
-
-[focus-visible],[focus-visible] test,
-test [focus-visible],
-test test[focus-visible],
-test [focus-visible] test,
-test test[focus-visible] test,
-test [focus-visible] [focus-visible] test,
-test :matches([focus-visible]) test,
-test :matches([focus-visible] test) test,
-test :matches(test [focus-visible]) test,
-test :matches(test test[focus-visible]) test,
-test :matches(test [focus-visible] test) test,
-test :matches(test test[focus-visible] test) test,
-test :matches(test [focus-visible] [focus-visible] test) test {
- order: 2;
-}
-
-:focus-visible,
-:focus-visible test,
-test :focus-visible,
-test test:focus-visible,
-test :focus-visible test,
-test test:focus-visible test,
-test :focus-visible :focus-visible test,
-test :matches(:focus-visible) test,
-test :matches(:focus-visible test) test,
-test :matches(test :focus-visible) test,
-test :matches(test test:focus-visible) test,
-test :matches(test :focus-visible test) test,
-test :matches(test test:focus-visible test) test,
-test :matches(test :focus-visible :focus-visible test) test {
+[data-focus-visible-added].js-focus-visible,
+.js-focus-visible [data-focus-visible-added],
+[data-focus-visible-added].js-focus-visible test,
+.js-focus-visible [data-focus-visible-added] test,
+test.js-focus-visible [data-focus-visible-added],
+.js-focus-visible test [data-focus-visible-added],
+test.js-focus-visible test[data-focus-visible-added],
+.js-focus-visible test test[data-focus-visible-added],
+html[dir="rtl"].js-focus-visible [data-focus-visible-added],
+.js-focus-visible html[dir="rtl"] [data-focus-visible-added],
+test.js-focus-visible [data-focus-visible-added] test,
+.js-focus-visible test [data-focus-visible-added] test,
+test.js-focus-visible test[data-focus-visible-added] test,
+.js-focus-visible test test[data-focus-visible-added] test,
+test.js-focus-visible [data-focus-visible-added] [data-focus-visible-added] test,
+.js-focus-visible test [data-focus-visible-added] [data-focus-visible-added] test,
+test.js-focus-visible :matches([data-focus-visible-added]) test,
+.js-focus-visible test :matches([data-focus-visible-added]) test,
+test.js-focus-visible :matches([data-focus-visible-added] test) test,
+.js-focus-visible test :matches([data-focus-visible-added] test) test,
+test.js-focus-visible :matches(test [data-focus-visible-added]) test,
+.js-focus-visible test :matches(test [data-focus-visible-added]) test,
+test.js-focus-visible :matches(test test[data-focus-visible-added]) test,
+.js-focus-visible test :matches(test test[data-focus-visible-added]) test,
+test.js-focus-visible :matches(test [data-focus-visible-added] test) test,
+.js-focus-visible test :matches(test [data-focus-visible-added] test) test,
+test.js-focus-visible :matches(test test[data-focus-visible-added] test) test,
+.js-focus-visible test :matches(test test[data-focus-visible-added] test) test,
+test.js-focus-visible :matches(test [data-focus-visible-added] [data-focus-visible-added] test) test,
+.js-focus-visible test :matches(test [data-focus-visible-added] [data-focus-visible-added] test) test {
order: 2;
}
@@ -52,14 +48,49 @@ test :matches(test :focus-visible :focus-visible test) test {
.escaped\:focus-visible,
.escaped\:times\:two\:focus-visible,
-.escaped\:focus-visible[focus-visible],
-.escaped\:times\:two[focus-visible] {
+.escaped\:focus-visible[data-focus-visible-added].js-focus-visible,
+.js-focus-visible .escaped\:focus-visible[data-focus-visible-added],
+.escaped\:times\:two[data-focus-visible-added].js-focus-visible,
+.js-focus-visible .escaped\:times\:two[data-focus-visible-added] {
order: 5;
}
-.escaped\:focus-visible,
-.escaped\:times\:two\:focus-visible,
-.escaped\:focus-visible:focus-visible,
-.escaped\:times\:two:focus-visible {
- order: 5;
+html.js-focus-visible [data-focus-visible-added], .js-focus-visible html [data-focus-visible-added] {
+ order: 6;
+}
+
+html[data-focus-visible-added].js-focus-visible, .js-focus-visible html[data-focus-visible-added] {
+ order: 6.1;
+}
+
+:not([data-focus-visible-added]).js-focus-visible, .js-focus-visible :not([data-focus-visible-added]) {
+ order: 7;
+}
+
+html.js-focus-visible :not([data-focus-visible-added]), .js-focus-visible html :not([data-focus-visible-added]) {
+ order: 8;
+}
+
+[data-focus-visible-added].js-focus-visible::before, .js-focus-visible [data-focus-visible-added]::before {
+ order: 10.0;
+}
+
+[data-focus-visible-added].js-focus-visible .foo, .js-focus-visible [data-focus-visible-added] .foo {
+ order: 10.1;
+}
+
+[data-focus-visible-added].js-focus-visible > .foo, .js-focus-visible [data-focus-visible-added] > .foo {
+ order: 10.2;
+}
+
+.js-focus-visible::before[data-focus-visible-added], .js-focus-visible ::before[data-focus-visible-added] {
+ order: 10.3;
+}
+
+.foo.js-focus-visible [data-focus-visible-added], .js-focus-visible .foo [data-focus-visible-added] {
+ order: 10.4;
+}
+
+.foo.js-focus-visible > [data-focus-visible-added], .js-focus-visible .foo > [data-focus-visible-added] {
+ order: 10.5;
}
diff --git a/plugins/postcss-focus-visible/test/browser.css b/plugins/postcss-focus-visible/test/browser.css
new file mode 100644
index 000000000..12122d422
--- /dev/null
+++ b/plugins/postcss-focus-visible/test/browser.css
@@ -0,0 +1,9 @@
+input,
+select,
+textarea {
+ background-color: rgb(255, 192, 203);
+}
+
+:focus-visible {
+ background-color: rgb(128, 0, 128);
+}
diff --git a/plugins/postcss-focus-visible/test/browser.expect.css b/plugins/postcss-focus-visible/test/browser.expect.css
new file mode 100644
index 000000000..cf0e52c08
--- /dev/null
+++ b/plugins/postcss-focus-visible/test/browser.expect.css
@@ -0,0 +1,9 @@
+input,
+select,
+textarea {
+ background-color: rgb(255, 192, 203);
+}
+
+.focus-visible.js-focus-visible, .js-focus-visible .focus-visible {
+ background-color: rgb(128, 0, 128);
+}
diff --git a/plugins/postcss-focus-visible/test/examples/example.css b/plugins/postcss-focus-visible/test/examples/example.css
new file mode 100644
index 000000000..b83264afe
--- /dev/null
+++ b/plugins/postcss-focus-visible/test/examples/example.css
@@ -0,0 +1,3 @@
+:focus:not(:focus-visible) {
+ outline: none;
+}
diff --git a/plugins/postcss-focus-visible/test/examples/example.expect.css b/plugins/postcss-focus-visible/test/examples/example.expect.css
new file mode 100644
index 000000000..d2288c25d
--- /dev/null
+++ b/plugins/postcss-focus-visible/test/examples/example.expect.css
@@ -0,0 +1,3 @@
+:focus:not(.focus-visible).js-focus-visible, .js-focus-visible :focus:not(.focus-visible) {
+ outline: none;
+}
diff --git a/plugins/postcss-focus-visible/test/examples/example.preserve-false.expect.css b/plugins/postcss-focus-visible/test/examples/example.preserve-false.expect.css
new file mode 100644
index 000000000..d2288c25d
--- /dev/null
+++ b/plugins/postcss-focus-visible/test/examples/example.preserve-false.expect.css
@@ -0,0 +1,3 @@
+:focus:not(.focus-visible).js-focus-visible, .js-focus-visible :focus:not(.focus-visible) {
+ outline: none;
+}
diff --git a/plugins/postcss-focus-visible/test/examples/example.preserve-true.expect.css b/plugins/postcss-focus-visible/test/examples/example.preserve-true.expect.css
new file mode 100644
index 000000000..8b020470a
--- /dev/null
+++ b/plugins/postcss-focus-visible/test/examples/example.preserve-true.expect.css
@@ -0,0 +1,8 @@
+.foo {
+ color: blue;
+ color: red;
+}
+
+.baz {
+ color: green;
+}
diff --git a/plugins/postcss-focus-visible/test/examples/example.replacewith.expect.css b/plugins/postcss-focus-visible/test/examples/example.replacewith.expect.css
new file mode 100644
index 000000000..9e6327e76
--- /dev/null
+++ b/plugins/postcss-focus-visible/test/examples/example.replacewith.expect.css
@@ -0,0 +1,3 @@
+:focus:not([focus-visible]).js-focus-visible, .js-focus-visible :focus:not([focus-visible]) {
+ outline: none;
+}
diff --git a/plugins/postcss-focus-visible/test/generated-selector-cases.expect.css b/plugins/postcss-focus-visible/test/generated-selector-cases.expect.css
index d8ed51a13..d122f1b4c 100644
--- a/plugins/postcss-focus-visible/test/generated-selector-cases.expect.css
+++ b/plugins/postcss-focus-visible/test/generated-selector-cases.expect.css
@@ -1,84 +1,84 @@
-.focus-visible.focus-visible {
+.focus-visible.focus-visible.js-focus-visible, .js-focus-visible .focus-visible.focus-visible {
order: 0;
}
-.focus-visible.focus-visible {
+.focus-visible.focus-visible.js-focus-visible, .js-focus-visible .focus-visible.focus-visible {
order: 1;
}
-.focus-visible .focus-visible {
+.focus-visible.js-focus-visible .focus-visible, .js-focus-visible .focus-visible .focus-visible {
order: 2;
}
-.focus-visible .focus-visible {
+.focus-visible.js-focus-visible .focus-visible, .js-focus-visible .focus-visible .focus-visible {
order: 3;
}
-.focus-visible .focus-visible {
+.focus-visible.js-focus-visible .focus-visible, .js-focus-visible .focus-visible .focus-visible {
order: 4;
}
-.focus-visible .focus-visible {
+.focus-visible.js-focus-visible .focus-visible, .js-focus-visible .focus-visible .focus-visible {
order: 5;
}
-.focus-visible+.focus-visible {
+.focus-visible.js-focus-visible+.focus-visible, .js-focus-visible .focus-visible+.focus-visible {
order: 6;
}
-.focus-visible+.focus-visible {
+.focus-visible.js-focus-visible+.focus-visible, .js-focus-visible .focus-visible+.focus-visible {
order: 7;
}
-.focus-visible + .focus-visible {
+.focus-visible.js-focus-visible + .focus-visible, .js-focus-visible .focus-visible + .focus-visible {
order: 8;
}
-.focus-visible + .focus-visible {
+.focus-visible.js-focus-visible + .focus-visible, .js-focus-visible .focus-visible + .focus-visible {
order: 9;
}
-.focus-visible~.focus-visible {
+.focus-visible.js-focus-visible~.focus-visible, .js-focus-visible .focus-visible~.focus-visible {
order: 10;
}
-.focus-visible~.focus-visible {
+.focus-visible.js-focus-visible~.focus-visible, .js-focus-visible .focus-visible~.focus-visible {
order: 11;
}
-.focus-visible ~ .focus-visible {
+.focus-visible.js-focus-visible ~ .focus-visible, .js-focus-visible .focus-visible ~ .focus-visible {
order: 12;
}
-.focus-visible ~ .focus-visible {
+.focus-visible.js-focus-visible ~ .focus-visible, .js-focus-visible .focus-visible ~ .focus-visible {
order: 13;
}
-.focus-visible>.focus-visible {
+.focus-visible.js-focus-visible>.focus-visible, .js-focus-visible .focus-visible>.focus-visible {
order: 14;
}
-.focus-visible>.focus-visible {
+.focus-visible.js-focus-visible>.focus-visible, .js-focus-visible .focus-visible>.focus-visible {
order: 15;
}
-.focus-visible > .focus-visible {
+.focus-visible.js-focus-visible > .focus-visible, .js-focus-visible .focus-visible > .focus-visible {
order: 16;
}
-.focus-visible > .focus-visible {
+.focus-visible.js-focus-visible > .focus-visible, .js-focus-visible .focus-visible > .focus-visible {
order: 17;
}
-.focus-visible,.focus-visible {
+.focus-visible.js-focus-visible, .js-focus-visible .focus-visible, .focus-visible.js-focus-visible, .js-focus-visible .focus-visible {
order: 18;
}
-.focus-visible,.focus-visible {
+.focus-visible.js-focus-visible, .js-focus-visible .focus-visible, .focus-visible.js-focus-visible, .js-focus-visible .focus-visible {
order: 19;
}
-button.focus-visible {
+button.focus-visible.js-focus-visible, .js-focus-visible button.focus-visible {
order: 20;
}
@@ -86,319 +86,319 @@ button.focus-visible {
order: 21;
}
-button .focus-visible {
+button.js-focus-visible .focus-visible, .js-focus-visible button .focus-visible {
order: 22;
}
-.focus-visible button {
+.focus-visible.js-focus-visible button, .js-focus-visible .focus-visible button {
order: 23;
}
-button .focus-visible {
+button.js-focus-visible .focus-visible, .js-focus-visible button .focus-visible {
order: 24;
}
-.focus-visible button {
+.focus-visible.js-focus-visible button, .js-focus-visible .focus-visible button {
order: 25;
}
-button+.focus-visible {
+button.js-focus-visible+.focus-visible, .js-focus-visible button+.focus-visible {
order: 26;
}
-.focus-visible+button {
+.focus-visible.js-focus-visible+button, .js-focus-visible .focus-visible+button {
order: 27;
}
-button + .focus-visible {
+button.js-focus-visible + .focus-visible, .js-focus-visible button + .focus-visible {
order: 28;
}
-.focus-visible + button {
+.focus-visible.js-focus-visible + button, .js-focus-visible .focus-visible + button {
order: 29;
}
-button~.focus-visible {
+button.js-focus-visible~.focus-visible, .js-focus-visible button~.focus-visible {
order: 30;
}
-.focus-visible~button {
+.focus-visible.js-focus-visible~button, .js-focus-visible .focus-visible~button {
order: 31;
}
-button ~ .focus-visible {
+button.js-focus-visible ~ .focus-visible, .js-focus-visible button ~ .focus-visible {
order: 32;
}
-.focus-visible ~ button {
+.focus-visible.js-focus-visible ~ button, .js-focus-visible .focus-visible ~ button {
order: 33;
}
-button>.focus-visible {
+button.js-focus-visible>.focus-visible, .js-focus-visible button>.focus-visible {
order: 34;
}
-.focus-visible>button {
+.focus-visible.js-focus-visible>button, .js-focus-visible .focus-visible>button {
order: 35;
}
-button > .focus-visible {
+button.js-focus-visible > .focus-visible, .js-focus-visible button > .focus-visible {
order: 36;
}
-.focus-visible > button {
+.focus-visible.js-focus-visible > button, .js-focus-visible .focus-visible > button {
order: 37;
}
-button,.focus-visible {
+button, .focus-visible.js-focus-visible, .js-focus-visible .focus-visible {
order: 38;
}
-.focus-visible, button {
+.focus-visible.js-focus-visible, .js-focus-visible .focus-visible, button {
order: 39;
}
-.🧑🏾🎤.focus-visible {
+.🧑🏾🎤.focus-visible.js-focus-visible, .js-focus-visible .🧑🏾🎤.focus-visible {
order: 40;
}
-.focus-visible.🧑🏾🎤 {
+.focus-visible.🧑🏾🎤.js-focus-visible, .js-focus-visible .focus-visible.🧑🏾🎤 {
order: 41;
}
-.🧑🏾🎤 .focus-visible {
+.🧑🏾🎤.js-focus-visible .focus-visible, .js-focus-visible .🧑🏾🎤 .focus-visible {
order: 42;
}
-.focus-visible .🧑🏾🎤 {
+.focus-visible.js-focus-visible .🧑🏾🎤, .js-focus-visible .focus-visible .🧑🏾🎤 {
order: 43;
}
-.🧑🏾🎤 .focus-visible {
+.🧑🏾🎤.js-focus-visible .focus-visible, .js-focus-visible .🧑🏾🎤 .focus-visible {
order: 44;
}
-.focus-visible .🧑🏾🎤 {
+.focus-visible.js-focus-visible .🧑🏾🎤, .js-focus-visible .focus-visible .🧑🏾🎤 {
order: 45;
}
-.🧑🏾🎤+.focus-visible {
+.🧑🏾🎤.js-focus-visible+.focus-visible, .js-focus-visible .🧑🏾🎤+.focus-visible {
order: 46;
}
-.focus-visible+.🧑🏾🎤 {
+.focus-visible.js-focus-visible+.🧑🏾🎤, .js-focus-visible .focus-visible+.🧑🏾🎤 {
order: 47;
}
-.🧑🏾🎤 + .focus-visible {
+.🧑🏾🎤.js-focus-visible + .focus-visible, .js-focus-visible .🧑🏾🎤 + .focus-visible {
order: 48;
}
-.focus-visible + .🧑🏾🎤 {
+.focus-visible.js-focus-visible + .🧑🏾🎤, .js-focus-visible .focus-visible + .🧑🏾🎤 {
order: 49;
}
-.🧑🏾🎤~.focus-visible {
+.🧑🏾🎤.js-focus-visible~.focus-visible, .js-focus-visible .🧑🏾🎤~.focus-visible {
order: 50;
}
-.focus-visible~.🧑🏾🎤 {
+.focus-visible.js-focus-visible~.🧑🏾🎤, .js-focus-visible .focus-visible~.🧑🏾🎤 {
order: 51;
}
-.🧑🏾🎤 ~ .focus-visible {
+.🧑🏾🎤.js-focus-visible ~ .focus-visible, .js-focus-visible .🧑🏾🎤 ~ .focus-visible {
order: 52;
}
-.focus-visible ~ .🧑🏾🎤 {
+.focus-visible.js-focus-visible ~ .🧑🏾🎤, .js-focus-visible .focus-visible ~ .🧑🏾🎤 {
order: 53;
}
-.🧑🏾🎤>.focus-visible {
+.🧑🏾🎤.js-focus-visible>.focus-visible, .js-focus-visible .🧑🏾🎤>.focus-visible {
order: 54;
}
-.focus-visible>.🧑🏾🎤 {
+.focus-visible.js-focus-visible>.🧑🏾🎤, .js-focus-visible .focus-visible>.🧑🏾🎤 {
order: 55;
}
-.🧑🏾🎤 > .focus-visible {
+.🧑🏾🎤.js-focus-visible > .focus-visible, .js-focus-visible .🧑🏾🎤 > .focus-visible {
order: 56;
}
-.focus-visible > .🧑🏾🎤 {
+.focus-visible.js-focus-visible > .🧑🏾🎤, .js-focus-visible .focus-visible > .🧑🏾🎤 {
order: 57;
}
-.🧑🏾🎤,.focus-visible {
+.🧑🏾🎤, .focus-visible.js-focus-visible, .js-focus-visible .focus-visible {
order: 58;
}
-.focus-visible, .🧑🏾🎤 {
+.focus-visible.js-focus-visible, .js-focus-visible .focus-visible, .🧑🏾🎤 {
order: 59;
}
-.foo.focus-visible {
+.foo.focus-visible.js-focus-visible, .js-focus-visible .foo.focus-visible {
order: 60;
}
-.focus-visible.foo {
+.focus-visible.foo.js-focus-visible, .js-focus-visible .focus-visible.foo {
order: 61;
}
-.foo .focus-visible {
+.foo.js-focus-visible .focus-visible, .js-focus-visible .foo .focus-visible {
order: 62;
}
-.focus-visible .foo {
+.focus-visible.js-focus-visible .foo, .js-focus-visible .focus-visible .foo {
order: 63;
}
-.foo .focus-visible {
+.foo.js-focus-visible .focus-visible, .js-focus-visible .foo .focus-visible {
order: 64;
}
-.focus-visible .foo {
+.focus-visible.js-focus-visible .foo, .js-focus-visible .focus-visible .foo {
order: 65;
}
-.foo+.focus-visible {
+.foo.js-focus-visible+.focus-visible, .js-focus-visible .foo+.focus-visible {
order: 66;
}
-.focus-visible+.foo {
+.focus-visible.js-focus-visible+.foo, .js-focus-visible .focus-visible+.foo {
order: 67;
}
-.foo + .focus-visible {
+.foo.js-focus-visible + .focus-visible, .js-focus-visible .foo + .focus-visible {
order: 68;
}
-.focus-visible + .foo {
+.focus-visible.js-focus-visible + .foo, .js-focus-visible .focus-visible + .foo {
order: 69;
}
-.foo~.focus-visible {
+.foo.js-focus-visible~.focus-visible, .js-focus-visible .foo~.focus-visible {
order: 70;
}
-.focus-visible~.foo {
+.focus-visible.js-focus-visible~.foo, .js-focus-visible .focus-visible~.foo {
order: 71;
}
-.foo ~ .focus-visible {
+.foo.js-focus-visible ~ .focus-visible, .js-focus-visible .foo ~ .focus-visible {
order: 72;
}
-.focus-visible ~ .foo {
+.focus-visible.js-focus-visible ~ .foo, .js-focus-visible .focus-visible ~ .foo {
order: 73;
}
-.foo>.focus-visible {
+.foo.js-focus-visible>.focus-visible, .js-focus-visible .foo>.focus-visible {
order: 74;
}
-.focus-visible>.foo {
+.focus-visible.js-focus-visible>.foo, .js-focus-visible .focus-visible>.foo {
order: 75;
}
-.foo > .focus-visible {
+.foo.js-focus-visible > .focus-visible, .js-focus-visible .foo > .focus-visible {
order: 76;
}
-.focus-visible > .foo {
+.focus-visible.js-focus-visible > .foo, .js-focus-visible .focus-visible > .foo {
order: 77;
}
-.foo,.focus-visible {
+.foo, .focus-visible.js-focus-visible, .js-focus-visible .focus-visible {
order: 78;
}
-.focus-visible, .foo {
+.focus-visible.js-focus-visible, .js-focus-visible .focus-visible, .foo {
order: 79;
}
-#foo.focus-visible {
+#foo.focus-visible.js-focus-visible, .js-focus-visible #foo.focus-visible {
order: 80;
}
-.focus-visible#foo {
+.focus-visible#foo.js-focus-visible, .js-focus-visible .focus-visible#foo {
order: 81;
}
-#foo .focus-visible {
+#foo.js-focus-visible .focus-visible, .js-focus-visible #foo .focus-visible {
order: 82;
}
-.focus-visible #foo {
+.focus-visible.js-focus-visible #foo, .js-focus-visible .focus-visible #foo {
order: 83;
}
-#foo .focus-visible {
+#foo.js-focus-visible .focus-visible, .js-focus-visible #foo .focus-visible {
order: 84;
}
-.focus-visible #foo {
+.focus-visible.js-focus-visible #foo, .js-focus-visible .focus-visible #foo {
order: 85;
}
-#foo+.focus-visible {
+#foo.js-focus-visible+.focus-visible, .js-focus-visible #foo+.focus-visible {
order: 86;
}
-.focus-visible+#foo {
+.focus-visible.js-focus-visible+#foo, .js-focus-visible .focus-visible+#foo {
order: 87;
}
-#foo + .focus-visible {
+#foo.js-focus-visible + .focus-visible, .js-focus-visible #foo + .focus-visible {
order: 88;
}
-.focus-visible + #foo {
+.focus-visible.js-focus-visible + #foo, .js-focus-visible .focus-visible + #foo {
order: 89;
}
-#foo~.focus-visible {
+#foo.js-focus-visible~.focus-visible, .js-focus-visible #foo~.focus-visible {
order: 90;
}
-.focus-visible~#foo {
+.focus-visible.js-focus-visible~#foo, .js-focus-visible .focus-visible~#foo {
order: 91;
}
-#foo ~ .focus-visible {
+#foo.js-focus-visible ~ .focus-visible, .js-focus-visible #foo ~ .focus-visible {
order: 92;
}
-.focus-visible ~ #foo {
+.focus-visible.js-focus-visible ~ #foo, .js-focus-visible .focus-visible ~ #foo {
order: 93;
}
-#foo>.focus-visible {
+#foo.js-focus-visible>.focus-visible, .js-focus-visible #foo>.focus-visible {
order: 94;
}
-.focus-visible>#foo {
+.focus-visible.js-focus-visible>#foo, .js-focus-visible .focus-visible>#foo {
order: 95;
}
-#foo > .focus-visible {
+#foo.js-focus-visible > .focus-visible, .js-focus-visible #foo > .focus-visible {
order: 96;
}
-.focus-visible > #foo {
+.focus-visible.js-focus-visible > #foo, .js-focus-visible .focus-visible > #foo {
order: 97;
}
-#foo,.focus-visible {
+#foo, .focus-visible.js-focus-visible, .js-focus-visible .focus-visible {
order: 98;
}
-.focus-visible, #foo {
+.focus-visible.js-focus-visible, .js-focus-visible .focus-visible, #foo {
order: 99;
}
-__foo.focus-visible {
+__foo.focus-visible.js-focus-visible, .js-focus-visible __foo.focus-visible {
order: 100;
}
@@ -406,475 +406,475 @@ __foo.focus-visible {
order: 101;
}
-__foo .focus-visible {
+__foo.js-focus-visible .focus-visible, .js-focus-visible __foo .focus-visible {
order: 102;
}
-.focus-visible __foo {
+.focus-visible.js-focus-visible __foo, .js-focus-visible .focus-visible __foo {
order: 103;
}
-__foo .focus-visible {
+__foo.js-focus-visible .focus-visible, .js-focus-visible __foo .focus-visible {
order: 104;
}
-.focus-visible __foo {
+.focus-visible.js-focus-visible __foo, .js-focus-visible .focus-visible __foo {
order: 105;
}
-__foo+.focus-visible {
+__foo.js-focus-visible+.focus-visible, .js-focus-visible __foo+.focus-visible {
order: 106;
}
-.focus-visible+__foo {
+.focus-visible.js-focus-visible+__foo, .js-focus-visible .focus-visible+__foo {
order: 107;
}
-__foo + .focus-visible {
+__foo.js-focus-visible + .focus-visible, .js-focus-visible __foo + .focus-visible {
order: 108;
}
-.focus-visible + __foo {
+.focus-visible.js-focus-visible + __foo, .js-focus-visible .focus-visible + __foo {
order: 109;
}
-__foo~.focus-visible {
+__foo.js-focus-visible~.focus-visible, .js-focus-visible __foo~.focus-visible {
order: 110;
}
-.focus-visible~__foo {
+.focus-visible.js-focus-visible~__foo, .js-focus-visible .focus-visible~__foo {
order: 111;
}
-__foo ~ .focus-visible {
+__foo.js-focus-visible ~ .focus-visible, .js-focus-visible __foo ~ .focus-visible {
order: 112;
}
-.focus-visible ~ __foo {
+.focus-visible.js-focus-visible ~ __foo, .js-focus-visible .focus-visible ~ __foo {
order: 113;
}
-__foo>.focus-visible {
+__foo.js-focus-visible>.focus-visible, .js-focus-visible __foo>.focus-visible {
order: 114;
}
-.focus-visible>__foo {
+.focus-visible.js-focus-visible>__foo, .js-focus-visible .focus-visible>__foo {
order: 115;
}
-__foo > .focus-visible {
+__foo.js-focus-visible > .focus-visible, .js-focus-visible __foo > .focus-visible {
order: 116;
}
-.focus-visible > __foo {
+.focus-visible.js-focus-visible > __foo, .js-focus-visible .focus-visible > __foo {
order: 117;
}
-__foo,.focus-visible {
+__foo, .focus-visible.js-focus-visible, .js-focus-visible .focus-visible {
order: 118;
}
-.focus-visible, __foo {
+.focus-visible.js-focus-visible, .js-focus-visible .focus-visible, __foo {
order: 119;
}
-:--foo.focus-visible {
+:--foo.focus-visible.js-focus-visible, .js-focus-visible :--foo.focus-visible {
order: 120;
}
-.focus-visible:--foo {
+.focus-visible:--foo.js-focus-visible, .js-focus-visible .focus-visible:--foo {
order: 121;
}
-:--foo .focus-visible {
+:--foo.js-focus-visible .focus-visible, .js-focus-visible :--foo .focus-visible {
order: 122;
}
-.focus-visible :--foo {
+.focus-visible.js-focus-visible :--foo, .js-focus-visible .focus-visible :--foo {
order: 123;
}
-:--foo .focus-visible {
+:--foo.js-focus-visible .focus-visible, .js-focus-visible :--foo .focus-visible {
order: 124;
}
-.focus-visible :--foo {
+.focus-visible.js-focus-visible :--foo, .js-focus-visible .focus-visible :--foo {
order: 125;
}
-:--foo+.focus-visible {
+:--foo.js-focus-visible+.focus-visible, .js-focus-visible :--foo+.focus-visible {
order: 126;
}
-.focus-visible+:--foo {
+.focus-visible.js-focus-visible+:--foo, .js-focus-visible .focus-visible+:--foo {
order: 127;
}
-:--foo + .focus-visible {
+:--foo.js-focus-visible + .focus-visible, .js-focus-visible :--foo + .focus-visible {
order: 128;
}
-.focus-visible + :--foo {
+.focus-visible.js-focus-visible + :--foo, .js-focus-visible .focus-visible + :--foo {
order: 129;
}
-:--foo~.focus-visible {
+:--foo.js-focus-visible~.focus-visible, .js-focus-visible :--foo~.focus-visible {
order: 130;
}
-.focus-visible~:--foo {
+.focus-visible.js-focus-visible~:--foo, .js-focus-visible .focus-visible~:--foo {
order: 131;
}
-:--foo ~ .focus-visible {
+:--foo.js-focus-visible ~ .focus-visible, .js-focus-visible :--foo ~ .focus-visible {
order: 132;
}
-.focus-visible ~ :--foo {
+.focus-visible.js-focus-visible ~ :--foo, .js-focus-visible .focus-visible ~ :--foo {
order: 133;
}
-:--foo>.focus-visible {
+:--foo.js-focus-visible>.focus-visible, .js-focus-visible :--foo>.focus-visible {
order: 134;
}
-.focus-visible>:--foo {
+.focus-visible.js-focus-visible>:--foo, .js-focus-visible .focus-visible>:--foo {
order: 135;
}
-:--foo > .focus-visible {
+:--foo.js-focus-visible > .focus-visible, .js-focus-visible :--foo > .focus-visible {
order: 136;
}
-.focus-visible > :--foo {
+.focus-visible.js-focus-visible > :--foo, .js-focus-visible .focus-visible > :--foo {
order: 137;
}
-:--foo,.focus-visible {
+:--foo, .focus-visible.js-focus-visible, .js-focus-visible .focus-visible {
order: 138;
}
-.focus-visible, :--foo {
+.focus-visible.js-focus-visible, .js-focus-visible .focus-visible, :--foo {
order: 139;
}
-[foo="baz"].focus-visible {
+[foo="baz"].focus-visible.js-focus-visible, .js-focus-visible [foo="baz"].focus-visible {
order: 140;
}
-.focus-visible[foo="baz"] {
+.focus-visible[foo="baz"].js-focus-visible, .js-focus-visible .focus-visible[foo="baz"] {
order: 141;
}
-[foo="baz"] .focus-visible {
+[foo="baz"].js-focus-visible .focus-visible, .js-focus-visible [foo="baz"] .focus-visible {
order: 142;
}
-.focus-visible [foo="baz"] {
+.focus-visible.js-focus-visible [foo="baz"], .js-focus-visible .focus-visible [foo="baz"] {
order: 143;
}
-[foo="baz"] .focus-visible {
+[foo="baz"].js-focus-visible .focus-visible, .js-focus-visible [foo="baz"] .focus-visible {
order: 144;
}
-.focus-visible [foo="baz"] {
+.focus-visible.js-focus-visible [foo="baz"], .js-focus-visible .focus-visible [foo="baz"] {
order: 145;
}
-[foo="baz"]+.focus-visible {
+[foo="baz"].js-focus-visible+.focus-visible, .js-focus-visible [foo="baz"]+.focus-visible {
order: 146;
}
-.focus-visible+[foo="baz"] {
+.focus-visible.js-focus-visible+[foo="baz"], .js-focus-visible .focus-visible+[foo="baz"] {
order: 147;
}
-[foo="baz"] + .focus-visible {
+[foo="baz"].js-focus-visible + .focus-visible, .js-focus-visible [foo="baz"] + .focus-visible {
order: 148;
}
-.focus-visible + [foo="baz"] {
+.focus-visible.js-focus-visible + [foo="baz"], .js-focus-visible .focus-visible + [foo="baz"] {
order: 149;
}
-[foo="baz"]~.focus-visible {
+[foo="baz"].js-focus-visible~.focus-visible, .js-focus-visible [foo="baz"]~.focus-visible {
order: 150;
}
-.focus-visible~[foo="baz"] {
+.focus-visible.js-focus-visible~[foo="baz"], .js-focus-visible .focus-visible~[foo="baz"] {
order: 151;
}
-[foo="baz"] ~ .focus-visible {
+[foo="baz"].js-focus-visible ~ .focus-visible, .js-focus-visible [foo="baz"] ~ .focus-visible {
order: 152;
}
-.focus-visible ~ [foo="baz"] {
+.focus-visible.js-focus-visible ~ [foo="baz"], .js-focus-visible .focus-visible ~ [foo="baz"] {
order: 153;
}
-[foo="baz"]>.focus-visible {
+[foo="baz"].js-focus-visible>.focus-visible, .js-focus-visible [foo="baz"]>.focus-visible {
order: 154;
}
-.focus-visible>[foo="baz"] {
+.focus-visible.js-focus-visible>[foo="baz"], .js-focus-visible .focus-visible>[foo="baz"] {
order: 155;
}
-[foo="baz"] > .focus-visible {
+[foo="baz"].js-focus-visible > .focus-visible, .js-focus-visible [foo="baz"] > .focus-visible {
order: 156;
}
-.focus-visible > [foo="baz"] {
+.focus-visible.js-focus-visible > [foo="baz"], .js-focus-visible .focus-visible > [foo="baz"] {
order: 157;
}
-[foo="baz"],.focus-visible {
+[foo="baz"], .focus-visible.js-focus-visible, .js-focus-visible .focus-visible {
order: 158;
}
-.focus-visible, [foo="baz"] {
+.focus-visible.js-focus-visible, .js-focus-visible .focus-visible, [foo="baz"] {
order: 159;
}
-*.focus-visible {
+*.focus-visible.js-focus-visible, .js-focus-visible *.focus-visible {
order: 160;
}
-.focus-visible* {
+.focus-visible*.js-focus-visible, .js-focus-visible .focus-visible* {
order: 161;
}
-* .focus-visible {
+*.js-focus-visible .focus-visible, .js-focus-visible * .focus-visible {
order: 162;
}
-.focus-visible * {
+.focus-visible.js-focus-visible *, .js-focus-visible .focus-visible * {
order: 163;
}
-* .focus-visible {
+*.js-focus-visible .focus-visible, .js-focus-visible * .focus-visible {
order: 164;
}
-.focus-visible * {
+.focus-visible.js-focus-visible *, .js-focus-visible .focus-visible * {
order: 165;
}
-*+.focus-visible {
+*.js-focus-visible+.focus-visible, .js-focus-visible *+.focus-visible {
order: 166;
}
-.focus-visible+* {
+.focus-visible.js-focus-visible+*, .js-focus-visible .focus-visible+* {
order: 167;
}
-* + .focus-visible {
+*.js-focus-visible + .focus-visible, .js-focus-visible * + .focus-visible {
order: 168;
}
-.focus-visible + * {
+.focus-visible.js-focus-visible + *, .js-focus-visible .focus-visible + * {
order: 169;
}
-*~.focus-visible {
+*.js-focus-visible~.focus-visible, .js-focus-visible *~.focus-visible {
order: 170;
}
-.focus-visible~* {
+.focus-visible.js-focus-visible~*, .js-focus-visible .focus-visible~* {
order: 171;
}
-* ~ .focus-visible {
+*.js-focus-visible ~ .focus-visible, .js-focus-visible * ~ .focus-visible {
order: 172;
}
-.focus-visible ~ * {
+.focus-visible.js-focus-visible ~ *, .js-focus-visible .focus-visible ~ * {
order: 173;
}
-*>.focus-visible {
+*.js-focus-visible>.focus-visible, .js-focus-visible *>.focus-visible {
order: 174;
}
-.focus-visible>* {
+.focus-visible.js-focus-visible>*, .js-focus-visible .focus-visible>* {
order: 175;
}
-* > .focus-visible {
+*.js-focus-visible > .focus-visible, .js-focus-visible * > .focus-visible {
order: 176;
}
-.focus-visible > * {
+.focus-visible.js-focus-visible > *, .js-focus-visible .focus-visible > * {
order: 177;
}
-*,.focus-visible {
+*, .focus-visible.js-focus-visible, .js-focus-visible .focus-visible {
order: 178;
}
-.focus-visible, * {
+.focus-visible.js-focus-visible, .js-focus-visible .focus-visible, * {
order: 179;
}
-:hover.focus-visible {
+:hover.focus-visible.js-focus-visible, .js-focus-visible :hover.focus-visible {
order: 180;
}
-.focus-visible:hover {
+.focus-visible:hover.js-focus-visible, .js-focus-visible .focus-visible:hover {
order: 181;
}
-:hover .focus-visible {
+:hover.js-focus-visible .focus-visible, .js-focus-visible :hover .focus-visible {
order: 182;
}
-.focus-visible :hover {
+.focus-visible.js-focus-visible :hover, .js-focus-visible .focus-visible :hover {
order: 183;
}
-:hover .focus-visible {
+:hover.js-focus-visible .focus-visible, .js-focus-visible :hover .focus-visible {
order: 184;
}
-.focus-visible :hover {
+.focus-visible.js-focus-visible :hover, .js-focus-visible .focus-visible :hover {
order: 185;
}
-:hover+.focus-visible {
+:hover.js-focus-visible+.focus-visible, .js-focus-visible :hover+.focus-visible {
order: 186;
}
-.focus-visible+:hover {
+.focus-visible.js-focus-visible+:hover, .js-focus-visible .focus-visible+:hover {
order: 187;
}
-:hover + .focus-visible {
+:hover.js-focus-visible + .focus-visible, .js-focus-visible :hover + .focus-visible {
order: 188;
}
-.focus-visible + :hover {
+.focus-visible.js-focus-visible + :hover, .js-focus-visible .focus-visible + :hover {
order: 189;
}
-:hover~.focus-visible {
+:hover.js-focus-visible~.focus-visible, .js-focus-visible :hover~.focus-visible {
order: 190;
}
-.focus-visible~:hover {
+.focus-visible.js-focus-visible~:hover, .js-focus-visible .focus-visible~:hover {
order: 191;
}
-:hover ~ .focus-visible {
+:hover.js-focus-visible ~ .focus-visible, .js-focus-visible :hover ~ .focus-visible {
order: 192;
}
-.focus-visible ~ :hover {
+.focus-visible.js-focus-visible ~ :hover, .js-focus-visible .focus-visible ~ :hover {
order: 193;
}
-:hover>.focus-visible {
+:hover.js-focus-visible>.focus-visible, .js-focus-visible :hover>.focus-visible {
order: 194;
}
-.focus-visible>:hover {
+.focus-visible.js-focus-visible>:hover, .js-focus-visible .focus-visible>:hover {
order: 195;
}
-:hover > .focus-visible {
+:hover.js-focus-visible > .focus-visible, .js-focus-visible :hover > .focus-visible {
order: 196;
}
-.focus-visible > :hover {
+.focus-visible.js-focus-visible > :hover, .js-focus-visible .focus-visible > :hover {
order: 197;
}
-:hover,.focus-visible {
+:hover, .focus-visible.js-focus-visible, .js-focus-visible .focus-visible {
order: 198;
}
-.focus-visible, :hover {
+.focus-visible.js-focus-visible, .js-focus-visible .focus-visible, :hover {
order: 199;
}
-::before.focus-visible {
+.js-focus-visible::before.focus-visible, .js-focus-visible ::before.focus-visible {
order: 200;
}
-.focus-visible::before {
+.focus-visible.js-focus-visible::before, .js-focus-visible .focus-visible::before {
order: 201;
}
-::before .focus-visible {
+.js-focus-visible::before .focus-visible, .js-focus-visible ::before .focus-visible {
order: 202;
}
-.focus-visible ::before {
+.focus-visible.js-focus-visible ::before, .js-focus-visible .focus-visible ::before {
order: 203;
}
-::before .focus-visible {
+.js-focus-visible::before .focus-visible, .js-focus-visible ::before .focus-visible {
order: 204;
}
-.focus-visible ::before {
+.focus-visible.js-focus-visible ::before, .js-focus-visible .focus-visible ::before {
order: 205;
}
-::before+.focus-visible {
+.js-focus-visible::before+.focus-visible, .js-focus-visible ::before+.focus-visible {
order: 206;
}
-.focus-visible+::before {
+.focus-visible.js-focus-visible+::before, .js-focus-visible .focus-visible+::before {
order: 207;
}
-::before + .focus-visible {
+.js-focus-visible::before + .focus-visible, .js-focus-visible ::before + .focus-visible {
order: 208;
}
-.focus-visible + ::before {
+.focus-visible.js-focus-visible + ::before, .js-focus-visible .focus-visible + ::before {
order: 209;
}
-::before~.focus-visible {
+.js-focus-visible::before~.focus-visible, .js-focus-visible ::before~.focus-visible {
order: 210;
}
-.focus-visible~::before {
+.focus-visible.js-focus-visible~::before, .js-focus-visible .focus-visible~::before {
order: 211;
}
-::before ~ .focus-visible {
+.js-focus-visible::before ~ .focus-visible, .js-focus-visible ::before ~ .focus-visible {
order: 212;
}
-.focus-visible ~ ::before {
+.focus-visible.js-focus-visible ~ ::before, .js-focus-visible .focus-visible ~ ::before {
order: 213;
}
-::before>.focus-visible {
+.js-focus-visible::before>.focus-visible, .js-focus-visible ::before>.focus-visible {
order: 214;
}
-.focus-visible>::before {
+.focus-visible.js-focus-visible>::before, .js-focus-visible .focus-visible>::before {
order: 215;
}
-::before > .focus-visible {
+.js-focus-visible::before > .focus-visible, .js-focus-visible ::before > .focus-visible {
order: 216;
}
-.focus-visible > ::before {
+.focus-visible.js-focus-visible > ::before, .js-focus-visible .focus-visible > ::before {
order: 217;
}
-::before,.focus-visible {
+::before, .focus-visible.js-focus-visible, .js-focus-visible .focus-visible {
order: 218;
}
-.focus-visible, ::before {
+.focus-visible.js-focus-visible, .js-focus-visible .focus-visible, ::before {
order: 219;
}
@@ -886,7 +886,7 @@ foo[baz=":focus-visible"] {
order: 221;
}
-:not(.focus-visible) {
+:not(.focus-visible).js-focus-visible, .js-focus-visible :not(.focus-visible) {
order: 222;
}
@@ -894,11 +894,11 @@ foo[baz=":focus-visible"] {
order: 223;
}
-:--.focus-visible {
+:--.focus-visible.js-focus-visible, .js-focus-visible :--.focus-visible {
order: 224;
}
-__.focus-visible {
+__.focus-visible.js-focus-visible, .js-focus-visible __.focus-visible {
order: 225;
}