From b8065df8c2eb252945c73312d318ec3052c74fd4 Mon Sep 17 00:00:00 2001 From: Romain Menke Date: Thu, 1 Oct 2026 21:56:37 +0200 Subject: [PATCH 1/5] wip --- plugin-packs/postcss-preset-env/CHANGELOG.md | 5 + plugin-packs/postcss-preset-env/FEATURES.md | 1 + .../postcss-preset-env/dist/index.d.ts | 219 +++++++------- .../postcss-preset-env/dist/index.mjs | 2 +- plugin-packs/postcss-preset-env/package.json | 1 + .../scripts/plugins-data.json | 5 + .../src/lib/ids-by-execution-order.mjs | 1 + .../src/plugins/plugins-by-id.mjs | 2 + .../src/plugins/plugins-data.mjs | 5 + .../src/plugins/plugins-options.ts | 3 + .../postcss-preset-env/test/_tape.mjs | 8 + .../test/postcss-functions.css | 171 +++++++++++ .../test/postcss-functions.expect.css | 275 ++++++++++++++++++ plugins/postcss-alpha-function/CHANGELOG.md | 4 + plugins/postcss-alpha-function/test/basic.css | 10 + .../test/basic.expect.css | 10 + .../test/basic.preserve-true.expect.css | 15 + .../CHANGELOG.md | 4 + .../test/basic.css | 10 + .../test/basic.expect.css | 10 + .../test/basic.preserve-true.expect.css | 15 + .../test/basic.with-cloned-rules.expect.css | 15 + plugins/postcss-color-function/CHANGELOG.md | 4 + plugins/postcss-color-function/test/basic.css | 10 + .../test/basic.expect.css | 10 + .../test/basic.preserve-true.expect.css | 15 + .../test/basic.with-cloned-rules.expect.css | 15 + .../CHANGELOG.md | 4 + .../test/basic.css | 10 + .../test/basic.expect.css | 10 + .../test/basic.preserve-true.expect.css | 18 ++ .../test/basic.with-cloned-rules.expect.css | 18 ++ .../postcss-color-hex-alpha/test/basic.css | 10 + .../test/basic.expect.css | 10 + .../test/basic.preserve.expect.css | 12 + .../test/basic.with-cloned-rules.expect.css | 12 + .../postcss-color-mix-function/CHANGELOG.md | 4 + .../postcss-color-mix-function/test/basic.css | 10 + .../test/basic.expect.css | 10 + .../test/basic.preserve-true.expect.css | 15 + .../test/basic.with-cloned-rules.expect.css | 15 + .../CHANGELOG.md | 4 + .../test/basic.css | 10 + .../test/basic.expect.css | 15 + .../test/basic.preserve-true.expect.css | 20 ++ .../test/basic.with-cloned-rules.expect.css | 20 ++ .../test/basic.css | 10 + .../test/basic.expect.css | 10 + .../test/basic.preserve-true.expect.css | 12 + .../test/basic.with-cloned-rules.expect.css | 12 + .../postcss-conditional-values/test/basic.css | 10 + .../test/basic.expect.css | 12 + .../CHANGELOG.md | 4 + .../test/basic.css | 10 + .../test/basic.expect.css | 15 + .../postcss-custom-properties/CHANGELOG.md | 1 + .../postcss-custom-properties/dist/index.mjs | 2 +- .../src/get-custom-properties-from-root.ts | 23 +- .../postcss-custom-properties/src/index.ts | 22 +- .../postcss-custom-properties/test/basic.css | 10 + .../test/basic.expect.css | 10 + .../test/basic.preserve.expect.css | 10 + plugins/postcss-design-tokens/test/basic.css | 10 + .../test/basic.expect.css | 10 + .../CHANGELOG.md | 1 + .../test/basic.css | 10 + .../test/basic.expect.css | 15 + .../test/basic.preserve.expect.css | 10 + .../test/basic.with-cloned-rules.expect.css | 15 + .../test/basic.css | 10 + .../test/basic.expect.css | 10 + .../test/basic.preserve.expect.css | 12 + plugins/postcss-gamut-mapping/CHANGELOG.md | 4 + plugins/postcss-gamut-mapping/dist/index.mjs | 2 +- plugins/postcss-gamut-mapping/src/index.ts | 31 +- plugins/postcss-gamut-mapping/test/basic.css | 10 + .../test/basic.expect.css | 18 ++ .../CHANGELOG.md | 4 + .../test/basic.css | 10 + .../test/basic.expect.css | 15 + .../test/basic.preserve-false.expect.css | 10 + .../test/basic.with-cloned-rules.expect.css | 15 + plugins/postcss-hwb-function/CHANGELOG.md | 4 + plugins/postcss-hwb-function/test/basic.css | 10 + .../test/basic.expect.css | 10 + .../test/basic.preserve-true.expect.css | 18 ++ .../test/basic.with-cloned-rules.expect.css | 18 ++ plugins/postcss-ic-unit/CHANGELOG.md | 4 + plugins/postcss-ic-unit/test/basic.css | 10 + plugins/postcss-ic-unit/test/basic.expect.css | 10 + .../test/basic.preserve-true.expect.css | 15 + .../test/basic.with-cloned-rules.expect.css | 15 + plugins/postcss-image-function/CHANGELOG.md | 4 + plugins/postcss-image-function/test/basic.css | 10 + .../test/basic.expect.css | 10 + .../test/basic.preserve-true.expect.css | 15 + .../postcss-image-set-function/CHANGELOG.md | 4 + .../postcss-image-set-function/dist/index.mjs | 2 +- .../src/lib/process-image-set.ts | 26 +- .../postcss-image-set-function/test/basic.css | 10 + .../test/basic.expect.css | 19 ++ .../test/basic.no-preserve.expect.css | 17 ++ .../test/basic.with-cloned-rules.expect.css | 19 ++ plugins/postcss-lab-function/CHANGELOG.md | 4 + plugins/postcss-lab-function/test/basic.css | 10 + .../test/basic.display-p3-false.expect.css | 10 + ....display-p3-false.preserve-true.expect.css | 15 + .../test/basic.expect.css | 10 + .../test/basic.preserve-true.expect.css | 15 + .../test/basic.with-cloned-rules.expect.css | 15 + .../test/basic.css | 10 + .../test/basic.expect.css | 25 ++ .../test/basic.preserve-false.expect.css | 17 ++ .../CHANGELOG.md | 4 + .../test/basic.css | 10 + .../test/basic.expect.css | 15 + .../test/basic.hebrew.expect.css | 15 + .../test/basic.preserve-false.expect.css | 10 + .../test/basic.vertical.expect.css | 15 + .../test/basic.with-cloned-rules.expect.css | 15 + plugins/postcss-minify/test/basic.css | 10 + plugins/postcss-minify/test/basic.expect.css | 2 +- plugins/postcss-nested-calc/test/basic.css | 10 + .../postcss-nested-calc/test/basic.expect.css | 11 + .../test/basic.preserve-false.expect.css | 10 + .../test/basic.with-cloned-rules.expect.css | 11 + plugins/postcss-oklab-function/CHANGELOG.md | 4 + plugins/postcss-oklab-function/test/basic.css | 10 + .../test/basic.expect.css | 10 + ....preserve-true.display-p3-false.expect.css | 15 + .../test/basic.preserve-true.expect.css | 15 + .../CHANGELOG.md | 1 + .../dist/index.mjs | 2 +- .../src/index.ts | 29 +- .../test/basic.css | 11 + .../test/basic.expect.css | 14 + .../postcss-random-function/test/basic.css | 10 + .../test/basic.expect.css | 98 ++++--- .../test/basic.preserve-true.expect.css | 98 ++++--- plugins/postcss-rebase-url/test/basic.css | 10 + .../postcss-rebase-url/test/basic.expect.css | 10 + .../CHANGELOG.md | 4 + .../test/basic.css | 10 + .../test/basic.expect.css | 10 + .../test/basic.preserve-true.expect.css | 15 + plugins/postcss-rewrite-url/test/basic.css | 10 + .../postcss-rewrite-url/test/basic.expect.css | 10 + plugins/postcss-sign-functions/test/basic.css | 10 + .../test/basic.expect.css | 10 + .../test/basic.preserve-true.expect.css | 12 + .../test/basic.css | 10 + .../test/basic.expect.css | 10 + .../test/basic.preserve-true.expect.css | 12 + .../CHANGELOG.md | 4 + .../dist/index.mjs | 2 +- .../src/index.ts | 30 +- .../test/basic.css | 10 + .../test/basic.expect.css | 11 + .../test/basic.css | 10 + .../test/basic.expect.css | 10 + .../test/basic.preserve-true.expect.css | 12 + 161 files changed, 2311 insertions(+), 224 deletions(-) create mode 100644 plugin-packs/postcss-preset-env/test/postcss-functions.css create mode 100644 plugin-packs/postcss-preset-env/test/postcss-functions.expect.css diff --git a/plugin-packs/postcss-preset-env/CHANGELOG.md b/plugin-packs/postcss-preset-env/CHANGELOG.md index 644f631458..e17f571f0e 100644 --- a/plugin-packs/postcss-preset-env/CHANGELOG.md +++ b/plugin-packs/postcss-preset-env/CHANGELOG.md @@ -1,5 +1,10 @@ # Changes to PostCSS Preset Env +### Unreleased (minor) + +- Added `@csstools/postcss-custom-functions` [Check the plugin README](https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-custom-functions#readme) for usage details. +- Correctly nest conditional rules inside `@function` instead of cloning the `@function` rule. + ### 11.5.5 _October 1, 2026_ diff --git a/plugin-packs/postcss-preset-env/FEATURES.md b/plugin-packs/postcss-preset-env/FEATURES.md index f7267eded7..058f27cc97 100644 --- a/plugin-packs/postcss-preset-env/FEATURES.md +++ b/plugin-packs/postcss-preset-env/FEATURES.md @@ -20,6 +20,7 @@ The `ID` listed is the key for PostCSS Preset Env configuration in your project. | [Baseline Status](https://cssdb.org/#container-rule-prelude-list) | `container-rule-prelude-list` | `@container` prelude list | [example](https://preset-env.cssdb.org/features/#container-rule-prelude-list) | [docs](https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-container-rule-prelude-list#readme) | | [Baseline Status](https://cssdb.org/#content-alt-text) | `content-alt-text` | Alt text for `content` | [example](https://preset-env.cssdb.org/features/#content-alt-text) | [docs](https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-content-alt-text#readme) | | [Baseline Status](https://cssdb.org/#contrast-color-function) | `contrast-color-function` | `contrast-color()` Function | [example](https://preset-env.cssdb.org/features/#contrast-color-function) | [docs](https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-contrast-color-function#readme) | +| | `custom-functions` | | | | | [Baseline Status](https://cssdb.org/#custom-media-queries) | `custom-media-queries` | Custom Media Queries | [example](https://preset-env.cssdb.org/features/#custom-media-queries) | [docs](https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-custom-media#readme) | | [Baseline Status](https://cssdb.org/#custom-properties) | `custom-properties` | Custom Properties | [example](https://preset-env.cssdb.org/features/#custom-properties) | [docs](https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-custom-properties#readme) | | [Baseline Status](https://cssdb.org/#custom-selectors) | `custom-selectors` | Custom Selectors | [example](https://preset-env.cssdb.org/features/#custom-selectors) | [docs](https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-custom-selectors#readme) | diff --git a/plugin-packs/postcss-preset-env/dist/index.d.ts b/plugin-packs/postcss-preset-env/dist/index.d.ts index b956a59f0a..49096e1336 100644 --- a/plugin-packs/postcss-preset-env/dist/index.d.ts +++ b/plugin-packs/postcss-preset-env/dist/index.d.ts @@ -6,66 +6,67 @@ import type { pluginOptions as pluginOptions_12 } from '@csstools/postcss-color- import type { pluginOptions as pluginOptions_13 } from '@csstools/postcss-container-rule-prelude-list'; import type { pluginOptions as pluginOptions_14 } from '@csstools/postcss-content-alt-text'; import type { pluginOptions as pluginOptions_15 } from '@csstools/postcss-contrast-color-function'; -import type { pluginOptions as pluginOptions_16 } from 'postcss-custom-media'; -import type { pluginOptions as pluginOptions_17 } from 'postcss-custom-properties'; -import type { pluginOptions as pluginOptions_18 } from 'postcss-custom-selectors'; -import type { pluginOptions as pluginOptions_19 } from 'postcss-dir-pseudo-class'; +import type { pluginOptions as pluginOptions_16 } from '@csstools/postcss-custom-functions'; +import type { pluginOptions as pluginOptions_17 } from 'postcss-custom-media'; +import type { pluginOptions as pluginOptions_18 } from 'postcss-custom-properties'; +import type { pluginOptions as pluginOptions_19 } from 'postcss-custom-selectors'; import type { pluginOptions as pluginOptions_2 } from '@csstools/postcss-initial'; -import type { pluginOptions as pluginOptions_20 } from '@csstools/postcss-normalize-display-values'; -import type { pluginOptions as pluginOptions_21 } from 'postcss-double-position-gradients'; -import type { pluginOptions as pluginOptions_22 } from '@csstools/postcss-exponential-functions'; -import type { pluginOptions as pluginOptions_23 } from '@csstools/postcss-fit-tolerance-property'; -import type { pluginOptions as pluginOptions_24 } from '@csstools/postcss-logical-float-and-clear'; -import type { pluginOptions as pluginOptions_25 } from 'postcss-focus-visible'; -import type { pluginOptions as pluginOptions_26 } from 'postcss-focus-within'; -import type { pluginOptions as pluginOptions_27 } from '@csstools/postcss-font-format-keywords'; -import type { pluginOptions as pluginOptions_28 } from '@csstools/postcss-font-width-property'; -import type { pluginOptions as pluginOptions_29 } from '@csstools/postcss-gamut-mapping'; +import type { pluginOptions as pluginOptions_20 } from 'postcss-dir-pseudo-class'; +import type { pluginOptions as pluginOptions_21 } from '@csstools/postcss-normalize-display-values'; +import type { pluginOptions as pluginOptions_22 } from 'postcss-double-position-gradients'; +import type { pluginOptions as pluginOptions_23 } from '@csstools/postcss-exponential-functions'; +import type { pluginOptions as pluginOptions_24 } from '@csstools/postcss-fit-tolerance-property'; +import type { pluginOptions as pluginOptions_25 } from '@csstools/postcss-logical-float-and-clear'; +import type { pluginOptions as pluginOptions_26 } from 'postcss-focus-visible'; +import type { pluginOptions as pluginOptions_27 } from 'postcss-focus-within'; +import type { pluginOptions as pluginOptions_28 } from '@csstools/postcss-font-format-keywords'; +import type { pluginOptions as pluginOptions_29 } from '@csstools/postcss-font-width-property'; import type { pluginOptions as pluginOptions_3 } from '@csstools/postcss-alpha-function'; -import type { pluginOptions as pluginOptions_30 } from 'postcss-gap-properties'; -import type { pluginOptions as pluginOptions_31 } from '@csstools/postcss-gradients-interpolation-method'; -import type { pluginOptions as pluginOptions_32 } from 'css-has-pseudo'; -import type { pluginOptions as pluginOptions_33 } from 'postcss-color-hex-alpha'; -import type { pluginOptions as pluginOptions_34 } from '@csstools/postcss-hwb-function'; -import type { pluginOptions as pluginOptions_35 } from '@csstools/postcss-ic-unit'; -import type { pluginOptions as pluginOptions_36 } from '@csstools/postcss-image-function'; -import type { pluginOptions as pluginOptions_37 } from 'postcss-image-set-function'; -import type { pluginOptions as pluginOptions_38 } from '@csstools/postcss-is-pseudo-class'; -import type { pluginOptions as pluginOptions_39 } from 'postcss-lab-function'; +import type { pluginOptions as pluginOptions_30 } from '@csstools/postcss-gamut-mapping'; +import type { pluginOptions as pluginOptions_31 } from 'postcss-gap-properties'; +import type { pluginOptions as pluginOptions_32 } from '@csstools/postcss-gradients-interpolation-method'; +import type { pluginOptions as pluginOptions_33 } from 'css-has-pseudo'; +import type { pluginOptions as pluginOptions_34 } from 'postcss-color-hex-alpha'; +import type { pluginOptions as pluginOptions_35 } from '@csstools/postcss-hwb-function'; +import type { pluginOptions as pluginOptions_36 } from '@csstools/postcss-ic-unit'; +import type { pluginOptions as pluginOptions_37 } from '@csstools/postcss-image-function'; +import type { pluginOptions as pluginOptions_38 } from 'postcss-image-set-function'; +import type { pluginOptions as pluginOptions_39 } from '@csstools/postcss-is-pseudo-class'; import type { pluginOptions as pluginOptions_4 } from 'postcss-pseudo-class-any-link'; -import type { pluginOptions as pluginOptions_40 } from '@csstools/postcss-light-dark-function'; -import type { pluginOptions as pluginOptions_41 } from '@csstools/postcss-logical-overflow'; -import type { pluginOptions as pluginOptions_42 } from '@csstools/postcss-logical-overscroll-behavior'; -import type { pluginOptions as pluginOptions_43 } from 'postcss-logical'; -import type { pluginOptions as pluginOptions_44 } from '@csstools/postcss-logical-resize'; -import type { pluginOptions as pluginOptions_45 } from '@csstools/postcss-logical-viewport-units'; -import type { pluginOptions as pluginOptions_46 } from '@csstools/postcss-media-queries-aspect-ratio-number-values'; -import type { pluginOptions as pluginOptions_47 } from '@csstools/postcss-media-minmax'; -import type { pluginOptions as pluginOptions_48 } from '@csstools/postcss-mixins'; -import type { pluginOptions as pluginOptions_49 } from '@csstools/postcss-nested-calc'; +import type { pluginOptions as pluginOptions_40 } from 'postcss-lab-function'; +import type { pluginOptions as pluginOptions_41 } from '@csstools/postcss-light-dark-function'; +import type { pluginOptions as pluginOptions_42 } from '@csstools/postcss-logical-overflow'; +import type { pluginOptions as pluginOptions_43 } from '@csstools/postcss-logical-overscroll-behavior'; +import type { pluginOptions as pluginOptions_44 } from 'postcss-logical'; +import type { pluginOptions as pluginOptions_45 } from '@csstools/postcss-logical-resize'; +import type { pluginOptions as pluginOptions_46 } from '@csstools/postcss-logical-viewport-units'; +import type { pluginOptions as pluginOptions_47 } from '@csstools/postcss-media-queries-aspect-ratio-number-values'; +import type { pluginOptions as pluginOptions_48 } from '@csstools/postcss-media-minmax'; +import type { pluginOptions as pluginOptions_49 } from '@csstools/postcss-mixins'; import type { pluginOptions as pluginOptions_5 } from 'css-blank-pseudo'; -import type { pluginOptions as pluginOptions_50 } from 'postcss-nesting'; -import type { pluginOptions as pluginOptions_51 } from 'postcss-selector-not'; -import type { pluginOptions as pluginOptions_52 } from '@csstools/postcss-oklab-function'; -import type { pluginOptions as pluginOptions_53 } from 'postcss-overflow-shorthand'; -import type { pluginOptions as pluginOptions_54 } from 'postcss-place'; -import type { pluginOptions as pluginOptions_55 } from '@csstools/postcss-position-area-property'; -import type { pluginOptions as pluginOptions_56 } from 'css-prefers-color-scheme'; -import type { pluginOptions as pluginOptions_57 } from '@csstools/postcss-property-rule-optional-descriptors'; -import type { pluginOptions as pluginOptions_58 } from '@csstools/postcss-property-rule-prelude-list'; -import type { pluginOptions as pluginOptions_59 } from '@csstools/postcss-random-function'; +import type { pluginOptions as pluginOptions_50 } from '@csstools/postcss-nested-calc'; +import type { pluginOptions as pluginOptions_51 } from 'postcss-nesting'; +import type { pluginOptions as pluginOptions_52 } from 'postcss-selector-not'; +import type { pluginOptions as pluginOptions_53 } from '@csstools/postcss-oklab-function'; +import type { pluginOptions as pluginOptions_54 } from 'postcss-overflow-shorthand'; +import type { pluginOptions as pluginOptions_55 } from 'postcss-place'; +import type { pluginOptions as pluginOptions_56 } from '@csstools/postcss-position-area-property'; +import type { pluginOptions as pluginOptions_57 } from 'css-prefers-color-scheme'; +import type { pluginOptions as pluginOptions_58 } from '@csstools/postcss-property-rule-optional-descriptors'; +import type { pluginOptions as pluginOptions_59 } from '@csstools/postcss-property-rule-prelude-list'; import type { pluginOptions as pluginOptions_6 } from '@csstools/postcss-cascade-layers'; -import type { pluginOptions as pluginOptions_60 } from 'postcss-color-rebeccapurple'; -import type { pluginOptions as pluginOptions_61 } from '@csstools/postcss-relative-color-syntax'; -import type { pluginOptions as pluginOptions_62 } from '@csstools/postcss-scope-pseudo-class'; -import type { pluginOptions as pluginOptions_63 } from '@csstools/postcss-sign-functions'; -import type { pluginOptions as pluginOptions_64 } from '@csstools/postcss-stepped-value-functions'; -import type { pluginOptions as pluginOptions_65 } from '@csstools/postcss-syntax-descriptor-syntax-production'; -import type { pluginOptions as pluginOptions_66 } from '@csstools/postcss-system-ui-font-family'; -import type { pluginOptions as pluginOptions_67 } from '@csstools/postcss-text-decoration-shorthand'; -import type { pluginOptions as pluginOptions_68 } from '@csstools/postcss-trigonometric-functions'; -import type { pluginOptions as pluginOptions_69 } from '@csstools/postcss-unset-value'; +import type { pluginOptions as pluginOptions_60 } from '@csstools/postcss-random-function'; +import type { pluginOptions as pluginOptions_61 } from 'postcss-color-rebeccapurple'; +import type { pluginOptions as pluginOptions_62 } from '@csstools/postcss-relative-color-syntax'; +import type { pluginOptions as pluginOptions_63 } from '@csstools/postcss-scope-pseudo-class'; +import type { pluginOptions as pluginOptions_64 } from '@csstools/postcss-sign-functions'; +import type { pluginOptions as pluginOptions_65 } from '@csstools/postcss-stepped-value-functions'; +import type { pluginOptions as pluginOptions_66 } from '@csstools/postcss-syntax-descriptor-syntax-production'; +import type { pluginOptions as pluginOptions_67 } from '@csstools/postcss-system-ui-font-family'; +import type { pluginOptions as pluginOptions_68 } from '@csstools/postcss-text-decoration-shorthand'; +import type { pluginOptions as pluginOptions_69 } from '@csstools/postcss-trigonometric-functions'; import type { pluginOptions as pluginOptions_7 } from 'postcss-attribute-case-insensitive'; +import type { pluginOptions as pluginOptions_70 } from '@csstools/postcss-unset-value'; import type { pluginOptions as pluginOptions_8 } from '@csstools/postcss-color-function'; import type { pluginOptions as pluginOptions_9 } from '@csstools/postcss-color-function-display-p3-linear'; @@ -198,120 +199,122 @@ export declare type pluginsOptions = { 'content-alt-text'?: subPluginOptions; /** plugin options for "@csstools/postcss-contrast-color-function" */ 'contrast-color-function'?: subPluginOptions; + /** plugin options for "@csstools/postcss-custom-functions" */ + 'custom-functions'?: subPluginOptions; /** plugin options for "postcss-custom-media" */ - 'custom-media-queries'?: subPluginOptions; + 'custom-media-queries'?: subPluginOptions; /** plugin options for "postcss-custom-properties" */ - 'custom-properties'?: subPluginOptions; + 'custom-properties'?: subPluginOptions; /** plugin options for "postcss-custom-selectors" */ - 'custom-selectors'?: subPluginOptions; + 'custom-selectors'?: subPluginOptions; /** plugin options for "postcss-dir-pseudo-class" */ - 'dir-pseudo-class'?: subPluginOptions; + 'dir-pseudo-class'?: subPluginOptions; /** plugin options for "@csstools/postcss-normalize-display-values" */ - 'display-two-values'?: subPluginOptions; + 'display-two-values'?: subPluginOptions; /** plugin options for "postcss-double-position-gradients" */ - 'double-position-gradients'?: subPluginOptions; + 'double-position-gradients'?: subPluginOptions; /** plugin options for "@csstools/postcss-exponential-functions" */ - 'exponential-functions'?: subPluginOptions; + 'exponential-functions'?: subPluginOptions; /** plugin options for "@csstools/postcss-fit-tolerance-property" */ - 'fit-tolerance-property'?: subPluginOptions; + 'fit-tolerance-property'?: subPluginOptions; /** plugin options for "@csstools/postcss-logical-float-and-clear" */ - 'float-clear-logical-values'?: subPluginOptions; + 'float-clear-logical-values'?: subPluginOptions; /** plugin options for "postcss-focus-visible" */ - 'focus-visible-pseudo-class'?: subPluginOptions; + 'focus-visible-pseudo-class'?: subPluginOptions; /** plugin options for "postcss-focus-within" */ - 'focus-within-pseudo-class'?: subPluginOptions; + 'focus-within-pseudo-class'?: subPluginOptions; /** plugin options for "@csstools/postcss-font-format-keywords" */ - 'font-format-keywords'?: subPluginOptions; + 'font-format-keywords'?: subPluginOptions; /** plugin options for "postcss-font-variant" */ 'font-variant-property'?: subPluginOptions; /** plugin options for "@csstools/postcss-font-width-property" */ - 'font-width-property'?: subPluginOptions; + 'font-width-property'?: subPluginOptions; /** plugin options for "@csstools/postcss-gamut-mapping" */ - 'gamut-mapping'?: subPluginOptions; + 'gamut-mapping'?: subPluginOptions; /** plugin options for "postcss-gap-properties" */ - 'gap-properties'?: subPluginOptions; + 'gap-properties'?: subPluginOptions; /** plugin options for "@csstools/postcss-gradients-interpolation-method" */ - 'gradients-interpolation-method'?: subPluginOptions; + 'gradients-interpolation-method'?: subPluginOptions; /** plugin options for "css-has-pseudo" */ - 'has-pseudo-class'?: subPluginOptions; + 'has-pseudo-class'?: subPluginOptions; /** plugin options for "postcss-color-hex-alpha" */ - 'hexadecimal-alpha-notation'?: subPluginOptions; + 'hexadecimal-alpha-notation'?: subPluginOptions; /** plugin options for "@csstools/postcss-hwb-function" */ - 'hwb-function'?: subPluginOptions; + 'hwb-function'?: subPluginOptions; /** plugin options for "@csstools/postcss-ic-unit" */ - 'ic-unit'?: subPluginOptions; + 'ic-unit'?: subPluginOptions; /** plugin options for "@csstools/postcss-image-function" */ - 'image-function'?: subPluginOptions; + 'image-function'?: subPluginOptions; /** plugin options for "postcss-image-set-function" */ - 'image-set-function'?: subPluginOptions; + 'image-set-function'?: subPluginOptions; /** plugin options for "@csstools/postcss-is-pseudo-class" */ - 'is-pseudo-class'?: subPluginOptions; + 'is-pseudo-class'?: subPluginOptions; /** plugin options for "postcss-lab-function" */ - 'lab-function'?: subPluginOptions; + 'lab-function'?: subPluginOptions; /** plugin options for "@csstools/postcss-light-dark-function" */ - 'light-dark-function'?: subPluginOptions; + 'light-dark-function'?: subPluginOptions; /** plugin options for "@csstools/postcss-logical-overflow" */ - 'logical-overflow'?: subPluginOptions; + 'logical-overflow'?: subPluginOptions; /** plugin options for "@csstools/postcss-logical-overscroll-behavior" */ - 'logical-overscroll-behavior'?: subPluginOptions; + 'logical-overscroll-behavior'?: subPluginOptions; /** plugin options for "postcss-logical" */ - 'logical-properties-and-values'?: subPluginOptions; + 'logical-properties-and-values'?: subPluginOptions; /** plugin options for "@csstools/postcss-logical-resize" */ - 'logical-resize'?: subPluginOptions; + 'logical-resize'?: subPluginOptions; /** plugin options for "@csstools/postcss-logical-viewport-units" */ - 'logical-viewport-units'?: subPluginOptions; + 'logical-viewport-units'?: subPluginOptions; /** plugin options for "@csstools/postcss-media-queries-aspect-ratio-number-values" */ - 'media-queries-aspect-ratio-number-values'?: subPluginOptions; + 'media-queries-aspect-ratio-number-values'?: subPluginOptions; /** plugin options for "@csstools/postcss-media-minmax" */ - 'media-query-ranges'?: subPluginOptions; + 'media-query-ranges'?: subPluginOptions; /** plugin options for "@csstools/postcss-mixins" */ - 'mixins'?: subPluginOptions; + 'mixins'?: subPluginOptions; /** plugin options for "@csstools/postcss-nested-calc" */ - 'nested-calc'?: subPluginOptions; + 'nested-calc'?: subPluginOptions; /** plugin options for "postcss-nesting" */ - 'nesting-rules'?: subPluginOptions; + 'nesting-rules'?: subPluginOptions; /** plugin options for "postcss-selector-not" */ - 'not-pseudo-class'?: subPluginOptions; + 'not-pseudo-class'?: subPluginOptions; /** plugin options for "@csstools/postcss-oklab-function" */ - 'oklab-function'?: subPluginOptions; + 'oklab-function'?: subPluginOptions; /** plugin options for "postcss-opacity-percentage" */ 'opacity-percentage'?: subPluginOptions; /** plugin options for "postcss-overflow-shorthand" */ - 'overflow-property'?: subPluginOptions; + 'overflow-property'?: subPluginOptions; /** plugin options for "postcss-replace-overflow-wrap" */ 'overflow-wrap-property'?: subPluginOptions; /** plugin options for "postcss-place" */ - 'place-properties'?: subPluginOptions; + 'place-properties'?: subPluginOptions; /** plugin options for "@csstools/postcss-position-area-property" */ - 'position-area-property'?: subPluginOptions; + 'position-area-property'?: subPluginOptions; /** plugin options for "css-prefers-color-scheme" */ - 'prefers-color-scheme-query'?: subPluginOptions; + 'prefers-color-scheme-query'?: subPluginOptions; /** plugin options for "@csstools/postcss-property-rule-optional-descriptors" */ - 'property-rule-optional-descriptors'?: subPluginOptions; + 'property-rule-optional-descriptors'?: subPluginOptions; /** plugin options for "@csstools/postcss-property-rule-prelude-list" */ - 'property-rule-prelude-list'?: subPluginOptions; + 'property-rule-prelude-list'?: subPluginOptions; /** plugin options for "@csstools/postcss-random-function" */ - 'random-function'?: subPluginOptions; + 'random-function'?: subPluginOptions; /** plugin options for "postcss-color-rebeccapurple" */ - 'rebeccapurple-color'?: subPluginOptions; + 'rebeccapurple-color'?: subPluginOptions; /** plugin options for "@csstools/postcss-relative-color-syntax" */ - 'relative-color-syntax'?: subPluginOptions; + 'relative-color-syntax'?: subPluginOptions; /** plugin options for "@csstools/postcss-scope-pseudo-class" */ - 'scope-pseudo-class'?: subPluginOptions; + 'scope-pseudo-class'?: subPluginOptions; /** plugin options for "@csstools/postcss-sign-functions" */ - 'sign-functions'?: subPluginOptions; + 'sign-functions'?: subPluginOptions; /** plugin options for "@csstools/postcss-stepped-value-functions" */ - 'stepped-value-functions'?: subPluginOptions; + 'stepped-value-functions'?: subPluginOptions; /** plugin options for "@csstools/postcss-syntax-descriptor-syntax-production" */ - 'syntax-descriptor-syntax-production'?: subPluginOptions; + 'syntax-descriptor-syntax-production'?: subPluginOptions; /** plugin options for "@csstools/postcss-system-ui-font-family" */ - 'system-ui-font-family'?: subPluginOptions; + 'system-ui-font-family'?: subPluginOptions; /** plugin options for "@csstools/postcss-text-decoration-shorthand" */ - 'text-decoration-shorthand'?: subPluginOptions; + 'text-decoration-shorthand'?: subPluginOptions; /** plugin options for "@csstools/postcss-trigonometric-functions" */ - 'trigonometric-functions'?: subPluginOptions; + 'trigonometric-functions'?: subPluginOptions; /** plugin options for "@csstools/postcss-unset-value" */ - 'unset-value'?: subPluginOptions; + 'unset-value'?: subPluginOptions; }; /** postcss-clamp plugin options */ diff --git a/plugin-packs/postcss-preset-env/dist/index.mjs b/plugin-packs/postcss-preset-env/dist/index.mjs index 04e3c902ad..17f66737ec 100644 --- a/plugin-packs/postcss-preset-env/dist/index.mjs +++ b/plugin-packs/postcss-preset-env/dist/index.mjs @@ -1 +1 @@ -import s from"autoprefixer";import o from"cssdb";import e from"browserslist";import t from"@csstools/postcss-initial";import r from"@csstools/postcss-alpha-function";import i from"postcss-pseudo-class-any-link";import a from"css-blank-pseudo";import c from"postcss-page-break";import p from"@csstools/postcss-cascade-layers";import n from"postcss-attribute-case-insensitive";import l from"postcss-clamp";import m from"@csstools/postcss-color-function";import u from"@csstools/postcss-color-function-display-p3-linear";import d from"postcss-color-functional-notation";import f from"@csstools/postcss-color-mix-function";import g from"@csstools/postcss-color-mix-variadic-function-arguments";import h from"@csstools/postcss-container-rule-prelude-list";import N from"@csstools/postcss-content-alt-text";import b from"@csstools/postcss-contrast-color-function";import y from"postcss-custom-media";import v from"postcss-custom-properties";import k from"postcss-custom-selectors";import w from"postcss-dir-pseudo-class";import x from"@csstools/postcss-normalize-display-values";import F from"postcss-double-position-gradients";import O from"@csstools/postcss-exponential-functions";import P from"@csstools/postcss-fit-tolerance-property";import C from"@csstools/postcss-logical-float-and-clear";import $ from"postcss-focus-visible";import S from"postcss-focus-within";import A from"@csstools/postcss-font-format-keywords";import L from"postcss-font-variant";import _ from"@csstools/postcss-font-width-property";import I from"@csstools/postcss-gamut-mapping";import E from"postcss-gap-properties";import B from"@csstools/postcss-gradients-interpolation-method";import q from"css-has-pseudo";import M from"postcss-color-hex-alpha";import D from"@csstools/postcss-hwb-function";import j from"@csstools/postcss-ic-unit";import z from"@csstools/postcss-image-function";import R from"postcss-image-set-function";import U from"@csstools/postcss-is-pseudo-class";import T from"postcss-lab-function";import V from"@csstools/postcss-light-dark-function";import H from"@csstools/postcss-logical-overflow";import W from"@csstools/postcss-logical-overscroll-behavior";import G from"postcss-logical";import K from"@csstools/postcss-logical-resize";import Z from"@csstools/postcss-logical-viewport-units";import Q from"@csstools/postcss-media-queries-aspect-ratio-number-values";import J from"@csstools/postcss-media-minmax";import X from"@csstools/postcss-mixins";import Y from"@csstools/postcss-nested-calc";import ss from"postcss-nesting";import os from"postcss-selector-not";import es from"@csstools/postcss-oklab-function";import ts from"postcss-opacity-percentage";import rs from"postcss-overflow-shorthand";import is from"postcss-replace-overflow-wrap";import as from"postcss-place";import cs from"@csstools/postcss-position-area-property";import ps from"css-prefers-color-scheme";import ns from"@csstools/postcss-progressive-custom-properties";import ls from"@csstools/postcss-property-rule-optional-descriptors";import ms from"@csstools/postcss-property-rule-prelude-list";import us from"@csstools/postcss-random-function";import ds from"postcss-color-rebeccapurple";import fs from"@csstools/postcss-relative-color-syntax";import gs from"@csstools/postcss-scope-pseudo-class";import hs from"@csstools/postcss-sign-functions";import Ns from"@csstools/postcss-stepped-value-functions";import bs from"@csstools/postcss-syntax-descriptor-syntax-production";import ys from"@csstools/postcss-system-ui-font-family";import vs from"@csstools/postcss-text-decoration-shorthand";import ks from"@csstools/postcss-trigonometric-functions";import ws from"@csstools/postcss-unset-value";const xs={"blank-pseudo-class":"https://github.com/csstools/postcss-plugins/blob/main/plugins/css-blank-pseudo/README.md#browser","focus-visible-pseudo-class":"https://github.com/WICG/focus-visible","focus-within-pseudo-class":"https://github.com/csstools/postcss-plugins/blob/main/plugins/postcss-focus-within/README.md#browser","has-pseudo-class":"https://github.com/csstools/postcss-plugins/blob/main/plugins/css-has-pseudo/README.md#browser","prefers-color-scheme-query":"https://github.com/csstools/postcss-plugins/blob/main/plugins/css-prefers-color-scheme/README.md#browser"},Fs=["blank-pseudo-class","focus-visible-pseudo-class","focus-within-pseudo-class","has-pseudo-class","prefers-color-scheme-query"];function logFeaturesList(s,o,e){if(o.debug){e.log("Enabling the following feature(s):");const t=[],r=[];!1!==o.autoprefixer&&r.push(" autoprefixer"),s.forEach(s=>{s.id.startsWith("before")||s.id.startsWith("after")?r.push(` ${s.id} (injected via options)`):r.push(` ${s.id}`),void 0!==xs[s.id]&&t.push(s.id)}),r.sort((s,o)=>s.localeCompare(o)),t.sort((s,o)=>s.localeCompare(o)),r.forEach(s=>e.log(s)),t.length&&(e.log("These feature(s) need a browser library to work:"),t.forEach(s=>e.log(` ${s}: ${xs[s]}`)))}}function initializeSharedOptions(s){if("preserve"in s){const o={};return o.preserve=s.preserve,o}return!1}function clamp(s,o,e){return Math.max(s,Math.min(o,e))}function stageFromOptions(s,o){let e=2;if(void 0===s.stage)return o.log("Using features from Stage 2 (default)."),e;if(!1===s.stage)e=5;else{let o=parseInt(s.stage,10);Number.isNaN(o)&&(o=0),e=clamp(0,o,5)}return 5===e?o.log('Stage has been disabled, features will be handled via the "features" option.'):o.log(`Using features from Stage ${e}.`),e}const Os=Symbol("insertBefore"),Ps=Symbol("insertAfter"),Cs=Symbol("insertOrder"),$s=Symbol("plugin");function getTransformedInsertions(s,o,e){if("insertBefore"!==e&&"insertAfter"!==e)return[];const t="insertBefore"===e?Os:Ps,r=[];for(const e in o){if(!Object.hasOwnProperty.call(o,e))continue;if(!s.find(s=>s.id===e))continue;let i=o[e];Array.isArray(i)||(i=[i]);for(let s=0;sfeatureIsInsertedOrHasAPlugin(s)).sort((s,o)=>featureIsLess(s,o))}function getOptionsForBrowsersByFeature(s,o,e,t){switch(o.id){case"is-pseudo-class":return{onComplexSelector:"warning"};case"any-link-pseudo-class":if(s.find(s=>s.startsWith("ie ")||"edge 12"===s||"edge 13"===s||"edge 14"===s||"edge 15"===s||"edge 16"===s||"edge 17"===s||"edge 18"===s))return t.log("- 'any-link-pseudo-class' setting 'subFeatures: { areaHrefNeedsFixing: true }' due to lack of browser support for area[href] in Edge and IE."),{subFeatures:{areaHrefNeedsFixing:!0}};return{};case"logical-properties-and-values":case"float-clear-logical-values":case"logical-resize":case"logical-viewport-units":case"logical-overflow":case"logical-overscroll-behavior":return"logical"in e?e.logical:{};default:return{}}}const Ls=["and_chr","and_ff","android","chrome","edge","firefox","ie","ios_saf","op_mini","op_mob","opera","safari","samsung"];function getUnsupportedBrowsersByFeature(s){if(!s)return[];if("position-area-property"===s.id)return["chrome 125","chrome 126","chrome 127","chrome 128","edge 125","edge 126","edge 127","edge 128","and_chr 125","and_chr 126","and_chr 127","and_chr 128","android 125","android 126","android 127","android 128","samsung 27","opera 111","opera 112","opera 113","opera 114","op_mob 83","op_mob 84","op_mob 85"];if(!("browser_support"in s))return["> 0%"];const o=[];return Ls.forEach(e=>{if("op_mini"===e&&void 0===s.browser_support[e])return void o.push("op_mini all");const t=s.browser_support[e];"string"==typeof t&&_s.test(t)?o.push(`${e} < ${s.browser_support[e]}`):o.push(`${e} >= 1`)}),o}const _s=/^[0-9|.]+$/;function formatPolyfillableFeature(s){const o=getUnsupportedBrowsersByFeature(s);if(s[Os]||s[Ps]){let e=s.id;return e=s.insertBefore?`before-${e}`:`after-${e}`,{browsers:o,vendors_implementations:s.vendors_implementations,plugin:s[$s],id:e,stage:6}}return{browsers:o,vendors_implementations:s.vendors_implementations,plugin:As.get(s.id),id:s.id,stage:s.stage}}function formatStagedFeature(s,o,e,t,r,i){let a,c;return a=getOptionsForBrowsersByFeature(s,e,r,i),a=t?Object.assign({},a,t,featureOptions(o,e.id)):Object.assign({},a,featureOptions(o,e.id)),"progressive-custom-properties"!==e.id&&(a.enableProgressiveCustomProperties=!1),"overflow-wrap-property"===e.id&&"preserve"in a&&(a.method=a.preserve?"copy":"replace"),c=e.plugin.postcss&&"function"==typeof e.plugin?e.plugin(a):e.plugin&&e.plugin.default&&"function"==typeof e.plugin.default&&e.plugin.default.postcss?e.plugin.default(a):e.plugin,{browsers:e.browsers,vendors_implementations:e.vendors_implementations,plugin:c,pluginOptions:a,id:e.id}}function featureOptions(s,o){if(!(o in s))return;const e=s[o];return Array.isArray(e)?e[1]:e}function intOrZero(s){const o=parseInt(s,10);return Number.isNaN(o)?0:o}const Is=new Set(["progressive-custom-properties"]);function listFeatures(s,o,t,r){const i=Object(o.features),a="enableClientSidePolyfills"in o&&o.enableClientSidePolyfills,c=Object(o.insertBefore),p=Object(o.insertAfter),n=o.browsers?void 0:o.env,l=o.browsers,m=clamp(0,intOrZero(o.minimumVendorImplementations),3);m>0&&r.log(`Using features with ${m} or more vendor implementations.`);const u=stageFromOptions(o,r),d=prepareFeaturesList([...s,{id:"progressive-custom-properties"}],c,p).map(s=>formatPolyfillableFeature(s)).filter(s=>!!Is.has(s.id)||(0===m||(!(!s[Os]&&!s[Ps])||(m<=s.vendors_implementations||(!0===featureEnabledByOptions(i,s.id)?(r.log(`- '${s.id}' enabled manually even when it lacks the required interop (${s.vendors_implementations} out of ${m}).`),!0):(r.log(`- '${s.id}' disabled because it lacks the required interop (${s.vendors_implementations} out of ${m}).`),!1)))))),f=e(l,{env:n,ignoreUnknownVersions:!0}).filter(s=>Ls.includes(s.split(" ")[0]));return d.filter(s=>{if(Is.has(s.id))return!0;const o=s.stage>=u,e=a||!Fs.includes(s.id),t=featureEnabledByOptions(i,s.id),c=!1===t,p=!0===t||o&&e;return c?r.log(`- '${s.id}' disabled manually`):o?e||r.log(`- '${s.id}' disabled because 'enableClientSidePolyfills' is 'false'.`):p?r.log(`- '${s.id}' enabled manually even when it lacks the required stage (${s.stage} out of ${u}).`):r.log(`- '${s.id}' disabled because it lacks the required stage (${s.stage} out of ${u}).`),!c&&p}).map(s=>formatStagedFeature(f,i,s,t,o,r)).filter(s=>{if(Is.has(s.id))return!0;const o=featureEnabledByOptions(i,s.id);if(!0===o||!1===o)return o;const t=e(s.browsers,{ignoreUnknownVersions:!0}),a=f.filter(s=>t.some(o=>o===s));return a.length>0?r.log(`- '${s.id}' enabled for:\n ${a.join("\n ")}`):r.log(`- '${s.id}' disabled because all targeted browsers support it.`),a.length>0})}function featureEnabledByOptions(s,o){if(!(o in s))return"auto";const e=s[o];return Array.isArray(e)?!0===e[0]||!1!==e[0]&&"auto":Boolean(e)}class Logger{constructor(){this.logs=[]}log(s){this.logs.push(s)}resetLogger(){this.logs.length=0}emitLogs(s){s&&s.warn(this.logs.join("\n")),this.resetLogger()}}var Es=[{packageName:"css-blank-pseudo",id:"blank-pseudo-class",importName:"postcssBlankPseudo"},{packageName:"css-has-pseudo",id:"has-pseudo-class",importName:"postcssHasPseudo"},{packageName:"css-prefers-color-scheme",id:"prefers-color-scheme-query",importName:"postcssPrefersColorScheme"},{packageName:"postcss-attribute-case-insensitive",id:"case-insensitive-attributes",importName:"postcssAttributeCaseInsensitive"},{packageName:"postcss-clamp",id:"clamp",importName:"postcssClamp"},{packageName:"@csstools/postcss-alpha-function",id:"alpha-function",importName:"postcssAlphaFunction"},{packageName:"@csstools/postcss-color-mix-variadic-function-arguments",id:"color-mix-variadic-function-arguments",importName:"postcssColorMixVariadicFunctionArguments"},{packageName:"@csstools/postcss-color-mix-function",id:"color-mix",importName:"postcssColorMixFunction"},{packageName:"@csstools/postcss-color-function",id:"color-function",importName:"postcssColorFunction"},{packageName:"@csstools/postcss-color-function-display-p3-linear",id:"color-function-display-p3-linear",importName:"postcssColorFunctionDisplayP3Linear"},{packageName:"postcss-color-functional-notation",id:"color-functional-notation",importName:"postcssColorFunctionalNotation"},{packageName:"postcss-color-hex-alpha",id:"hexadecimal-alpha-notation",importName:"postcssColorHexAlpha"},{packageName:"@csstools/postcss-content-alt-text",id:"content-alt-text",importName:"postcssContentAltText"},{packageName:"postcss-color-rebeccapurple",id:"rebeccapurple-color",importName:"postcssColorRebeccapurple"},{packageName:"@csstools/postcss-contrast-color-function",id:"contrast-color-function",importName:"postcssContrastColorFunction"},{packageName:"postcss-custom-media",id:"custom-media-queries",importName:"postcssCustomMedia"},{packageName:"postcss-custom-properties",id:"custom-properties",importName:"postcssCustomProperties"},{packageName:"postcss-custom-selectors",id:"custom-selectors",importName:"postcssCustomSelectors"},{packageName:"postcss-dir-pseudo-class",id:"dir-pseudo-class",importName:"postcssDirPseudoClass"},{packageName:"postcss-double-position-gradients",id:"double-position-gradients",importName:"postcssDoublePositionGradients"},{packageName:"@csstools/postcss-exponential-functions",id:"exponential-functions",importName:"postcssExponentialFunctions"},{packageName:"postcss-focus-visible",id:"focus-visible-pseudo-class",importName:"postcssFocusVisible"},{packageName:"postcss-focus-within",id:"focus-within-pseudo-class",importName:"postcssFocusWithin"},{packageName:"@csstools/postcss-font-format-keywords",id:"font-format-keywords",importName:"postcssFontFormatKeywords"},{packageName:"postcss-font-variant",id:"font-variant-property",importName:"postcssFontVariant"},{packageName:"@csstools/postcss-font-width-property",id:"font-width-property",importName:"postcssFontWidthProperty"},{packageName:"@csstools/postcss-gamut-mapping",id:"gamut-mapping",importName:"postcssGamutMapping"},{packageName:"postcss-gap-properties",id:"gap-properties",importName:"postcssGapProperties"},{packageName:"@csstools/postcss-gradients-interpolation-method",id:"gradients-interpolation-method",importName:"postcssGradientsInterpolationMethod"},{packageName:"@csstools/postcss-hwb-function",id:"hwb-function",importName:"postcssHWBFunction"},{packageName:"@csstools/postcss-ic-unit",id:"ic-unit",importName:"postcssICUnit"},{packageName:"postcss-image-set-function",id:"image-set-function",importName:"postcssImageSetFunction"},{packageName:"@csstools/postcss-initial",id:"all-property",importName:"postcssInitial"},{packageName:"@csstools/postcss-is-pseudo-class",id:"is-pseudo-class",importName:"postcssIsPseudoClass"},{packageName:"@csstools/postcss-scope-pseudo-class",id:"scope-pseudo-class",importName:"postcssScopePseudoClass"},{packageName:"postcss-lab-function",id:"lab-function",importName:"postcssLabFunction"},{packageName:"@csstools/postcss-light-dark-function",id:"light-dark-function",importName:"postcssLightDarkFunction"},{packageName:"postcss-logical",id:"logical-properties-and-values",importName:"postcssLogical"},{packageName:"@csstools/postcss-logical-float-and-clear",id:"float-clear-logical-values",importName:"postcssLogicalFloatAndClear"},{packageName:"@csstools/postcss-logical-overflow",id:"logical-overflow",importName:"postcssLogicalOverflow"},{packageName:"@csstools/postcss-logical-overscroll-behavior",id:"logical-overscroll-behavior",importName:"postcssLogicalOverscrollBehavor"},{packageName:"@csstools/postcss-logical-resize",id:"logical-resize",importName:"postcssLogicalResize"},{packageName:"@csstools/postcss-logical-viewport-units",id:"logical-viewport-units",importName:"postcssLogicalViewportUnits"},{packageName:"@csstools/postcss-media-minmax",id:"media-query-ranges",importName:"postcssMediaMinmax"},{packageName:"@csstools/postcss-media-queries-aspect-ratio-number-values",id:"media-queries-aspect-ratio-number-values",importName:"postcssMediaQueriesAspectRatioNumberValues"},{packageName:"@csstools/postcss-mixins",id:"mixins",importName:"postcssMixins"},{packageName:"postcss-nesting",id:"nesting-rules",importName:"postcssNesting"},{packageName:"@csstools/postcss-normalize-display-values",id:"display-two-values",importName:"postcssNormalizeDisplayValues"},{packageName:"@csstools/postcss-oklab-function",id:"oklab-function",importName:"postcssOKLabFunction"},{packageName:"@csstools/postcss-relative-color-syntax",id:"relative-color-syntax",importName:"postcssRelativeColorSyntax"},{packageName:"postcss-opacity-percentage",id:"opacity-percentage",importName:"postcssOpacityPercentage"},{packageName:"postcss-overflow-shorthand",id:"overflow-property",importName:"postcssOverflowShorthand"},{packageName:"postcss-page-break",id:"break-properties",importName:"postcssPageBreak"},{packageName:"@csstools/postcss-position-area-property",id:"position-area-property",importName:"postcssPositionAreaProperty"},{packageName:"postcss-place",id:"place-properties",importName:"postcssPlace"},{packageName:"postcss-pseudo-class-any-link",id:"any-link-pseudo-class",importName:"postcssPseudoClassAnyLink"},{packageName:"postcss-replace-overflow-wrap",id:"overflow-wrap-property",importName:"postcssReplaceOverflowWrap"},{packageName:"postcss-selector-not",id:"not-pseudo-class",importName:"postcssSelectorNot"},{packageName:"@csstools/postcss-stepped-value-functions",id:"stepped-value-functions",importName:"postcssSteppedValueFunctions"},{packageName:"@csstools/postcss-system-ui-font-family",id:"system-ui-font-family",importName:"postcssSystemUIFontFamily"},{packageName:"@csstools/postcss-unset-value",id:"unset-value",importName:"postcssUnsetValue"},{packageName:"@csstools/postcss-cascade-layers",id:"cascade-layers",importName:"postcssCascadeLayers"},{packageName:"@csstools/postcss-trigonometric-functions",id:"trigonometric-functions",importName:"postcssTrigonometricFunctions"},{packageName:"@csstools/postcss-nested-calc",id:"nested-calc",importName:"postcssNestedCalc"},{packageName:"@csstools/postcss-text-decoration-shorthand",id:"text-decoration-shorthand",importName:"postcssTextDecorationShorthand"},{packageName:"@csstools/postcss-sign-functions",id:"sign-functions",importName:"postcssSignFunctions"},{packageName:"@csstools/postcss-random-function",id:"random-function",importName:"postcssRandomFunction"},{packageName:"@csstools/postcss-property-rule-prelude-list",id:"property-rule-prelude-list",importName:"postcssPropertyRulePreludeList"},{packageName:"@csstools/postcss-syntax-descriptor-syntax-production",id:"syntax-descriptor-syntax-production",importName:"postcssSyntaxDescriptorSyntaxProduction"},{packageName:"@csstools/postcss-image-function",id:"image-function",importName:"postcssImageFunction"},{packageName:"@csstools/postcss-container-rule-prelude-list",id:"container-rule-prelude-list",importName:"postcssContainerRulePreludeList"},{packageName:"@csstools/postcss-fit-tolerance-property",id:"fit-tolerance-property",importName:"postcssFitToleranceProperty"},{packageName:"@csstools/postcss-property-rule-optional-descriptors",id:"property-rule-optional-descriptors",importName:"postcssPropertyRuleOptionalDescriptors"},{packageName:"@csstools/postcss-progressive-custom-properties",id:"progressive-custom-properties",importName:"postcssProgressiveCustomProperties",omitTypedOptions:!0,omitDocs:!0}];function getPackageNamesToIds(){const s={};return Es.forEach(o=>{s[o.packageName]=o.id}),s}function pluginIdHelp(s,o,e){const t=Es.map(s=>s.id),r=Es.map(s=>s.packageName),i=getPackageNamesToIds();s.forEach(s=>{if(t.includes(s))return;const a=[...t.map(o=>[o,levenshteinDistance(s,o)]),...r.map(o=>[i[o],levenshteinDistance(s,o)])].sort((s,o)=>s[1]-o[1]).filter(s=>s[1]<10),c=new Set;for(let s=0;s=3));s++);if(!c.size)return void o.warn(e,`Unknown feature: "${s}", see the list of features https://github.com/csstools/postcss-plugins/blob/main/plugin-packs/postcss-preset-env/FEATURES.md`);let p='"';p+=Array.from(c).join('", "'),p+='"',o.warn(e,`Unknown feature: "${s}", did you mean one of: ${p}`)})}function levenshteinDistance(s,o){if(!s.length)return o.length;if(!o.length)return s.length;const e=[];for(let t=0;t<=o.length;t++){e[t]=[t];for(let r=1;r<=s.length;r++)e[t][r]=0===t?r:Math.min(e[t-1][r]+1,e[t][r-1]+1,e[t-1][r-1]+(s[r-1]===o[t-1]?0:1))}return e[o.length][s.length]}const creator=e=>{const t=new Logger,r=Object(e),i=Object.keys(Object(r.features)),a=r.browsers?void 0:r.env,c=r.browsers,p=initializeSharedOptions(r),n=listFeatures(o,r,p,t),l=n.map(s=>s.plugin);!1!==r.autoprefixer&&l.push(s(Object.assign({env:a,overrideBrowserslist:c},r.autoprefixer))),logFeaturesList(n,r,t);const internalPlugin=()=>({postcssPlugin:"postcss-preset-env",OnceExit(s,{result:o}){pluginIdHelp(i,s,o),r.debug&&t.emitLogs(o),t.resetLogger()}});return internalPlugin.postcss=!0,{postcssPlugin:"postcss-preset-env",plugins:[...l,internalPlugin()]}};creator.postcss=!0;export{creator as default,creator as"module.exports"}; +import s from"autoprefixer";import o from"cssdb";import e from"browserslist";import t from"@csstools/postcss-initial";import r from"@csstools/postcss-alpha-function";import i from"postcss-pseudo-class-any-link";import a from"css-blank-pseudo";import c from"postcss-page-break";import p from"@csstools/postcss-cascade-layers";import n from"postcss-attribute-case-insensitive";import l from"postcss-clamp";import m from"@csstools/postcss-color-function";import u from"@csstools/postcss-color-function-display-p3-linear";import d from"postcss-color-functional-notation";import f from"@csstools/postcss-color-mix-function";import g from"@csstools/postcss-color-mix-variadic-function-arguments";import h from"@csstools/postcss-container-rule-prelude-list";import N from"@csstools/postcss-content-alt-text";import b from"@csstools/postcss-contrast-color-function";import y from"@csstools/postcss-custom-functions";import v from"postcss-custom-media";import k from"postcss-custom-properties";import w from"postcss-custom-selectors";import x from"postcss-dir-pseudo-class";import F from"@csstools/postcss-normalize-display-values";import O from"postcss-double-position-gradients";import P from"@csstools/postcss-exponential-functions";import C from"@csstools/postcss-fit-tolerance-property";import $ from"@csstools/postcss-logical-float-and-clear";import S from"postcss-focus-visible";import A from"postcss-focus-within";import L from"@csstools/postcss-font-format-keywords";import _ from"postcss-font-variant";import I from"@csstools/postcss-font-width-property";import E from"@csstools/postcss-gamut-mapping";import B from"postcss-gap-properties";import q from"@csstools/postcss-gradients-interpolation-method";import M from"css-has-pseudo";import D from"postcss-color-hex-alpha";import j from"@csstools/postcss-hwb-function";import z from"@csstools/postcss-ic-unit";import R from"@csstools/postcss-image-function";import U from"postcss-image-set-function";import T from"@csstools/postcss-is-pseudo-class";import V from"postcss-lab-function";import H from"@csstools/postcss-light-dark-function";import W from"@csstools/postcss-logical-overflow";import G from"@csstools/postcss-logical-overscroll-behavior";import K from"postcss-logical";import Z from"@csstools/postcss-logical-resize";import Q from"@csstools/postcss-logical-viewport-units";import J from"@csstools/postcss-media-queries-aspect-ratio-number-values";import X from"@csstools/postcss-media-minmax";import Y from"@csstools/postcss-mixins";import ss from"@csstools/postcss-nested-calc";import os from"postcss-nesting";import es from"postcss-selector-not";import ts from"@csstools/postcss-oklab-function";import rs from"postcss-opacity-percentage";import is from"postcss-overflow-shorthand";import as from"postcss-replace-overflow-wrap";import cs from"postcss-place";import ps from"@csstools/postcss-position-area-property";import ns from"css-prefers-color-scheme";import ls from"@csstools/postcss-progressive-custom-properties";import ms from"@csstools/postcss-property-rule-optional-descriptors";import us from"@csstools/postcss-property-rule-prelude-list";import ds from"@csstools/postcss-random-function";import fs from"postcss-color-rebeccapurple";import gs from"@csstools/postcss-relative-color-syntax";import hs from"@csstools/postcss-scope-pseudo-class";import Ns from"@csstools/postcss-sign-functions";import bs from"@csstools/postcss-stepped-value-functions";import ys from"@csstools/postcss-syntax-descriptor-syntax-production";import vs from"@csstools/postcss-system-ui-font-family";import ks from"@csstools/postcss-text-decoration-shorthand";import ws from"@csstools/postcss-trigonometric-functions";import xs from"@csstools/postcss-unset-value";const Fs={"blank-pseudo-class":"https://github.com/csstools/postcss-plugins/blob/main/plugins/css-blank-pseudo/README.md#browser","focus-visible-pseudo-class":"https://github.com/WICG/focus-visible","focus-within-pseudo-class":"https://github.com/csstools/postcss-plugins/blob/main/plugins/postcss-focus-within/README.md#browser","has-pseudo-class":"https://github.com/csstools/postcss-plugins/blob/main/plugins/css-has-pseudo/README.md#browser","prefers-color-scheme-query":"https://github.com/csstools/postcss-plugins/blob/main/plugins/css-prefers-color-scheme/README.md#browser"},Os=["blank-pseudo-class","focus-visible-pseudo-class","focus-within-pseudo-class","has-pseudo-class","prefers-color-scheme-query"];function logFeaturesList(s,o,e){if(o.debug){e.log("Enabling the following feature(s):");const t=[],r=[];!1!==o.autoprefixer&&r.push(" autoprefixer"),s.forEach(s=>{s.id.startsWith("before")||s.id.startsWith("after")?r.push(` ${s.id} (injected via options)`):r.push(` ${s.id}`),void 0!==Fs[s.id]&&t.push(s.id)}),r.sort((s,o)=>s.localeCompare(o)),t.sort((s,o)=>s.localeCompare(o)),r.forEach(s=>e.log(s)),t.length&&(e.log("These feature(s) need a browser library to work:"),t.forEach(s=>e.log(` ${s}: ${Fs[s]}`)))}}function initializeSharedOptions(s){if("preserve"in s){const o={};return o.preserve=s.preserve,o}return!1}function clamp(s,o,e){return Math.max(s,Math.min(o,e))}function stageFromOptions(s,o){let e=2;if(void 0===s.stage)return o.log("Using features from Stage 2 (default)."),e;if(!1===s.stage)e=5;else{let o=parseInt(s.stage,10);Number.isNaN(o)&&(o=0),e=clamp(0,o,5)}return 5===e?o.log('Stage has been disabled, features will be handled via the "features" option.'):o.log(`Using features from Stage ${e}.`),e}const Ps=Symbol("insertBefore"),Cs=Symbol("insertAfter"),$s=Symbol("insertOrder"),Ss=Symbol("plugin");function getTransformedInsertions(s,o,e){if("insertBefore"!==e&&"insertAfter"!==e)return[];const t="insertBefore"===e?Ps:Cs,r=[];for(const e in o){if(!Object.hasOwnProperty.call(o,e))continue;if(!s.find(s=>s.id===e))continue;let i=o[e];Array.isArray(i)||(i=[i]);for(let s=0;sfeatureIsInsertedOrHasAPlugin(s)).sort((s,o)=>featureIsLess(s,o))}function getOptionsForBrowsersByFeature(s,o,e,t){switch(o.id){case"is-pseudo-class":return{onComplexSelector:"warning"};case"any-link-pseudo-class":if(s.find(s=>s.startsWith("ie ")||"edge 12"===s||"edge 13"===s||"edge 14"===s||"edge 15"===s||"edge 16"===s||"edge 17"===s||"edge 18"===s))return t.log("- 'any-link-pseudo-class' setting 'subFeatures: { areaHrefNeedsFixing: true }' due to lack of browser support for area[href] in Edge and IE."),{subFeatures:{areaHrefNeedsFixing:!0}};return{};case"logical-properties-and-values":case"float-clear-logical-values":case"logical-resize":case"logical-viewport-units":case"logical-overflow":case"logical-overscroll-behavior":return"logical"in e?e.logical:{};default:return{}}}const _s=["and_chr","and_ff","android","chrome","edge","firefox","ie","ios_saf","op_mini","op_mob","opera","safari","samsung"];function getUnsupportedBrowsersByFeature(s){if(!s)return[];if("position-area-property"===s.id)return["chrome 125","chrome 126","chrome 127","chrome 128","edge 125","edge 126","edge 127","edge 128","and_chr 125","and_chr 126","and_chr 127","and_chr 128","android 125","android 126","android 127","android 128","samsung 27","opera 111","opera 112","opera 113","opera 114","op_mob 83","op_mob 84","op_mob 85"];if(!("browser_support"in s))return["> 0%"];const o=[];return _s.forEach(e=>{if("op_mini"===e&&void 0===s.browser_support[e])return void o.push("op_mini all");const t=s.browser_support[e];"string"==typeof t&&Is.test(t)?o.push(`${e} < ${s.browser_support[e]}`):o.push(`${e} >= 1`)}),o}const Is=/^[0-9|.]+$/;function formatPolyfillableFeature(s){const o=getUnsupportedBrowsersByFeature(s);if(s[Ps]||s[Cs]){let e=s.id;return e=s.insertBefore?`before-${e}`:`after-${e}`,{browsers:o,vendors_implementations:s.vendors_implementations,plugin:s[Ss],id:e,stage:6}}return{browsers:o,vendors_implementations:s.vendors_implementations,plugin:Ls.get(s.id),id:s.id,stage:s.stage}}function formatStagedFeature(s,o,e,t,r,i){let a,c;return a=getOptionsForBrowsersByFeature(s,e,r,i),a=t?Object.assign({},a,t,featureOptions(o,e.id)):Object.assign({},a,featureOptions(o,e.id)),"progressive-custom-properties"!==e.id&&(a.enableProgressiveCustomProperties=!1),"overflow-wrap-property"===e.id&&"preserve"in a&&(a.method=a.preserve?"copy":"replace"),c=e.plugin.postcss&&"function"==typeof e.plugin?e.plugin(a):e.plugin&&e.plugin.default&&"function"==typeof e.plugin.default&&e.plugin.default.postcss?e.plugin.default(a):e.plugin,{browsers:e.browsers,vendors_implementations:e.vendors_implementations,plugin:c,pluginOptions:a,id:e.id}}function featureOptions(s,o){if(!(o in s))return;const e=s[o];return Array.isArray(e)?e[1]:e}function intOrZero(s){const o=parseInt(s,10);return Number.isNaN(o)?0:o}const Es=new Set(["progressive-custom-properties"]);function listFeatures(s,o,t,r){const i=Object(o.features),a="enableClientSidePolyfills"in o&&o.enableClientSidePolyfills,c=Object(o.insertBefore),p=Object(o.insertAfter),n=o.browsers?void 0:o.env,l=o.browsers,m=clamp(0,intOrZero(o.minimumVendorImplementations),3);m>0&&r.log(`Using features with ${m} or more vendor implementations.`);const u=stageFromOptions(o,r),d=prepareFeaturesList([...s,{id:"progressive-custom-properties"}],c,p).map(s=>formatPolyfillableFeature(s)).filter(s=>!!Es.has(s.id)||(0===m||(!(!s[Ps]&&!s[Cs])||(m<=s.vendors_implementations||(!0===featureEnabledByOptions(i,s.id)?(r.log(`- '${s.id}' enabled manually even when it lacks the required interop (${s.vendors_implementations} out of ${m}).`),!0):(r.log(`- '${s.id}' disabled because it lacks the required interop (${s.vendors_implementations} out of ${m}).`),!1)))))),f=e(l,{env:n,ignoreUnknownVersions:!0}).filter(s=>_s.includes(s.split(" ")[0]));return d.filter(s=>{if(Es.has(s.id))return!0;const o=s.stage>=u,e=a||!Os.includes(s.id),t=featureEnabledByOptions(i,s.id),c=!1===t,p=!0===t||o&&e;return c?r.log(`- '${s.id}' disabled manually`):o?e||r.log(`- '${s.id}' disabled because 'enableClientSidePolyfills' is 'false'.`):p?r.log(`- '${s.id}' enabled manually even when it lacks the required stage (${s.stage} out of ${u}).`):r.log(`- '${s.id}' disabled because it lacks the required stage (${s.stage} out of ${u}).`),!c&&p}).map(s=>formatStagedFeature(f,i,s,t,o,r)).filter(s=>{if(Es.has(s.id))return!0;const o=featureEnabledByOptions(i,s.id);if(!0===o||!1===o)return o;const t=e(s.browsers,{ignoreUnknownVersions:!0}),a=f.filter(s=>t.some(o=>o===s));return a.length>0?r.log(`- '${s.id}' enabled for:\n ${a.join("\n ")}`):r.log(`- '${s.id}' disabled because all targeted browsers support it.`),a.length>0})}function featureEnabledByOptions(s,o){if(!(o in s))return"auto";const e=s[o];return Array.isArray(e)?!0===e[0]||!1!==e[0]&&"auto":Boolean(e)}class Logger{constructor(){this.logs=[]}log(s){this.logs.push(s)}resetLogger(){this.logs.length=0}emitLogs(s){s&&s.warn(this.logs.join("\n")),this.resetLogger()}}var Bs=[{packageName:"css-blank-pseudo",id:"blank-pseudo-class",importName:"postcssBlankPseudo"},{packageName:"css-has-pseudo",id:"has-pseudo-class",importName:"postcssHasPseudo"},{packageName:"css-prefers-color-scheme",id:"prefers-color-scheme-query",importName:"postcssPrefersColorScheme"},{packageName:"postcss-attribute-case-insensitive",id:"case-insensitive-attributes",importName:"postcssAttributeCaseInsensitive"},{packageName:"postcss-clamp",id:"clamp",importName:"postcssClamp"},{packageName:"@csstools/postcss-alpha-function",id:"alpha-function",importName:"postcssAlphaFunction"},{packageName:"@csstools/postcss-color-mix-variadic-function-arguments",id:"color-mix-variadic-function-arguments",importName:"postcssColorMixVariadicFunctionArguments"},{packageName:"@csstools/postcss-color-mix-function",id:"color-mix",importName:"postcssColorMixFunction"},{packageName:"@csstools/postcss-color-function",id:"color-function",importName:"postcssColorFunction"},{packageName:"@csstools/postcss-color-function-display-p3-linear",id:"color-function-display-p3-linear",importName:"postcssColorFunctionDisplayP3Linear"},{packageName:"postcss-color-functional-notation",id:"color-functional-notation",importName:"postcssColorFunctionalNotation"},{packageName:"postcss-color-hex-alpha",id:"hexadecimal-alpha-notation",importName:"postcssColorHexAlpha"},{packageName:"@csstools/postcss-content-alt-text",id:"content-alt-text",importName:"postcssContentAltText"},{packageName:"postcss-color-rebeccapurple",id:"rebeccapurple-color",importName:"postcssColorRebeccapurple"},{packageName:"@csstools/postcss-contrast-color-function",id:"contrast-color-function",importName:"postcssContrastColorFunction"},{packageName:"postcss-custom-media",id:"custom-media-queries",importName:"postcssCustomMedia"},{packageName:"postcss-custom-properties",id:"custom-properties",importName:"postcssCustomProperties"},{packageName:"postcss-custom-selectors",id:"custom-selectors",importName:"postcssCustomSelectors"},{packageName:"postcss-dir-pseudo-class",id:"dir-pseudo-class",importName:"postcssDirPseudoClass"},{packageName:"postcss-double-position-gradients",id:"double-position-gradients",importName:"postcssDoublePositionGradients"},{packageName:"@csstools/postcss-exponential-functions",id:"exponential-functions",importName:"postcssExponentialFunctions"},{packageName:"postcss-focus-visible",id:"focus-visible-pseudo-class",importName:"postcssFocusVisible"},{packageName:"postcss-focus-within",id:"focus-within-pseudo-class",importName:"postcssFocusWithin"},{packageName:"@csstools/postcss-font-format-keywords",id:"font-format-keywords",importName:"postcssFontFormatKeywords"},{packageName:"postcss-font-variant",id:"font-variant-property",importName:"postcssFontVariant"},{packageName:"@csstools/postcss-font-width-property",id:"font-width-property",importName:"postcssFontWidthProperty"},{packageName:"@csstools/postcss-gamut-mapping",id:"gamut-mapping",importName:"postcssGamutMapping"},{packageName:"postcss-gap-properties",id:"gap-properties",importName:"postcssGapProperties"},{packageName:"@csstools/postcss-gradients-interpolation-method",id:"gradients-interpolation-method",importName:"postcssGradientsInterpolationMethod"},{packageName:"@csstools/postcss-hwb-function",id:"hwb-function",importName:"postcssHWBFunction"},{packageName:"@csstools/postcss-ic-unit",id:"ic-unit",importName:"postcssICUnit"},{packageName:"postcss-image-set-function",id:"image-set-function",importName:"postcssImageSetFunction"},{packageName:"@csstools/postcss-initial",id:"all-property",importName:"postcssInitial"},{packageName:"@csstools/postcss-is-pseudo-class",id:"is-pseudo-class",importName:"postcssIsPseudoClass"},{packageName:"@csstools/postcss-scope-pseudo-class",id:"scope-pseudo-class",importName:"postcssScopePseudoClass"},{packageName:"postcss-lab-function",id:"lab-function",importName:"postcssLabFunction"},{packageName:"@csstools/postcss-light-dark-function",id:"light-dark-function",importName:"postcssLightDarkFunction"},{packageName:"postcss-logical",id:"logical-properties-and-values",importName:"postcssLogical"},{packageName:"@csstools/postcss-logical-float-and-clear",id:"float-clear-logical-values",importName:"postcssLogicalFloatAndClear"},{packageName:"@csstools/postcss-logical-overflow",id:"logical-overflow",importName:"postcssLogicalOverflow"},{packageName:"@csstools/postcss-logical-overscroll-behavior",id:"logical-overscroll-behavior",importName:"postcssLogicalOverscrollBehavor"},{packageName:"@csstools/postcss-logical-resize",id:"logical-resize",importName:"postcssLogicalResize"},{packageName:"@csstools/postcss-logical-viewport-units",id:"logical-viewport-units",importName:"postcssLogicalViewportUnits"},{packageName:"@csstools/postcss-media-minmax",id:"media-query-ranges",importName:"postcssMediaMinmax"},{packageName:"@csstools/postcss-media-queries-aspect-ratio-number-values",id:"media-queries-aspect-ratio-number-values",importName:"postcssMediaQueriesAspectRatioNumberValues"},{packageName:"@csstools/postcss-mixins",id:"mixins",importName:"postcssMixins"},{packageName:"postcss-nesting",id:"nesting-rules",importName:"postcssNesting"},{packageName:"@csstools/postcss-normalize-display-values",id:"display-two-values",importName:"postcssNormalizeDisplayValues"},{packageName:"@csstools/postcss-oklab-function",id:"oklab-function",importName:"postcssOKLabFunction"},{packageName:"@csstools/postcss-relative-color-syntax",id:"relative-color-syntax",importName:"postcssRelativeColorSyntax"},{packageName:"postcss-opacity-percentage",id:"opacity-percentage",importName:"postcssOpacityPercentage"},{packageName:"postcss-overflow-shorthand",id:"overflow-property",importName:"postcssOverflowShorthand"},{packageName:"postcss-page-break",id:"break-properties",importName:"postcssPageBreak"},{packageName:"@csstools/postcss-position-area-property",id:"position-area-property",importName:"postcssPositionAreaProperty"},{packageName:"postcss-place",id:"place-properties",importName:"postcssPlace"},{packageName:"postcss-pseudo-class-any-link",id:"any-link-pseudo-class",importName:"postcssPseudoClassAnyLink"},{packageName:"postcss-replace-overflow-wrap",id:"overflow-wrap-property",importName:"postcssReplaceOverflowWrap"},{packageName:"postcss-selector-not",id:"not-pseudo-class",importName:"postcssSelectorNot"},{packageName:"@csstools/postcss-stepped-value-functions",id:"stepped-value-functions",importName:"postcssSteppedValueFunctions"},{packageName:"@csstools/postcss-system-ui-font-family",id:"system-ui-font-family",importName:"postcssSystemUIFontFamily"},{packageName:"@csstools/postcss-unset-value",id:"unset-value",importName:"postcssUnsetValue"},{packageName:"@csstools/postcss-cascade-layers",id:"cascade-layers",importName:"postcssCascadeLayers"},{packageName:"@csstools/postcss-trigonometric-functions",id:"trigonometric-functions",importName:"postcssTrigonometricFunctions"},{packageName:"@csstools/postcss-nested-calc",id:"nested-calc",importName:"postcssNestedCalc"},{packageName:"@csstools/postcss-text-decoration-shorthand",id:"text-decoration-shorthand",importName:"postcssTextDecorationShorthand"},{packageName:"@csstools/postcss-sign-functions",id:"sign-functions",importName:"postcssSignFunctions"},{packageName:"@csstools/postcss-random-function",id:"random-function",importName:"postcssRandomFunction"},{packageName:"@csstools/postcss-property-rule-prelude-list",id:"property-rule-prelude-list",importName:"postcssPropertyRulePreludeList"},{packageName:"@csstools/postcss-syntax-descriptor-syntax-production",id:"syntax-descriptor-syntax-production",importName:"postcssSyntaxDescriptorSyntaxProduction"},{packageName:"@csstools/postcss-image-function",id:"image-function",importName:"postcssImageFunction"},{packageName:"@csstools/postcss-container-rule-prelude-list",id:"container-rule-prelude-list",importName:"postcssContainerRulePreludeList"},{packageName:"@csstools/postcss-fit-tolerance-property",id:"fit-tolerance-property",importName:"postcssFitToleranceProperty"},{packageName:"@csstools/postcss-property-rule-optional-descriptors",id:"property-rule-optional-descriptors",importName:"postcssPropertyRuleOptionalDescriptors"},{packageName:"@csstools/postcss-custom-functions",id:"custom-functions",importName:"postcssCustomFunctions"},{packageName:"@csstools/postcss-progressive-custom-properties",id:"progressive-custom-properties",importName:"postcssProgressiveCustomProperties",omitTypedOptions:!0,omitDocs:!0}];function getPackageNamesToIds(){const s={};return Bs.forEach(o=>{s[o.packageName]=o.id}),s}function pluginIdHelp(s,o,e){const t=Bs.map(s=>s.id),r=Bs.map(s=>s.packageName),i=getPackageNamesToIds();s.forEach(s=>{if(t.includes(s))return;const a=[...t.map(o=>[o,levenshteinDistance(s,o)]),...r.map(o=>[i[o],levenshteinDistance(s,o)])].sort((s,o)=>s[1]-o[1]).filter(s=>s[1]<10),c=new Set;for(let s=0;s=3));s++);if(!c.size)return void o.warn(e,`Unknown feature: "${s}", see the list of features https://github.com/csstools/postcss-plugins/blob/main/plugin-packs/postcss-preset-env/FEATURES.md`);let p='"';p+=Array.from(c).join('", "'),p+='"',o.warn(e,`Unknown feature: "${s}", did you mean one of: ${p}`)})}function levenshteinDistance(s,o){if(!s.length)return o.length;if(!o.length)return s.length;const e=[];for(let t=0;t<=o.length;t++){e[t]=[t];for(let r=1;r<=s.length;r++)e[t][r]=0===t?r:Math.min(e[t-1][r]+1,e[t][r-1]+1,e[t-1][r-1]+(s[r-1]===o[t-1]?0:1))}return e[o.length][s.length]}const creator=e=>{const t=new Logger,r=Object(e),i=Object.keys(Object(r.features)),a=r.browsers?void 0:r.env,c=r.browsers,p=initializeSharedOptions(r),n=listFeatures(o,r,p,t),l=n.map(s=>s.plugin);!1!==r.autoprefixer&&l.push(s(Object.assign({env:a,overrideBrowserslist:c},r.autoprefixer))),logFeaturesList(n,r,t);const internalPlugin=()=>({postcssPlugin:"postcss-preset-env",OnceExit(s,{result:o}){pluginIdHelp(i,s,o),r.debug&&t.emitLogs(o),t.resetLogger()}});return internalPlugin.postcss=!0,{postcssPlugin:"postcss-preset-env",plugins:[...l,internalPlugin()]}};creator.postcss=!0;export{creator as default,creator as"module.exports"}; diff --git a/plugin-packs/postcss-preset-env/package.json b/plugin-packs/postcss-preset-env/package.json index 351abf29d5..96216a3f58 100644 --- a/plugin-packs/postcss-preset-env/package.json +++ b/plugin-packs/postcss-preset-env/package.json @@ -54,6 +54,7 @@ "@csstools/postcss-container-rule-prelude-list": "^1.0.3", "@csstools/postcss-content-alt-text": "^3.0.6", "@csstools/postcss-contrast-color-function": "^3.0.14", + "@csstools/postcss-custom-functions": "^1.0.0", "@csstools/postcss-exponential-functions": "^3.0.8", "@csstools/postcss-fit-tolerance-property": "^1.0.1", "@csstools/postcss-font-format-keywords": "^5.0.0", diff --git a/plugin-packs/postcss-preset-env/scripts/plugins-data.json b/plugin-packs/postcss-preset-env/scripts/plugins-data.json index a160f64731..1239c8af08 100644 --- a/plugin-packs/postcss-preset-env/scripts/plugins-data.json +++ b/plugin-packs/postcss-preset-env/scripts/plugins-data.json @@ -364,6 +364,11 @@ "id": "property-rule-optional-descriptors", "importName": "postcssPropertyRuleOptionalDescriptors" }, + { + "packageName": "@csstools/postcss-custom-functions", + "id": "custom-functions", + "importName": "postcssCustomFunctions" + }, { "packageName": "@csstools/postcss-progressive-custom-properties", "id": "progressive-custom-properties", diff --git a/plugin-packs/postcss-preset-env/src/lib/ids-by-execution-order.mjs b/plugin-packs/postcss-preset-env/src/lib/ids-by-execution-order.mjs index 386921f3a1..8717bc131b 100644 --- a/plugin-packs/postcss-preset-env/src/lib/ids-by-execution-order.mjs +++ b/plugin-packs/postcss-preset-env/src/lib/ids-by-execution-order.mjs @@ -1,6 +1,7 @@ // ids ordered by required execution, then alphabetically export default [ 'mixins', + 'custom-functions', 'custom-media-queries', 'environment-variables', // run environment-variables here to access transpiled custom media params and properties diff --git a/plugin-packs/postcss-preset-env/src/plugins/plugins-by-id.mjs b/plugin-packs/postcss-preset-env/src/plugins/plugins-by-id.mjs index c562a77013..5c3eb496db 100644 --- a/plugin-packs/postcss-preset-env/src/plugins/plugins-by-id.mjs +++ b/plugin-packs/postcss-preset-env/src/plugins/plugins-by-id.mjs @@ -14,6 +14,7 @@ import postcssColorMixVariadicFunctionArguments from '@csstools/postcss-color-mi import postcssContainerRulePreludeList from '@csstools/postcss-container-rule-prelude-list'; import postcssContentAltText from '@csstools/postcss-content-alt-text'; import postcssContrastColorFunction from '@csstools/postcss-contrast-color-function'; +import postcssCustomFunctions from '@csstools/postcss-custom-functions'; import postcssCustomMedia from 'postcss-custom-media'; import postcssCustomProperties from 'postcss-custom-properties'; import postcssCustomSelectors from 'postcss-custom-selectors'; @@ -92,6 +93,7 @@ export const pluginsById = new Map( ['container-rule-prelude-list', postcssContainerRulePreludeList], ['content-alt-text', postcssContentAltText], ['contrast-color-function', postcssContrastColorFunction], + ['custom-functions', postcssCustomFunctions], ['custom-media-queries', postcssCustomMedia], ['custom-properties', postcssCustomProperties], ['custom-selectors', postcssCustomSelectors], diff --git a/plugin-packs/postcss-preset-env/src/plugins/plugins-data.mjs b/plugin-packs/postcss-preset-env/src/plugins/plugins-data.mjs index dd9cb79131..d1755d717c 100644 --- a/plugin-packs/postcss-preset-env/src/plugins/plugins-data.mjs +++ b/plugin-packs/postcss-preset-env/src/plugins/plugins-data.mjs @@ -364,6 +364,11 @@ export default [ 'id': 'property-rule-optional-descriptors', 'importName': 'postcssPropertyRuleOptionalDescriptors', }, + { + 'packageName': '@csstools/postcss-custom-functions', + 'id': 'custom-functions', + 'importName': 'postcssCustomFunctions', + }, { 'packageName': '@csstools/postcss-progressive-custom-properties', 'id': 'progressive-custom-properties', diff --git a/plugin-packs/postcss-preset-env/src/plugins/plugins-options.ts b/plugin-packs/postcss-preset-env/src/plugins/plugins-options.ts index 8daf37f60c..17fd9bc273 100644 --- a/plugin-packs/postcss-preset-env/src/plugins/plugins-options.ts +++ b/plugin-packs/postcss-preset-env/src/plugins/plugins-options.ts @@ -14,6 +14,7 @@ import type { pluginOptions as postcssColorMixVariadicFunctionArgumentsOptions } import type { pluginOptions as postcssContainerRulePreludeListOptions } from '@csstools/postcss-container-rule-prelude-list'; import type { pluginOptions as postcssContentAltTextOptions } from '@csstools/postcss-content-alt-text'; import type { pluginOptions as postcssContrastColorFunctionOptions } from '@csstools/postcss-contrast-color-function'; +import type { pluginOptions as postcssCustomFunctionsOptions } from '@csstools/postcss-custom-functions'; import type { pluginOptions as postcssCustomMediaOptions } from 'postcss-custom-media'; import type { pluginOptions as postcssCustomPropertiesOptions } from 'postcss-custom-properties'; import type { pluginOptions as postcssCustomSelectorsOptions } from 'postcss-custom-selectors'; @@ -107,6 +108,8 @@ export type pluginsOptions = { 'content-alt-text'?: subPluginOptions /** plugin options for "@csstools/postcss-contrast-color-function" */ 'contrast-color-function'?: subPluginOptions + /** plugin options for "@csstools/postcss-custom-functions" */ + 'custom-functions'?: subPluginOptions /** plugin options for "postcss-custom-media" */ 'custom-media-queries'?: subPluginOptions /** plugin options for "postcss-custom-properties" */ diff --git a/plugin-packs/postcss-preset-env/test/_tape.mjs b/plugin-packs/postcss-preset-env/test/_tape.mjs index 384e603a08..56a02a1a4b 100644 --- a/plugin-packs/postcss-preset-env/test/_tape.mjs +++ b/plugin-packs/postcss-preset-env/test/_tape.mjs @@ -450,4 +450,12 @@ postcssTape(plugin)({ }), ], }, + 'postcss-functions': { + message: 'does not clone `@function` rules when generating conditional rules', + options: { + preserve: true, + stage: 0, + browsers: '> 0%', + }, + }, }); diff --git a/plugin-packs/postcss-preset-env/test/postcss-functions.css b/plugin-packs/postcss-preset-env/test/postcss-functions.css new file mode 100644 index 0000000000..e7fdcd9b50 --- /dev/null +++ b/plugin-packs/postcss-preset-env/test/postcss-functions.css @@ -0,0 +1,171 @@ +/* + * `@function` interaction coverage. + * + * A `@function` body accepts conditional group rules such as `@supports` and `@media`. + * Transpilers must nest those rules inside the existing `@function` and never clone the + * `@function` rule into a conditional group rule, as a cloned `@function` with the same + * name overrides the original definition. + * + * Each pair covers a direct assignment to the `result` descriptor and indirection + * through a local custom property. + */ + +@function --color-function() { + result: color(display-p3 0.1 0.1 0.1); +} + +@function --color-function-var() { + --local: color(display-p3 0.1 0.1 0.1); + + result: var(--local); +} + +@function --lab-function() { + result: lab(40% 56.6 39); +} + +@function --lab-function-var() { + --local: lab(40% 56.6 39); + + result: var(--local); +} + +@function --oklab-function() { + result: oklch(60% 0.150 0); +} + +@function --oklab-function-var() { + --local: oklch(60% 0.150 0); + + result: var(--local); +} + +@function --hwb-function() { + result: hwb(0 60% 40% / var(--alpha)); +} + +@function --hwb-function-var() { + --local: hwb(0 60% 40% / var(--alpha)); + + result: var(--local); +} + +@function --color-functional-notation() { + result: rgb(255 0 0 / var(--alpha-50)); +} + +@function --color-functional-notation-var() { + --local: rgb(255 0 0 / var(--alpha-50)); + + result: var(--local); +} + +@function --color-mix-function() { + result: color-mix(in lch, purple 50%, plum 50%); +} + +@function --color-mix-function-var() { + --local: color-mix(in lch, purple 50%, plum 50%); + + result: var(--local); +} + +@function --relative-color-syntax() { + result: rgb(from blue r g b); +} + +@function --relative-color-syntax-var() { + --local: rgb(from blue r g b); + + result: var(--local); +} + +@function --double-position-gradients() { + result: linear-gradient(90deg, black 25% 50%, blue 50% 75%); +} + +@function --double-position-gradients-var() { + --local: linear-gradient(90deg, black 25% 50%, blue 50% 75%); + + result: var(--local); +} + +@function --gradients-interpolation-method() { + result: linear-gradient(in oklch 90deg, black 25% 50%, blue 50% 75%); +} + +@function --gradients-interpolation-method-var() { + --local: linear-gradient(in oklch 90deg, black 25% 50%, blue 50% 75%); + + result: var(--local); +} + +@function --image-function() { + result: image(red); +} + +@function --image-function-var() { + --local: image(red); + + result: var(--local); +} + +@function --image-set-function() { + result: image-set(url(img/test.png) 1x, url(img/test-2x.png) 2x); +} + +@function --image-set-function-var() { + --local: image-set(url(img/test.png) 1x, url(img/test-2x.png) 2x); + + result: var(--local); +} + +@function --ic-unit() { + result: 2ic; +} + +@function --ic-unit-var() { + --local: 2ic; + + result: var(--local); +} + +@function --logical-viewport-units() { + result: 2vi; +} + +@function --logical-viewport-units-var() { + --local: 2vi; + + result: var(--local); +} + +@function --gamut-mapping() { + result: oklch(60% 0.4 0); +} + +@function --gamut-mapping-var() { + --local: oklch(60% 0.4 0); + + result: var(--local); +} + +@function --system-ui-font-family() { + result: system-ui; +} + +@function --system-ui-font-family-var() { + --local: system-ui; + + result: var(--local); +} + +@function --custom-properties() { + result: var(--color-fallback); +} + +@function --custom-properties-var() { + --local: var(--color-fallback); + + result: var(--local); +} diff --git a/plugin-packs/postcss-preset-env/test/postcss-functions.expect.css b/plugin-packs/postcss-preset-env/test/postcss-functions.expect.css new file mode 100644 index 0000000000..0d6f526715 --- /dev/null +++ b/plugin-packs/postcss-preset-env/test/postcss-functions.expect.css @@ -0,0 +1,275 @@ +/* + * `@function` interaction coverage. + * + * A `@function` body accepts conditional group rules such as `@supports` and `@media`. + * Transpilers must nest those rules inside the existing `@function` and never clone the + * `@function` rule into a conditional group rule, as a cloned `@function` with the same + * name overrides the original definition. + * + * Each pair covers a direct assignment to the `result` descriptor and indirection + * through a local custom property. + */ + +@function --color-function() { + result: rgb(26, 26, 26); + result: color(display-p3 0.1 0.1 0.1); +} + +@function --color-function-var() { + --local: rgb(26, 26, 26); + + result: var(--local); + +@supports (color: color(display-p3 0 0 0%)) { + --local: color(display-p3 0.1 0.1 0.1); +} +} + +@function --lab-function() { + result: rgb(179, 35, 35); + result: lab(40% 56.6 39); +} + +@function --lab-function-var() { + --local: rgb(179, 35, 35); + + result: var(--local); + +@supports (color: lab(0% 0 0%)) { + --local: lab(40% 56.6 39); +} +} + +@function --oklab-function() { + result: rgb(197, 84, 124); + result: oklch(60% 0.150 0); +} + +@function --oklab-function-var() { + --local: rgb(197, 84, 124); + + result: var(--local); + +@supports (color: oklab(0% 0 0%)) { + --local: oklch(60% 0.150 0); +} +} + +@function --hwb-function() { + result: rgba(153, 153, 153, var(--alpha)); + +@supports (color: hwb(0 0% 0%)) { + result: hwb(0 60% 40% / var(--alpha)); +} +} + +@function --hwb-function-var() { + --local: rgba(153, 153, 153, var(--alpha)); + + result: var(--local); + +@supports (color: hwb(0 0% 0%)) { + --local: hwb(0 60% 40% / var(--alpha)); +} +} + +@function --color-functional-notation() { + result: rgba(255, 0, 0, var(--alpha-50)); + +@supports (color: rgb(0 0 0 / 0)) { + result: rgb(255 0 0 / var(--alpha-50)); +} +} + +@function --color-functional-notation-var() { + --local: rgba(255, 0, 0, var(--alpha-50)); + + result: var(--local); + +@supports (color: rgb(0 0 0 / 0)) { + --local: rgb(255 0 0 / var(--alpha-50)); +} +} + +@function --color-mix-function() { + result: rgb(175, 92, 174); + result: color-mix(in lch, purple 50%, plum 50%); +} + +@function --color-mix-function-var() { + --local: rgb(175, 92, 174); + + result: var(--local); + +@supports (color: color-mix(in lch, red, blue)) { + --local: color-mix(in lch, purple 50%, plum 50%); +} +} + +@function --relative-color-syntax() { + result: rgb(0, 0, 255); + result: rgb(from blue r g b); +} + +@function --relative-color-syntax-var() { + --local: rgb(0, 0, 255); + + result: var(--local); + +@supports (color: lab(from red l 1 1% / calc(alpha + 0.1))) { + --local: rgb(from blue r g b); +} +} + +@function --double-position-gradients() { + result: linear-gradient(90deg, black 25%,black 50%, blue 50%, blue 75%); + result: linear-gradient(90deg, black 25% 50%, blue 50% 75%); +} + +@function --double-position-gradients-var() { + --local: linear-gradient(90deg, black 25%,black 50%, blue 50%, blue 75%); + + result: var(--local); + +@supports (background: linear-gradient(red 0%, red 0% 1%, red 2%)) { + --local: linear-gradient(90deg, black 25% 50%, blue 50% 75%); +} +} + +@function --gradients-interpolation-method() { + result: linear-gradient(90deg, rgb(0, 0, 0) 25%, rgb(0, 0, 0) 50%, rgb(0, 0, 255) 50%, rgb(0, 0, 255) 75%); + result: linear-gradient(in oklch 90deg, black 25% 50%, blue 50% 75%); +} + +@function --gradients-interpolation-method-var() { + --local: linear-gradient(90deg, rgb(0, 0, 0) 25%, rgb(0, 0, 0) 50%, rgb(0, 0, 255) 50%, rgb(0, 0, 255) 75%); + + result: var(--local); + +@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) { + --local: linear-gradient(in oklch 90deg, black 25% 50%, blue 50% 75%); +} +} + +@function --image-function() { + result: linear-gradient(red,red); + result: image(red); +} + +@function --image-function-var() { + --local: linear-gradient(red,red); + + result: var(--local); + +@supports (background-image: image(red)) { + --local: image(red); +} +} + +@function --image-set-function() { + result: url(img/test.png); + result: image-set(url(img/test.png) 1x, url(img/test-2x.png) 2x); + @media (-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 2), (min-resolution: 192dpi) { + result: url(img/test-2x.png); + } +} + +@function --image-set-function-var() { + --local: url(img/test.png); + --local: image-set(url(img/test.png) 1x, url(img/test-2x.png) 2x); + + result: var(--local); + + @media (-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 2), (min-resolution: 192dpi) { + --local: url(img/test-2x.png); + } +} + +@function --ic-unit() { + result: 2em; + result: 2ic; +} + +@function --ic-unit-var() { + --local: 2em; + + result: var(--local); + +@supports (font-size: 1ic) { + --local: 2ic; +} +} + +@function --logical-viewport-units() { + result: 2vw; + result: 2vi; +} + +@function --logical-viewport-units-var() { + --local: 2vw; + + result: var(--local); + +@supports (width: 1vi) { + --local: 2vi; +} +} + +@function --gamut-mapping() { + result: rgb(230, 0, 122); + +@media (color-gamut: p3) { + result: color(display-p3 0.86333 0 0.47139); +} + +@media (color-gamut: rec2020) { + result: oklch(60% 0.4 0); +} +} + +@function --gamut-mapping-var() { + --local: rgb(230, 0, 122); + + result: var(--local); + +@supports (color: color(display-p3 0 0 0%)) { + --local: rgb(230, 0, 122); +} + +@media (color-gamut: p3) { +@supports (color: color(display-p3 0 0 0%)) { + --local: color(display-p3 0.86333 0 0.47139); +} +} + +@supports (color: oklab(0% 0 0%)) { + --local: rgb(230, 0, 122); +} + +@media (color-gamut: rec2020) { +@supports (color: oklab(0% 0 0%)) { + --local: oklch(60% 0.4 0); +} +} +} + +@function --system-ui-font-family() { + result: system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif; + result: system-ui; +} + +@function --system-ui-font-family-var() { + --local: system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif; + + result: var(--local); +} + +@function --custom-properties() { + result: var(--color-fallback); +} + +@function --custom-properties-var() { + --local: var(--color-fallback); + + result: var(--local); +} diff --git a/plugins/postcss-alpha-function/CHANGELOG.md b/plugins/postcss-alpha-function/CHANGELOG.md index 11ad02c1a3..4a6df779c2 100644 --- a/plugins/postcss-alpha-function/CHANGELOG.md +++ b/plugins/postcss-alpha-function/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Alpha Function +### Unreleased (patch) + +- Correctly nest conditional rules inside `@function` instead of cloning the `@function` rule. + ### 2.0.15 _October 1, 2026_ diff --git a/plugins/postcss-alpha-function/test/basic.css b/plugins/postcss-alpha-function/test/basic.css index 368c4c4f4e..bd59a175d4 100644 --- a/plugins/postcss-alpha-function/test/basic.css +++ b/plugins/postcss-alpha-function/test/basic.css @@ -91,3 +91,13 @@ --color: alpha(from oklch(2 1 0) / calc(alpha / 2)); } } + +@function --a() { + result: alpha(from red / 0.5); +} + +@function --b() { + --a: alpha(from red / 0.5); + + result: var(--a); +} diff --git a/plugins/postcss-alpha-function/test/basic.expect.css b/plugins/postcss-alpha-function/test/basic.expect.css index 6a26556d1a..be3c070d14 100644 --- a/plugins/postcss-alpha-function/test/basic.expect.css +++ b/plugins/postcss-alpha-function/test/basic.expect.css @@ -91,3 +91,13 @@ --color: oklch(from oklch(2 1 0) l c h / calc(alpha / 2)); } } + +@function --a() { + result: rgb(from red r g b / 0.5); +} + +@function --b() { + --a: rgb(from red r g b / 0.5); + + result: var(--a); +} diff --git a/plugins/postcss-alpha-function/test/basic.preserve-true.expect.css b/plugins/postcss-alpha-function/test/basic.preserve-true.expect.css index 9bc69e5311..9a2704e8a0 100644 --- a/plugins/postcss-alpha-function/test/basic.preserve-true.expect.css +++ b/plugins/postcss-alpha-function/test/basic.preserve-true.expect.css @@ -189,3 +189,18 @@ } } } + +@function --a() { + result: rgb(from red r g b / 0.5); + result: alpha(from red / 0.5); +} + +@function --b() { + --a: rgb(from red r g b / 0.5); + + result: var(--a); + +@supports (color: alpha(from red / 1)) { + --a: alpha(from red / 0.5); +} +} diff --git a/plugins/postcss-color-function-display-p3-linear/CHANGELOG.md b/plugins/postcss-color-function-display-p3-linear/CHANGELOG.md index 98ed7e69bf..0053922892 100644 --- a/plugins/postcss-color-function-display-p3-linear/CHANGELOG.md +++ b/plugins/postcss-color-function-display-p3-linear/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Color Function Display P3 Linear +### Unreleased (patch) + +- Correctly nest conditional rules inside `@function` instead of cloning the `@function` rule. + ### 2.0.14 _October 1, 2026_ diff --git a/plugins/postcss-color-function-display-p3-linear/test/basic.css b/plugins/postcss-color-function-display-p3-linear/test/basic.css index ef5986cffd..bdc7ec94d5 100644 --- a/plugins/postcss-color-function-display-p3-linear/test/basic.css +++ b/plugins/postcss-color-function-display-p3-linear/test/basic.css @@ -34,3 +34,13 @@ to-clone { --color: color(display-p3-linear 0.1 0.1 0.1); } } + +@function --a() { + result: color(display-p3-linear 0.1 0.1 0.1); +} + +@function --b() { + --a: color(display-p3-linear 0.1 0.1 0.1); + + result: var(--a); +} diff --git a/plugins/postcss-color-function-display-p3-linear/test/basic.expect.css b/plugins/postcss-color-function-display-p3-linear/test/basic.expect.css index 411e7b2f4b..6262738c75 100644 --- a/plugins/postcss-color-function-display-p3-linear/test/basic.expect.css +++ b/plugins/postcss-color-function-display-p3-linear/test/basic.expect.css @@ -34,3 +34,13 @@ to-clone { --color: color(display-p3 0.34919 0.34919 0.34919); } } + +@function --a() { + result: color(display-p3 0.34919 0.34919 0.34919); +} + +@function --b() { + --a: color(display-p3 0.34919 0.34919 0.34919); + + result: var(--a); +} diff --git a/plugins/postcss-color-function-display-p3-linear/test/basic.preserve-true.expect.css b/plugins/postcss-color-function-display-p3-linear/test/basic.preserve-true.expect.css index 629dee34e0..b97c107d41 100644 --- a/plugins/postcss-color-function-display-p3-linear/test/basic.preserve-true.expect.css +++ b/plugins/postcss-color-function-display-p3-linear/test/basic.preserve-true.expect.css @@ -55,3 +55,18 @@ to-clone { } } } + +@function --a() { + result: color(display-p3 0.34919 0.34919 0.34919); + result: color(display-p3-linear 0.1 0.1 0.1); +} + +@function --b() { + --a: color(display-p3 0.34919 0.34919 0.34919); + + result: var(--a); + +@supports (color: color(display-p3-linear 0 0 0)) { + --a: color(display-p3-linear 0.1 0.1 0.1); +} +} diff --git a/plugins/postcss-color-function-display-p3-linear/test/basic.with-cloned-rules.expect.css b/plugins/postcss-color-function-display-p3-linear/test/basic.with-cloned-rules.expect.css index 62a00a75c5..2b79590f85 100644 --- a/plugins/postcss-color-function-display-p3-linear/test/basic.with-cloned-rules.expect.css +++ b/plugins/postcss-color-function-display-p3-linear/test/basic.with-cloned-rules.expect.css @@ -60,3 +60,18 @@ to-clone { } } } + +@function --a() { + result: color(display-p3 0.34919 0.34919 0.34919); + result: color(display-p3-linear 0.1 0.1 0.1); +} + +@function --b() { + --a: color(display-p3 0.34919 0.34919 0.34919); + + result: var(--a); + +@supports (color: color(display-p3-linear 0 0 0)) { + --a: color(display-p3-linear 0.1 0.1 0.1); +} +} diff --git a/plugins/postcss-color-function/CHANGELOG.md b/plugins/postcss-color-function/CHANGELOG.md index 8dd6ca2dea..f09c337b81 100644 --- a/plugins/postcss-color-function/CHANGELOG.md +++ b/plugins/postcss-color-function/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Color Function +### Unreleased (patch) + +- Correctly nest conditional rules inside `@function` instead of cloning the `@function` rule. + ### 5.0.14 _October 1, 2026_ diff --git a/plugins/postcss-color-function/test/basic.css b/plugins/postcss-color-function/test/basic.css index 2e0981039b..f83ceed504 100644 --- a/plugins/postcss-color-function/test/basic.css +++ b/plugins/postcss-color-function/test/basic.css @@ -232,3 +232,13 @@ to-clone { --color: color(display-p3 0.1 0.1 0.1); } } + +@function --a() { + result: color(display-p3 0.1 0.1 0.1); +} + +@function --b() { + --a: color(display-p3 0.1 0.1 0.1); + + result: var(--a); +} diff --git a/plugins/postcss-color-function/test/basic.expect.css b/plugins/postcss-color-function/test/basic.expect.css index 9ab934f7de..d720671b72 100644 --- a/plugins/postcss-color-function/test/basic.expect.css +++ b/plugins/postcss-color-function/test/basic.expect.css @@ -232,3 +232,13 @@ to-clone { --color: rgb(26, 26, 26); } } + +@function --a() { + result: rgb(26, 26, 26); +} + +@function --b() { + --a: rgb(26, 26, 26); + + result: var(--a); +} diff --git a/plugins/postcss-color-function/test/basic.preserve-true.expect.css b/plugins/postcss-color-function/test/basic.preserve-true.expect.css index bb4fcd5938..e57d19d93e 100644 --- a/plugins/postcss-color-function/test/basic.preserve-true.expect.css +++ b/plugins/postcss-color-function/test/basic.preserve-true.expect.css @@ -352,3 +352,18 @@ to-clone { } } } + +@function --a() { + result: rgb(26, 26, 26); + result: color(display-p3 0.1 0.1 0.1); +} + +@function --b() { + --a: rgb(26, 26, 26); + + result: var(--a); + +@supports (color: color(display-p3 0 0 0%)) { + --a: color(display-p3 0.1 0.1 0.1); +} +} diff --git a/plugins/postcss-color-function/test/basic.with-cloned-rules.expect.css b/plugins/postcss-color-function/test/basic.with-cloned-rules.expect.css index ac52f37af9..bb6a7de5be 100644 --- a/plugins/postcss-color-function/test/basic.with-cloned-rules.expect.css +++ b/plugins/postcss-color-function/test/basic.with-cloned-rules.expect.css @@ -357,3 +357,18 @@ to-clone { } } } + +@function --a() { + result: rgb(26, 26, 26); + result: color(display-p3 0.1 0.1 0.1); +} + +@function --b() { + --a: rgb(26, 26, 26); + + result: var(--a); + +@supports (color: color(display-p3 0 0 0%)) { + --a: color(display-p3 0.1 0.1 0.1); +} +} diff --git a/plugins/postcss-color-functional-notation/CHANGELOG.md b/plugins/postcss-color-functional-notation/CHANGELOG.md index 7b9b781da9..905884373b 100644 --- a/plugins/postcss-color-functional-notation/CHANGELOG.md +++ b/plugins/postcss-color-functional-notation/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Color Functional Notation +### Unreleased (patch) + +- Correctly nest conditional rules inside `@function` instead of cloning the `@function` rule. + ### 8.0.14 _October 1, 2026_ diff --git a/plugins/postcss-color-functional-notation/test/basic.css b/plugins/postcss-color-functional-notation/test/basic.css index 8e6f8a26f3..21aa36b85b 100644 --- a/plugins/postcss-color-functional-notation/test/basic.css +++ b/plugins/postcss-color-functional-notation/test/basic.css @@ -117,3 +117,13 @@ to-clone { --color: rgb(255 0 0); } } + +@function --a() { + result: rgb(255 0 0 / var(--alpha-50)); +} + +@function --b() { + --a: rgb(255 0 0 / var(--alpha-50)); + + result: var(--a); +} diff --git a/plugins/postcss-color-functional-notation/test/basic.expect.css b/plugins/postcss-color-functional-notation/test/basic.expect.css index 7747fda78b..8b00ba53f4 100644 --- a/plugins/postcss-color-functional-notation/test/basic.expect.css +++ b/plugins/postcss-color-functional-notation/test/basic.expect.css @@ -117,3 +117,13 @@ to-clone { --color: rgb(255, 0, 0); } } + +@function --a() { + result: rgba(255, 0, 0, var(--alpha-50)); +} + +@function --b() { + --a: rgba(255, 0, 0, var(--alpha-50)); + + result: var(--a); +} diff --git a/plugins/postcss-color-functional-notation/test/basic.preserve-true.expect.css b/plugins/postcss-color-functional-notation/test/basic.preserve-true.expect.css index cea9a6ffff..31b6d26b51 100644 --- a/plugins/postcss-color-functional-notation/test/basic.preserve-true.expect.css +++ b/plugins/postcss-color-functional-notation/test/basic.preserve-true.expect.css @@ -196,3 +196,21 @@ to-clone { } } } + +@function --a() { + result: rgba(255, 0, 0, var(--alpha-50)); + +@supports (color: rgb(0 0 0 / 0)) { + result: rgb(255 0 0 / var(--alpha-50)); +} +} + +@function --b() { + --a: rgba(255, 0, 0, var(--alpha-50)); + + result: var(--a); + +@supports (color: rgb(0 0 0 / 0)) { + --a: rgb(255 0 0 / var(--alpha-50)); +} +} diff --git a/plugins/postcss-color-functional-notation/test/basic.with-cloned-rules.expect.css b/plugins/postcss-color-functional-notation/test/basic.with-cloned-rules.expect.css index 64b6dd3251..4b95a688cc 100644 --- a/plugins/postcss-color-functional-notation/test/basic.with-cloned-rules.expect.css +++ b/plugins/postcss-color-functional-notation/test/basic.with-cloned-rules.expect.css @@ -201,3 +201,21 @@ to-clone { } } } + +@function --a() { + result: rgba(255, 0, 0, var(--alpha-50)); + +@supports (color: rgb(0 0 0 / 0)) { + result: rgb(255 0 0 / var(--alpha-50)); +} +} + +@function --b() { + --a: rgba(255, 0, 0, var(--alpha-50)); + + result: var(--a); + +@supports (color: rgb(0 0 0 / 0)) { + --a: rgb(255 0 0 / var(--alpha-50)); +} +} diff --git a/plugins/postcss-color-hex-alpha/test/basic.css b/plugins/postcss-color-hex-alpha/test/basic.css index 424c757feb..980557b00a 100644 --- a/plugins/postcss-color-hex-alpha/test/basic.css +++ b/plugins/postcss-color-hex-alpha/test/basic.css @@ -34,3 +34,13 @@ to-clone { --color: #9823f8a9; } } + +@function --a() { + result: #9823f8a9; +} + +@function --b() { + --a: #9823f8a9; + + result: var(--a); +} diff --git a/plugins/postcss-color-hex-alpha/test/basic.expect.css b/plugins/postcss-color-hex-alpha/test/basic.expect.css index f6ce0370f9..11582c8fb3 100644 --- a/plugins/postcss-color-hex-alpha/test/basic.expect.css +++ b/plugins/postcss-color-hex-alpha/test/basic.expect.css @@ -34,3 +34,13 @@ to-clone { --color: rgba(152,35,248,0.66275); } } + +@function --a() { + result: rgba(152,35,248,0.66275); +} + +@function --b() { + --a: rgba(152,35,248,0.66275); + + result: var(--a); +} diff --git a/plugins/postcss-color-hex-alpha/test/basic.preserve.expect.css b/plugins/postcss-color-hex-alpha/test/basic.preserve.expect.css index 4c4a3c4de7..a9f7d66263 100644 --- a/plugins/postcss-color-hex-alpha/test/basic.preserve.expect.css +++ b/plugins/postcss-color-hex-alpha/test/basic.preserve.expect.css @@ -39,3 +39,15 @@ to-clone { --color: #9823f8a9; } } + +@function --a() { + result: rgba(152,35,248,0.66275); + result: #9823f8a9; +} + +@function --b() { + --a: rgba(152,35,248,0.66275); + --a: #9823f8a9; + + result: var(--a); +} diff --git a/plugins/postcss-color-hex-alpha/test/basic.with-cloned-rules.expect.css b/plugins/postcss-color-hex-alpha/test/basic.with-cloned-rules.expect.css index 9aa7b974a0..9822c353ba 100644 --- a/plugins/postcss-color-hex-alpha/test/basic.with-cloned-rules.expect.css +++ b/plugins/postcss-color-hex-alpha/test/basic.with-cloned-rules.expect.css @@ -44,3 +44,15 @@ to-clone { --color: #9823f8a9; } } + +@function --a() { + result: rgba(152,35,248,0.66275); + result: #9823f8a9; +} + +@function --b() { + --a: rgba(152,35,248,0.66275); + --a: #9823f8a9; + + result: var(--a); +} diff --git a/plugins/postcss-color-mix-function/CHANGELOG.md b/plugins/postcss-color-mix-function/CHANGELOG.md index c418dcab31..144c926bc9 100644 --- a/plugins/postcss-color-mix-function/CHANGELOG.md +++ b/plugins/postcss-color-mix-function/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Color Mix Function +### Unreleased (patch) + +- Correctly nest conditional rules inside `@function` instead of cloning the `@function` rule. + ### 4.0.14 _October 1, 2026_ diff --git a/plugins/postcss-color-mix-function/test/basic.css b/plugins/postcss-color-mix-function/test/basic.css index 8a0b9eb770..49b7af30bb 100644 --- a/plugins/postcss-color-mix-function/test/basic.css +++ b/plugins/postcss-color-mix-function/test/basic.css @@ -193,3 +193,13 @@ --color: color-mix(#09232c, white 50%); } } + +@function --a() { + result: color-mix(in lch, purple 50%, plum 50%); +} + +@function --b() { + --a: color-mix(in lch, purple 50%, plum 50%); + + result: var(--a); +} diff --git a/plugins/postcss-color-mix-function/test/basic.expect.css b/plugins/postcss-color-mix-function/test/basic.expect.css index 2969e4d4c5..8af722be4d 100644 --- a/plugins/postcss-color-mix-function/test/basic.expect.css +++ b/plugins/postcss-color-mix-function/test/basic.expect.css @@ -199,3 +199,13 @@ --color: rgb(123, 137, 142); } } + +@function --a() { + result: rgb(175, 92, 174); +} + +@function --b() { + --a: rgb(175, 92, 174); + + result: var(--a); +} diff --git a/plugins/postcss-color-mix-function/test/basic.preserve-true.expect.css b/plugins/postcss-color-mix-function/test/basic.preserve-true.expect.css index 1f29d4ea57..6c95b0f99e 100644 --- a/plugins/postcss-color-mix-function/test/basic.preserve-true.expect.css +++ b/plugins/postcss-color-mix-function/test/basic.preserve-true.expect.css @@ -297,3 +297,18 @@ } } } + +@function --a() { + result: rgb(175, 92, 174); + result: color-mix(in lch, purple 50%, plum 50%); +} + +@function --b() { + --a: rgb(175, 92, 174); + + result: var(--a); + +@supports (color: color-mix(in lch, red, blue)) { + --a: color-mix(in lch, purple 50%, plum 50%); +} +} diff --git a/plugins/postcss-color-mix-function/test/basic.with-cloned-rules.expect.css b/plugins/postcss-color-mix-function/test/basic.with-cloned-rules.expect.css index 1f29d4ea57..6c95b0f99e 100644 --- a/plugins/postcss-color-mix-function/test/basic.with-cloned-rules.expect.css +++ b/plugins/postcss-color-mix-function/test/basic.with-cloned-rules.expect.css @@ -297,3 +297,18 @@ } } } + +@function --a() { + result: rgb(175, 92, 174); + result: color-mix(in lch, purple 50%, plum 50%); +} + +@function --b() { + --a: rgb(175, 92, 174); + + result: var(--a); + +@supports (color: color-mix(in lch, red, blue)) { + --a: color-mix(in lch, purple 50%, plum 50%); +} +} diff --git a/plugins/postcss-color-mix-variadic-function-arguments/CHANGELOG.md b/plugins/postcss-color-mix-variadic-function-arguments/CHANGELOG.md index 00c423a06c..3fe6be6ce0 100644 --- a/plugins/postcss-color-mix-variadic-function-arguments/CHANGELOG.md +++ b/plugins/postcss-color-mix-variadic-function-arguments/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Color Mix Variadic Function Arguments +### Unreleased (patch) + +- Correctly nest conditional rules inside `@function` instead of cloning the `@function` rule. + ### 2.0.14 _October 1, 2026_ diff --git a/plugins/postcss-color-mix-variadic-function-arguments/test/basic.css b/plugins/postcss-color-mix-variadic-function-arguments/test/basic.css index 2b7de75b8c..1b5bc18cad 100644 --- a/plugins/postcss-color-mix-variadic-function-arguments/test/basic.css +++ b/plugins/postcss-color-mix-variadic-function-arguments/test/basic.css @@ -32,3 +32,13 @@ --color: color-mix(in oklch, red, lime, green); } } + +@function --a() { + result: color-mix(in oklch, red, lime, green); +} + +@function --b() { + --a: color-mix(in oklch, red, lime, green); + + result: var(--a); +} diff --git a/plugins/postcss-color-mix-variadic-function-arguments/test/basic.expect.css b/plugins/postcss-color-mix-variadic-function-arguments/test/basic.expect.css index a83122a4c4..02d82e2fde 100644 --- a/plugins/postcss-color-mix-variadic-function-arguments/test/basic.expect.css +++ b/plugins/postcss-color-mix-variadic-function-arguments/test/basic.expect.css @@ -51,3 +51,18 @@ } } } + +@function --a() { + result: rgb(164, 153, 0); + result: color(display-p3 0.64336 0.60238 0); +} + +@function --b() { + --a: rgb(164, 153, 0); + + result: var(--a); + +@supports (color: color(display-p3 0 0 0%)) { + --a: color(display-p3 0.64336 0.60238 0); +} +} diff --git a/plugins/postcss-color-mix-variadic-function-arguments/test/basic.preserve-true.expect.css b/plugins/postcss-color-mix-variadic-function-arguments/test/basic.preserve-true.expect.css index c3dc0c6020..b15a7bf508 100644 --- a/plugins/postcss-color-mix-variadic-function-arguments/test/basic.preserve-true.expect.css +++ b/plugins/postcss-color-mix-variadic-function-arguments/test/basic.preserve-true.expect.css @@ -65,3 +65,23 @@ } } } + +@function --a() { + result: rgb(164, 153, 0); + result: color(display-p3 0.64336 0.60238 0); + result: color-mix(in oklch, red, lime, green); +} + +@function --b() { + --a: rgb(164, 153, 0); + + result: var(--a); + +@supports (color: color(display-p3 0 0 0%)) { + --a: color(display-p3 0.64336 0.60238 0); +} + +@supports (color: color-mix(in lch, red)) { + --a: color-mix(in oklch, red, lime, green); +} +} diff --git a/plugins/postcss-color-mix-variadic-function-arguments/test/basic.with-cloned-rules.expect.css b/plugins/postcss-color-mix-variadic-function-arguments/test/basic.with-cloned-rules.expect.css index c3dc0c6020..b15a7bf508 100644 --- a/plugins/postcss-color-mix-variadic-function-arguments/test/basic.with-cloned-rules.expect.css +++ b/plugins/postcss-color-mix-variadic-function-arguments/test/basic.with-cloned-rules.expect.css @@ -65,3 +65,23 @@ } } } + +@function --a() { + result: rgb(164, 153, 0); + result: color(display-p3 0.64336 0.60238 0); + result: color-mix(in oklch, red, lime, green); +} + +@function --b() { + --a: rgb(164, 153, 0); + + result: var(--a); + +@supports (color: color(display-p3 0 0 0%)) { + --a: color(display-p3 0.64336 0.60238 0); +} + +@supports (color: color-mix(in lch, red)) { + --a: color-mix(in oklch, red, lime, green); +} +} diff --git a/plugins/postcss-color-rebeccapurple/test/basic.css b/plugins/postcss-color-rebeccapurple/test/basic.css index 534a99c318..9eda654d5a 100644 --- a/plugins/postcss-color-rebeccapurple/test/basic.css +++ b/plugins/postcss-color-rebeccapurple/test/basic.css @@ -26,3 +26,13 @@ to-clone { --color: rebeccapurple; } } + +@function --a() { + result: rebeccapurple; +} + +@function --b() { + --a: rebeccapurple; + + result: var(--a); +} diff --git a/plugins/postcss-color-rebeccapurple/test/basic.expect.css b/plugins/postcss-color-rebeccapurple/test/basic.expect.css index aaa63df3ed..e68df3091f 100644 --- a/plugins/postcss-color-rebeccapurple/test/basic.expect.css +++ b/plugins/postcss-color-rebeccapurple/test/basic.expect.css @@ -26,3 +26,13 @@ to-clone { --color: #639; } } + +@function --a() { + result: #639; +} + +@function --b() { + --a: #639; + + result: var(--a); +} diff --git a/plugins/postcss-color-rebeccapurple/test/basic.preserve-true.expect.css b/plugins/postcss-color-rebeccapurple/test/basic.preserve-true.expect.css index b3a2ef6dda..d39457d371 100644 --- a/plugins/postcss-color-rebeccapurple/test/basic.preserve-true.expect.css +++ b/plugins/postcss-color-rebeccapurple/test/basic.preserve-true.expect.css @@ -31,3 +31,15 @@ to-clone { --color: rebeccapurple; } } + +@function --a() { + result: #639; + result: rebeccapurple; +} + +@function --b() { + --a: #639; + --a: rebeccapurple; + + result: var(--a); +} diff --git a/plugins/postcss-color-rebeccapurple/test/basic.with-cloned-rules.expect.css b/plugins/postcss-color-rebeccapurple/test/basic.with-cloned-rules.expect.css index d734458d07..c3bc96e578 100644 --- a/plugins/postcss-color-rebeccapurple/test/basic.with-cloned-rules.expect.css +++ b/plugins/postcss-color-rebeccapurple/test/basic.with-cloned-rules.expect.css @@ -36,3 +36,15 @@ to-clone { --color: rebeccapurple; } } + +@function --a() { + result: #639; + result: rebeccapurple; +} + +@function --b() { + --a: #639; + --a: rebeccapurple; + + result: var(--a); +} diff --git a/plugins/postcss-conditional-values/test/basic.css b/plugins/postcss-conditional-values/test/basic.css index ecf02eedd3..8c100f87a1 100644 --- a/plugins/postcss-conditional-values/test/basic.css +++ b/plugins/postcss-conditional-values/test/basic.css @@ -15,3 +15,13 @@ .ignore { color: csstools-if(--dark-mode black, red else green, blue); } + +@function --a() { + result: csstools-if(--dark-mode black else white); +} + +@function --b() { + --a: csstools-if(--dark-mode black else white); + + result: var(--a); +} diff --git a/plugins/postcss-conditional-values/test/basic.expect.css b/plugins/postcss-conditional-values/test/basic.expect.css index c068ebb87e..b9827a7c53 100644 --- a/plugins/postcss-conditional-values/test/basic.expect.css +++ b/plugins/postcss-conditional-values/test/basic.expect.css @@ -16,3 +16,15 @@ .ignore { color: csstools-if(--dark-mode black, red else green, blue); } + +@function --a() { + --dark-mode--1: var(--dark-mode) white; + result: var(--dark-mode--1,black); +} + +@function --b() { + --dark-mode--2: var(--dark-mode) white; + --a: var(--dark-mode--2,black); + + result: var(--a); +} diff --git a/plugins/postcss-contrast-color-function/CHANGELOG.md b/plugins/postcss-contrast-color-function/CHANGELOG.md index e768956f89..5ed5f7f85e 100644 --- a/plugins/postcss-contrast-color-function/CHANGELOG.md +++ b/plugins/postcss-contrast-color-function/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Contrast Color Function +### Unreleased (patch) + +- Correctly nest conditional rules inside `@function` instead of cloning the `@function` rule. + ### 3.0.14 _October 1, 2026_ diff --git a/plugins/postcss-contrast-color-function/test/basic.css b/plugins/postcss-contrast-color-function/test/basic.css index 6aca97a6ee..46a699be71 100644 --- a/plugins/postcss-contrast-color-function/test/basic.css +++ b/plugins/postcss-contrast-color-function/test/basic.css @@ -44,3 +44,13 @@ background-color: contrast-color(contrast-color(green)); border-color: contrast-color(contrast-color(contrast-color(green))); } + +@function --a() { + result: contrast-color(green); +} + +@function --b() { + --a: contrast-color(green); + + result: var(--a); +} diff --git a/plugins/postcss-contrast-color-function/test/basic.expect.css b/plugins/postcss-contrast-color-function/test/basic.expect.css index 4dda873b70..d8fa9ea3f2 100644 --- a/plugins/postcss-contrast-color-function/test/basic.expect.css +++ b/plugins/postcss-contrast-color-function/test/basic.expect.css @@ -52,3 +52,18 @@ border-color: rgb(255, 255, 255); border-color: contrast-color(contrast-color(contrast-color(green))); } + +@function --a() { + result: rgb(255, 255, 255); + result: contrast-color(green); +} + +@function --b() { + --a: rgb(255, 255, 255); + + result: var(--a); + +@supports (color: contrast-color(red)) { + --a: contrast-color(green); +} +} diff --git a/plugins/postcss-custom-properties/CHANGELOG.md b/plugins/postcss-custom-properties/CHANGELOG.md index b1a9a21d2a..9d41cd4f8a 100644 --- a/plugins/postcss-custom-properties/CHANGELOG.md +++ b/plugins/postcss-custom-properties/CHANGELOG.md @@ -4,6 +4,7 @@ - Share a single expansion budget across all declarations. - Avoid a quadratic sibling scan when checking for an existing fallback declaration. +- Ignore custom properties in `@function` bodies. ### 15.0.3 diff --git a/plugins/postcss-custom-properties/dist/index.mjs b/plugins/postcss-custom-properties/dist/index.mjs index 759b8fc230..648511538d 100644 --- a/plugins/postcss-custom-properties/dist/index.mjs +++ b/plugins/postcss-custom-properties/dist/index.mjs @@ -1 +1 @@ -import{parse as e,addLayerToModel as t}from"@csstools/cascade-layer-name-parser";import n from"postcss-value-parser";import{hasSupportsAtRuleAncestor as r}from"@csstools/utilities";const o=e("csstools-implicit-layer")[0];function collectCascadeLayerOrder(n){const r=new Map,s=new Map,a=[];let i=1;n.walkAtRules(n=>{if("layer"!==n.name.toLowerCase())return;{let e=n.parent,t=0;for(;e;){if("atrule"!==e.type||"layer"!==e.name.toLowerCase()){if(e===n.root())break;return}if(t++,t>100)throw new Error("Maximum nested @layer depth exceeded, reduce the complexity of your layers");e=e.parent}}let c;if(n.nodes)c=normalizeLayerName(n.params,i++);else{if(!n.params.trim())return;c=n.params}let l=e(c);if(l?.length){{let e=n.parent;for(;e&&"atrule"===e.type&&"layer"===e.name.toLowerCase();){const t=s.get(e);if(t){l=l.map(e=>t.concat(e));break}e=e.parent}}if(t(a,l),n.nodes){const e=l[0].concat(o);r.set(n,e),s.set(n,l[0])}}});for(const e of r.values())t(a,[e]);const c=new WeakMap;for(const[e,t]of r)c.set(e,a.findIndex(e=>t.equal(e)));return c}function normalizeLayerName(e,t){return e.trim()?e:`csstools-anon-layer--${t}`}const s=/(?:!\s*)?postcss-custom-properties:\s*off\b/i,a=new WeakMap;function isBlockIgnored(e){if(!e||!e.nodes)return!1;if(a.has(e))return a.get(e);const t=e.some(e=>isIgnoreComment(e,s));return a.set(e,t),t}const i=/(?:!\s*)?postcss-custom-properties:\s*ignore\s+next\b/i;function isDeclarationIgnored(e){return!!e&&(!!isBlockIgnored(e.parent)||isIgnoreComment(e.prev(),i))}function isIgnoreComment(e,t){return!!e&&"comment"===e.type&&t.test(e.text)}const c=new Set(["layer"]);function isProcessableRule(e){let t=e.parent;for(;t;){if("atrule"===t.type&&!c.has(t.name.toLowerCase()))return!1;t=t.parent}return!0}const l=/^html$/i,u=/^:where\(html\)$/i,p=/^:root$/i,f=/^:where\(:root\)$/i,d=/(html|:root)/i,m=/^var$/i;function isVarFunction(e){return"function"===e.type&&m.test(e.value)&&e.nodes?.length>0}const g=/\bvar\(/i;function parseOrCached(e,t){let r=t.get(e);return r||(r=n(e),t.set(e,r),r)}function toposort(e,t){let n=e.length;const r=new Array(n),o=new Set,s=makeOutgoingEdges(t),a=makeNodesHash(e);for(let t=e.length-1;t>=0;t--){if(o.has(t))continue;const i=e[t],c=new Set,l=[];for(o.add(t),c.add(i),l.push({node:i,outgoing:Array.from(s.get(i)||new Set),next:0});l.length;){const e=l[l.length-1];if(e.nexts.get(e)??0,getLowLink=e=>a.get(e)??0;for(const e of r){if(s.has(e))continue;const t=[{node:e,childIndex:0}];for(s.set(e,l),a.set(e,l),l++,c.push(e),i.add(e);t.length;){const e=t[t.length-1],r=o.get(e.node)??[];if(e.childIndex1)for(const e of t)n.add(e)}}}for(const t of n)e.delete(t);return n}function makeOutgoingEdges(e){const t=new Map;for(let n=0,r=e.length;n{if(r.remaining--,r.remaining<0)throw new Error("Maximum custom property expansion size exceeded, reduce the complexity of your custom properties");if(!isVarFunction(e))return;const a=parseVarFunction(e);if(!a)return;let i=!1;a.fallback&&n.walk(a.fallback,e=>{if(!isVarFunction(e))return;const n=parseVarFunction(e);return n?n.fallback||t.has(n.name.value)?void 0:(i=!0,!1):void 0});let c=t.get(a.name.value)?.nodes;c||!a.fallback||i||(c=a.fallback),void 0!==c&&(c.length?replaceNodeWithNodes(s,o,c):s.splice(o,1,{type:"div",value:" ",before:"",after:"",sourceIndex:e.sourceIndex,sourceEndIndex:e.sourceEndIndex}))}),n.stringify(e.nodes)):""}function walk(e,t){let n,r,o;for(n=0,r=e.length;n"comment"!==e.type&&"space"!==e.type);return 1===t.length&&("word"===t[0].type&&w.test(t[0].value))}function buildCustomPropertiesMap(e,t,r){if(!e.size)return t;const o=new Map(t);{const s=[];for(const[a,i]of e.entries()){const c=parseOrCached(i,r);let l=!1;n.walk(c.nodes,n=>{if(!isVarFunction(n))return;const r=parseVarFunction(n);r&&(r.fallback||e.has(r.name.value)||t.has(r.name.value)?s.push([r.name.value,a]):l=!0)}),l||o.set(a,c)}removeCyclicReferences(o,s)}{const e=[];for(const[t,r]of o.entries())n.walk(r.nodes,n=>{if(!isVarFunction(n))return;const r=parseVarFunction(n);r&&(r.fallback||o.has(r.name.value)?e.push([r.name.value,t]):o.delete(t))});for(let t=0;t{d.test(e.selector)&&e.nodes?.length&&isProcessableRule(e)&&(isBlockIgnored(e)||e.selectors.forEach(t=>{let s;if(u.test(t)||f.test(t))s=0;else if(l.test(t))s=1;else{if(!p.test(t))return;s=2}const a=(c=o,((i=e).parent&&"atrule"===i.parent.type&&"layer"===i.parent.name.toLowerCase()?c.has(i.parent)?c.get(i.parent)+1:0:1e7)+10+s);var i,c;e.each(e=>{if("decl"!==e.type)return;if(!e.variable||isDeclarationIgnored(e))return;if("initial"===e.value.toLowerCase().trim())return;const t=r.get(e.prop)??-1;a>=t&&(r.set(e.prop,a),n.set(e.prop,e.value))})}))}),buildCustomPropertiesMap(n,new Map,t)}function getCustomPropertiesFromSiblings(e,t,n){if(!e.parent)return t;const r=new Map;return e.parent.each(t=>{"decl"===t.type&&t.variable&&e!==t&&(isDeclarationIgnored(t)||r.set(t.prop,t.value))}),r.size?buildCustomPropertiesMap(r,t,n):t}function transformProperties(e,t,r){if(isTransformableDecl(e)&&!isDeclarationIgnored(e)){const o=e.raws?.value?.raw??e.value,s=transformValueAST(n(o),t,r.budget);if(s===o)return;if(parentHasExactFallback(e,s))return void(r.preserve||e.remove());const a=e.cloneBefore({value:s});a.raws?.value?.raw&&(a.raws.value.raw=""),r?.preserve||e.remove()}}const isTransformableDecl=e=>!e.variable&&e.value.includes("--")&&e.value.toLowerCase().includes("var(");function parentHasExactFallback(e,t){if(!e||!e.parent)return!1;const n=e.prop.toLowerCase();let r=e.prev();for(;r;){if("decl"===r.type&&r.prop.toLowerCase()===n&&r.value===t)return!0;r=r.prev()}return!1}const v=/\bvar\(|\(top: var\(--f\)/i,creator=e=>{const t=!("preserve"in Object(e))||Boolean(e?.preserve);if("importFrom"in Object(e))throw new Error('[postcss-custom-properties] "importFrom" is no longer supported');if("exportTo"in Object(e))throw new Error('[postcss-custom-properties] "exportTo" is no longer supported');return{postcssPlugin:"postcss-custom-properties",prepare(){let e=new Map;const n=new WeakMap,o=new Map;let s={remaining:h};return{postcssPlugin:"postcss-custom-properties",Once(t){s={remaining:h},e=getCustomPropertiesFromRoot(t,o)},Declaration(a){if(!g.test(a.value))return;if(r(a,v))return;let i=e;t&&a.parent&&(i=n.get(a.parent)??getCustomPropertiesFromSiblings(a,e,o),n.set(a.parent,i)),transformProperties(a,i,{preserve:t,budget:s})}}}}};creator.postcss=!0;export{creator as default,creator as"module.exports"}; +import{parse as e,addLayerToModel as t}from"@csstools/cascade-layer-name-parser";import n from"postcss-value-parser";import{hasSupportsAtRuleAncestor as r}from"@csstools/utilities";const o=e("csstools-implicit-layer")[0];function collectCascadeLayerOrder(n){const r=new Map,s=new Map,a=[];let i=1;n.walkAtRules(n=>{if("layer"!==n.name.toLowerCase())return;{let e=n.parent,t=0;for(;e;){if("atrule"!==e.type||"layer"!==e.name.toLowerCase()){if(e===n.root())break;return}if(t++,t>100)throw new Error("Maximum nested @layer depth exceeded, reduce the complexity of your layers");e=e.parent}}let c;if(n.nodes)c=normalizeLayerName(n.params,i++);else{if(!n.params.trim())return;c=n.params}let l=e(c);if(l?.length){{let e=n.parent;for(;e&&"atrule"===e.type&&"layer"===e.name.toLowerCase();){const t=s.get(e);if(t){l=l.map(e=>t.concat(e));break}e=e.parent}}if(t(a,l),n.nodes){const e=l[0].concat(o);r.set(n,e),s.set(n,l[0])}}});for(const e of r.values())t(a,[e]);const c=new WeakMap;for(const[e,t]of r)c.set(e,a.findIndex(e=>t.equal(e)));return c}function normalizeLayerName(e,t){return e.trim()?e:`csstools-anon-layer--${t}`}const s=/(?:!\s*)?postcss-custom-properties:\s*off\b/i,a=new WeakMap;function isBlockIgnored(e){if(!e||!e.nodes)return!1;if(a.has(e))return a.get(e);const t=e.some(e=>isIgnoreComment(e,s));return a.set(e,t),t}const i=/(?:!\s*)?postcss-custom-properties:\s*ignore\s+next\b/i;function isDeclarationIgnored(e){return!!e&&(!!isBlockIgnored(e.parent)||isIgnoreComment(e.prev(),i))}function isIgnoreComment(e,t){return!!e&&"comment"===e.type&&t.test(e.text)}const c=new Set(["layer"]);function isProcessableRule(e){let t=e.parent;for(;t;){if("atrule"===t.type&&!c.has(t.name.toLowerCase()))return!1;t=t.parent}return!0}const l=/^html$/i,u=/^:where\(html\)$/i,p=/^:root$/i,f=/^:where\(:root\)$/i,d=/(html|:root)/i,m=/^var$/i;function isVarFunction(e){return"function"===e.type&&m.test(e.value)&&e.nodes?.length>0}const g=/\bvar\(/i;function parseOrCached(e,t){let r=t.get(e);return r||(r=n(e),t.set(e,r),r)}function toposort(e,t){let n=e.length;const r=new Array(n),o=new Set,s=makeOutgoingEdges(t),a=makeNodesHash(e);for(let t=e.length-1;t>=0;t--){if(o.has(t))continue;const i=e[t],c=new Set,l=[];for(o.add(t),c.add(i),l.push({node:i,outgoing:Array.from(s.get(i)||new Set),next:0});l.length;){const e=l[l.length-1];if(e.nexts.get(e)??0,getLowLink=e=>a.get(e)??0;for(const e of r){if(s.has(e))continue;const t=[{node:e,childIndex:0}];for(s.set(e,l),a.set(e,l),l++,c.push(e),i.add(e);t.length;){const e=t[t.length-1],r=o.get(e.node)??[];if(e.childIndex1)for(const e of t)n.add(e)}}}for(const t of n)e.delete(t);return n}function makeOutgoingEdges(e){const t=new Map;for(let n=0,r=e.length;n{if(r.remaining--,r.remaining<0)throw new Error("Maximum custom property expansion size exceeded, reduce the complexity of your custom properties");if(!isVarFunction(e))return;const a=parseVarFunction(e);if(!a)return;let i=!1;a.fallback&&n.walk(a.fallback,e=>{if(!isVarFunction(e))return;const n=parseVarFunction(e);return n?n.fallback||t.has(n.name.value)?void 0:(i=!0,!1):void 0});let c=t.get(a.name.value)?.nodes;c||!a.fallback||i||(c=a.fallback),void 0!==c&&(c.length?replaceNodeWithNodes(s,o,c):s.splice(o,1,{type:"div",value:" ",before:"",after:"",sourceIndex:e.sourceIndex,sourceEndIndex:e.sourceEndIndex}))}),n.stringify(e.nodes)):""}function walk(e,t){let n,r,o;for(n=0,r=e.length;n"comment"!==e.type&&"space"!==e.type);return 1===t.length&&("word"===t[0].type&&w.test(t[0].value))}function buildCustomPropertiesMap(e,t,r){if(!e.size)return t;const o=new Map(t);{const s=[];for(const[a,i]of e.entries()){const c=parseOrCached(i,r);let l=!1;n.walk(c.nodes,n=>{if(!isVarFunction(n))return;const r=parseVarFunction(n);r&&(r.fallback||e.has(r.name.value)||t.has(r.name.value)?s.push([r.name.value,a]):l=!0)}),l||o.set(a,c)}removeCyclicReferences(o,s)}{const e=[];for(const[t,r]of o.entries())n.walk(r.nodes,n=>{if(!isVarFunction(n))return;const r=parseVarFunction(n);r&&(r.fallback||o.has(r.name.value)?e.push([r.name.value,t]):o.delete(t))});for(let t=0;t{d.test(e.selector)&&e.nodes?.length&&isProcessableRule(e)&&(isBlockIgnored(e)||e.selectors.forEach(t=>{let s;if(u.test(t)||f.test(t))s=0;else if(l.test(t))s=1;else{if(!p.test(t))return;s=2}const a=(c=o,((i=e).parent&&"atrule"===i.parent.type&&"layer"===i.parent.name.toLowerCase()?c.has(i.parent)?c.get(i.parent)+1:0:1e7)+10+s);var i,c;e.each(e=>{if("decl"!==e.type)return;if(!e.variable||isDeclarationIgnored(e))return;if(inFunction$1(e))return;if("initial"===e.value.toLowerCase().trim())return;const t=r.get(e.prop)??-1;a>=t&&(r.set(e.prop,a),n.set(e.prop,e.value))})}))}),buildCustomPropertiesMap(n,new Map,t)}function getCustomPropertiesFromSiblings(e,t,n){if(!e.parent)return t;const r=new Map;return e.parent.each(t=>{"decl"===t.type&&t.variable&&e!==t&&(isDeclarationIgnored(t)||r.set(t.prop,t.value))}),r.size?buildCustomPropertiesMap(r,t,n):t}function transformProperties(e,t,r){if(isTransformableDecl(e)&&!isDeclarationIgnored(e)){const o=e.raws?.value?.raw??e.value,s=transformValueAST(n(o),t,r.budget);if(s===o)return;if(parentHasExactFallback(e,s))return void(r.preserve||e.remove());const a=e.cloneBefore({value:s});a.raws?.value?.raw&&(a.raws.value.raw=""),r?.preserve||e.remove()}}const isTransformableDecl=e=>!e.variable&&e.value.includes("--")&&e.value.toLowerCase().includes("var(");function parentHasExactFallback(e,t){if(!e||!e.parent)return!1;const n=e.prop.toLowerCase();let r=e.prev();for(;r;){if("decl"===r.type&&r.prop.toLowerCase()===n&&r.value===t)return!0;r=r.prev()}return!1}const y=/\bvar\(|\(top: var\(--f\)/i,k=/^function$/i;function inFunction(e){let t=e.parent;for(;t;){if("atrule"===t.type&&k.test(t.name))return!0;t=t.parent}return!1}const creator=e=>{const t=!("preserve"in Object(e))||Boolean(e?.preserve);if("importFrom"in Object(e))throw new Error('[postcss-custom-properties] "importFrom" is no longer supported');if("exportTo"in Object(e))throw new Error('[postcss-custom-properties] "exportTo" is no longer supported');return{postcssPlugin:"postcss-custom-properties",prepare(){let e=new Map;const n=new WeakMap,o=new Map;let s={remaining:h};return{postcssPlugin:"postcss-custom-properties",Once(t){s={remaining:h},e=getCustomPropertiesFromRoot(t,o)},Declaration(a){if(inFunction(a))return;if(!g.test(a.value))return;if(r(a,y))return;let i=e;t&&a.parent&&(i=n.get(a.parent)??getCustomPropertiesFromSiblings(a,e,o),n.set(a.parent,i)),transformProperties(a,i,{preserve:t,budget:s})}}}}};creator.postcss=!0;export{creator as default,creator as"module.exports"}; diff --git a/plugins/postcss-custom-properties/src/get-custom-properties-from-root.ts b/plugins/postcss-custom-properties/src/get-custom-properties-from-root.ts index dae588b978..0296be35d7 100644 --- a/plugins/postcss-custom-properties/src/get-custom-properties-from-root.ts +++ b/plugins/postcss-custom-properties/src/get-custom-properties-from-root.ts @@ -1,10 +1,25 @@ -import type { Root } from 'postcss'; +import type { AtRule, Declaration, Document, Root } from 'postcss'; import type valuesParser from 'postcss-value-parser'; import { cascadeLayerNumberForNode, collectCascadeLayerOrder } from './cascade-layers'; import { isBlockIgnored, isDeclarationIgnored } from './is-ignored'; import { HTML_SELECTOR_REGEX, HTML_WHERE_SELECTOR_REGEX, MAYBE_HTML_OR_ROOT_RULE_REGEX, ROOT_SELECTOR_REGEX, ROOT_WHERE_SELECTOR_REGEX, isProcessableRule } from './is-processable-rule'; import { buildCustomPropertiesMap } from './build-custom-properties-map'; +const IS_FUNCTION_REGEX = /^function$/i; + +function inFunction(decl: Declaration): boolean { + let parent: typeof decl.parent | Document = decl.parent; + while (parent) { + if (parent.type === 'atrule' && IS_FUNCTION_REGEX.test((parent as AtRule).name)) { + return true; + } + + parent = parent.parent; + } + + return false; +} + // return custom selectors from the css root, conditionally removing them export default function getCustomPropertiesFromRoot(root: Root, parsedValuesCache: Map): Map { const customProperties: Map = new Map(); @@ -50,6 +65,12 @@ export default function getCustomPropertiesFromRoot(root: Root, parsedValuesCach return; } + if (inFunction(decl)) { + // Custom properties defined in an `@function` body are local variables. + // They must not be exposed as document level custom properties. + return; + } + if (decl.value.toLowerCase().trim() === 'initial') { return; } diff --git a/plugins/postcss-custom-properties/src/index.ts b/plugins/postcss-custom-properties/src/index.ts index fa508a545c..376c580d25 100644 --- a/plugins/postcss-custom-properties/src/index.ts +++ b/plugins/postcss-custom-properties/src/index.ts @@ -1,4 +1,4 @@ -import type { Node, Plugin, PluginCreator } from 'postcss'; +import type { AtRule, Declaration, Document, Node, Plugin, PluginCreator } from 'postcss'; import type valuesParser from 'postcss-value-parser'; import getCustomPropertiesFromRoot from './get-custom-properties-from-root'; @@ -16,6 +16,20 @@ export type pluginOptions = { }; const SUPPORTS_REGEX = /\bvar\(|\(top: var\(--f\)/i; +const IS_FUNCTION_REGEX = /^function$/i; + +function inFunction(decl: Declaration): boolean { + let parent: typeof decl.parent | Document = decl.parent; + while (parent) { + if (parent.type === 'atrule' && IS_FUNCTION_REGEX.test((parent as AtRule).name)) { + return true; + } + + parent = parent.parent; + } + + return false; +} const creator: PluginCreator = (opts?: pluginOptions) => { const preserve = 'preserve' in Object(opts) ? Boolean(opts?.preserve) : true; @@ -47,6 +61,12 @@ const creator: PluginCreator = (opts?: pluginOptions) => { rootCustomProperties = getCustomPropertiesFromRoot(root, parsedValuesCache); }, Declaration(decl): void { + if (inFunction(decl)) { + // Custom properties in an `@function` body are local variables + // with dynamic scoping and must be left as-is. + return; + } + if (!HAS_VAR_FUNCTION_REGEX.test(decl.value)) { return; } diff --git a/plugins/postcss-custom-properties/test/basic.css b/plugins/postcss-custom-properties/test/basic.css index 7f6e9be025..2c434269d0 100644 --- a/plugins/postcss-custom-properties/test/basic.css +++ b/plugins/postcss-custom-properties/test/basic.css @@ -259,3 +259,13 @@ html { .breadcrumb-item + .breadcrumb-item::before { content: var(--bs-breadcrumb-divider, "/") /* rtl: var(--bs-breadcrumb-divider, "/") */; } + +@function --a() { + result: var(--color); +} + +@function --b() { + --a: var(--color); + + result: var(--a); +} diff --git a/plugins/postcss-custom-properties/test/basic.expect.css b/plugins/postcss-custom-properties/test/basic.expect.css index 78858223a9..100a74d1a2 100644 --- a/plugins/postcss-custom-properties/test/basic.expect.css +++ b/plugins/postcss-custom-properties/test/basic.expect.css @@ -298,3 +298,13 @@ html { content: "/" /* rtl: var(--bs-breadcrumb-divider, "/") */; content: var(--bs-breadcrumb-divider, "/") /* rtl: var(--bs-breadcrumb-divider, "/") */; } + +@function --a() { + result: var(--color); +} + +@function --b() { + --a: var(--color); + + result: var(--a); +} diff --git a/plugins/postcss-custom-properties/test/basic.preserve.expect.css b/plugins/postcss-custom-properties/test/basic.preserve.expect.css index 06e5e5ca8d..a1dc601068 100644 --- a/plugins/postcss-custom-properties/test/basic.preserve.expect.css +++ b/plugins/postcss-custom-properties/test/basic.preserve.expect.css @@ -254,3 +254,13 @@ html { .breadcrumb-item + .breadcrumb-item::before { content: "/" /* rtl: var(--bs-breadcrumb-divider, "/") */; } + +@function --a() { + result: var(--color); +} + +@function --b() { + --a: var(--color); + + result: var(--a); +} diff --git a/plugins/postcss-design-tokens/test/basic.css b/plugins/postcss-design-tokens/test/basic.css index 61790da39f..8d1a2c644a 100644 --- a/plugins/postcss-design-tokens/test/basic.css +++ b/plugins/postcss-design-tokens/test/basic.css @@ -31,3 +31,13 @@ bar(design-token('lists.comma')) ); } + +@function --a() { + result: design-token('color.font.base'); +} + +@function --b() { + --a: design-token('color.font.base'); + + result: var(--a); +} diff --git a/plugins/postcss-design-tokens/test/basic.expect.css b/plugins/postcss-design-tokens/test/basic.expect.css index eec7a6ac31..cb2e60fba5 100644 --- a/plugins/postcss-design-tokens/test/basic.expect.css +++ b/plugins/postcss-design-tokens/test/basic.expect.css @@ -24,3 +24,13 @@ bar(255, 0, 255) ); } + +@function --a() { + result: #111111; +} + +@function --b() { + --a: #111111; + + result: var(--a); +} diff --git a/plugins/postcss-double-position-gradients/CHANGELOG.md b/plugins/postcss-double-position-gradients/CHANGELOG.md index 83881938c4..3c14509a44 100644 --- a/plugins/postcss-double-position-gradients/CHANGELOG.md +++ b/plugins/postcss-double-position-gradients/CHANGELOG.md @@ -3,6 +3,7 @@ ### Unreleased (patch) - Improve performance when a gradient contains multiple double-position stops. +- Correctly nest conditional rules inside `@function` instead of cloning the `@function` rule. ### 7.0.4 diff --git a/plugins/postcss-double-position-gradients/test/basic.css b/plugins/postcss-double-position-gradients/test/basic.css index b42451bcfd..894d462737 100644 --- a/plugins/postcss-double-position-gradients/test/basic.css +++ b/plugins/postcss-double-position-gradients/test/basic.css @@ -88,3 +88,13 @@ to-clone { --foo: linear-gradient(90deg, black 25% 50%, blue 50% 75%); } } + +@function --a() { + result: linear-gradient(90deg, black 25% 50%, blue 50% 75%); +} + +@function --b() { + --a: linear-gradient(90deg, black 25% 50%, blue 50% 75%); + + result: var(--a); +} diff --git a/plugins/postcss-double-position-gradients/test/basic.expect.css b/plugins/postcss-double-position-gradients/test/basic.expect.css index 5a2fefe8f1..49972e5fd4 100644 --- a/plugins/postcss-double-position-gradients/test/basic.expect.css +++ b/plugins/postcss-double-position-gradients/test/basic.expect.css @@ -146,3 +146,18 @@ to-clone { } } } + +@function --a() { + result: linear-gradient(90deg, black 25%,black 50%, blue 50%, blue 75%); + result: linear-gradient(90deg, black 25% 50%, blue 50% 75%); +} + +@function --b() { + --a: linear-gradient(90deg, black 25%,black 50%, blue 50%, blue 75%); + + result: var(--a); + +@supports (background: linear-gradient(red 0%, red 0% 1%, red 2%)) { + --a: linear-gradient(90deg, black 25% 50%, blue 50% 75%); +} +} diff --git a/plugins/postcss-double-position-gradients/test/basic.preserve.expect.css b/plugins/postcss-double-position-gradients/test/basic.preserve.expect.css index 6ecf9cf843..8176ae7f2e 100644 --- a/plugins/postcss-double-position-gradients/test/basic.preserve.expect.css +++ b/plugins/postcss-double-position-gradients/test/basic.preserve.expect.css @@ -88,3 +88,13 @@ to-clone { --foo: linear-gradient(90deg, black 25%,black 50%, blue 50%, blue 75%); } } + +@function --a() { + result: linear-gradient(90deg, black 25%,black 50%, blue 50%, blue 75%); +} + +@function --b() { + --a: linear-gradient(90deg, black 25%,black 50%, blue 50%, blue 75%); + + result: var(--a); +} diff --git a/plugins/postcss-double-position-gradients/test/basic.with-cloned-rules.expect.css b/plugins/postcss-double-position-gradients/test/basic.with-cloned-rules.expect.css index 88296f8e0f..a6aba1cdfa 100644 --- a/plugins/postcss-double-position-gradients/test/basic.with-cloned-rules.expect.css +++ b/plugins/postcss-double-position-gradients/test/basic.with-cloned-rules.expect.css @@ -151,3 +151,18 @@ to-clone { } } } + +@function --a() { + result: linear-gradient(90deg, black 25%,black 50%, blue 50%, blue 75%); + result: linear-gradient(90deg, black 25% 50%, blue 50% 75%); +} + +@function --b() { + --a: linear-gradient(90deg, black 25%,black 50%, blue 50%, blue 75%); + + result: var(--a); + +@supports (background: linear-gradient(red 0%, red 0% 1%, red 2%)) { + --a: linear-gradient(90deg, black 25% 50%, blue 50% 75%); +} +} diff --git a/plugins/postcss-exponential-functions/test/basic.css b/plugins/postcss-exponential-functions/test/basic.css index 240ad0f7fc..611fd3ba0c 100644 --- a/plugins/postcss-exponential-functions/test/basic.css +++ b/plugins/postcss-exponential-functions/test/basic.css @@ -209,3 +209,13 @@ .foo { z-index: exp(1); } + +@function --a() { + result: pow(2, 3); +} + +@function --b() { + --a: pow(2, 3); + + result: var(--a); +} diff --git a/plugins/postcss-exponential-functions/test/basic.expect.css b/plugins/postcss-exponential-functions/test/basic.expect.css index e9d4c593c0..4a4d7c4871 100644 --- a/plugins/postcss-exponential-functions/test/basic.expect.css +++ b/plugins/postcss-exponential-functions/test/basic.expect.css @@ -209,3 +209,13 @@ .foo { z-index: calc(2.71828); } + +@function --a() { + result: calc(8); +} + +@function --b() { + --a: calc(8); + + result: var(--a); +} diff --git a/plugins/postcss-exponential-functions/test/basic.preserve.expect.css b/plugins/postcss-exponential-functions/test/basic.preserve.expect.css index 674717514b..b9f93cc3ee 100644 --- a/plugins/postcss-exponential-functions/test/basic.preserve.expect.css +++ b/plugins/postcss-exponential-functions/test/basic.preserve.expect.css @@ -269,3 +269,15 @@ z-index: calc(2.71828); z-index: exp(1); } + +@function --a() { + result: calc(8); + result: pow(2, 3); +} + +@function --b() { + --a: calc(8); + --a: pow(2, 3); + + result: var(--a); +} diff --git a/plugins/postcss-gamut-mapping/CHANGELOG.md b/plugins/postcss-gamut-mapping/CHANGELOG.md index 4426a45e4d..64c529450a 100644 --- a/plugins/postcss-gamut-mapping/CHANGELOG.md +++ b/plugins/postcss-gamut-mapping/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS gamut-mapping +### Unreleased (patch) + +- Correctly nest conditional rules inside `@function` instead of cloning the `@function` rule. + ### 3.0.14 _October 1, 2026_ diff --git a/plugins/postcss-gamut-mapping/dist/index.mjs b/plugins/postcss-gamut-mapping/dist/index.mjs index fc54dfe8a8..ce39ca1857 100644 --- a/plugins/postcss-gamut-mapping/dist/index.mjs +++ b/plugins/postcss-gamut-mapping/dist/index.mjs @@ -1 +1 @@ -import{tokenize as e}from"@csstools/css-tokenizer";import{replaceComponentValues as t,parseCommaSeparatedListOfComponentValues as o,isFunctionNode as s,stringify as a}from"@csstools/css-parser-algorithms";import{color as r,SyntaxFlag as n,colorDataFitsRGB_Gamut as l,colorDataFitsDisplayP3_Gamut as i,serializeRGB as c}from"@csstools/css-color-parser";const p=/\bcolor-gamut\b/i;function hasConditionalAncestor(e){let t=e.parent;for(;t;)if("atrule"===t.type){if("media"===t.name.toLowerCase()&&p.test(t.params))return!0;t=t.parent}else t=t.parent;return!1}function sameProperty(e){const t=e.prop.toLowerCase(),o=[],s=e.parent?.nodes??[];for(let e=0;e({postcssPlugin:"postcss-gamut-mapping",prepare(){const p=new WeakMap,f=new WeakSet;return{postcssPlugin:"postcss-gamut-mapping",OnceExit(h,{postcss:g}){h.walkDecls(h=>{if(f.has(h))return;if(!u.test(h.value))return;if(!h.parent||hasConditionalAncestor(h))return;if(inKeyframes(h)||"atrule"===h.parent.type&&d.test(h.parent.name))return;const v=sameProperty(h).map((p,u)=>{f.add(p);let d=!1;const h=p.value,g=t(o(e({css:h})),e=>{if(!s(e)||!m.test(e.getName()))return;const t=r(e);return!t||t.syntaxFlags.has(n.HasNoneKeywords)||l(t)?void 0:(d||i(t)||(d=!0),c(t,!0))}),v=a(g);return{isRec2020:d,matchesOriginal:v===h,modifiedValue:v,hasFallback:u>0,item:p}}),k=[];v.reverse();for(const e of v){if(e.matchesOriginal)break;k.push(e)}k.reverse(),k.forEach(({isRec2020:e,modifiedValue:t,hasFallback:o,item:s})=>{const a=s.parent;if(!a)return;const r=p.get(a)||{conditionalRules:[],propNames:new Set,lastConditionParams:void 0,lastConditionalRule:void 0};p.set(a,r);const n=`(color-gamut: ${e?"rec2020":"p3"})`;if(r.lastConditionParams!==n&&(r.lastConditionalRule=void 0),!o){const e=s.cloneBefore({value:t});f.add(e)}if(r.lastConditionalRule){const e=s.clone();return r.lastConditionalRule.append(e),f.add(e),void s.remove()}const l=g.atRule({name:"media",params:n,source:a.source,raws:{before:"\n\n",after:"\n"}}),i=a.clone();i.removeAll(),i.raws.before="\n";const c=s.clone();i.append(c),s.remove(),f.add(c),r.lastConditionParams=l.params,r.lastConditionalRule=i,l.append(i),r.conditionalRules.push(l)})}),h.walk(e=>{const t=p.get(e);t&&0!==t.conditionalRules.length&&t.conditionalRules.reverse().forEach(t=>{e.after(t)})})}}}});creator.postcss=!0;export{creator as default,creator as"module.exports"}; +import{tokenize as e}from"@csstools/css-tokenizer";import{replaceComponentValues as t,parseCommaSeparatedListOfComponentValues as o,isFunctionNode as a,stringify as s}from"@csstools/css-parser-algorithms";import{color as n,SyntaxFlag as r,colorDataFitsRGB_Gamut as l,colorDataFitsDisplayP3_Gamut as i,serializeRGB as c}from"@csstools/css-color-parser";const p=/\bcolor-gamut\b/i;function hasConditionalAncestor(e){let t=e.parent;for(;t;)if("atrule"===t.type){if("media"===t.name.toLowerCase()&&p.test(t.params))return!0;t=t.parent}else t=t.parent;return!1}function sameProperty(e){const t=e.prop.toLowerCase(),o=[],a=e.parent?.nodes??[];for(let e=0;e({postcssPlugin:"postcss-gamut-mapping",prepare(){const p=new WeakMap,f=new WeakSet;return{postcssPlugin:"postcss-gamut-mapping",OnceExit(g,{postcss:v}){g.walkDecls(g=>{if(f.has(g))return;if(!u.test(g.value))return;if(!g.parent||hasConditionalAncestor(g))return;if(inKeyframes(g)||"atrule"===g.parent.type&&d.test(g.parent.name))return;const y=sameProperty(g).map((p,u)=>{f.add(p);let d=!1;const h=p.value,g=t(o(e({css:h})),e=>{if(!a(e)||!m.test(e.getName()))return;const t=n(e);return!t||t.syntaxFlags.has(r.HasNoneKeywords)||l(t)?void 0:(d||i(t)||(d=!0),c(t,!0))}),v=s(g);return{isRec2020:d,matchesOriginal:v===h,modifiedValue:v,hasFallback:u>0,item:p}}),k=[];y.reverse();for(const e of y){if(e.matchesOriginal)break;k.push(e)}k.reverse(),k.forEach(({isRec2020:e,modifiedValue:t,hasFallback:o,item:a})=>{const s=a.parent;if(!s)return;const n=p.get(s)||{conditionalRules:[],propNames:new Set,lastConditionParams:void 0,lastConditionalRule:void 0};p.set(s,n);const r=`(color-gamut: ${e?"rec2020":"p3"})`;if(n.lastConditionParams!==r&&(n.lastConditionalRule=void 0),!o){const e=a.cloneBefore({value:t});f.add(e)}if(n.lastConditionalRule){const e=a.clone();return n.lastConditionalRule.append(e),f.add(e),void a.remove()}const l=v.atRule({name:"media",params:r,source:s.source,raws:{before:"\n\n",after:"\n"}});let i;if("atrule"===s.type&&h.test(s.name))i=l;else{const e=s.clone();e.removeAll(),e.raws.before="\n",l.append(e),i=e}const c=a.clone();i.append(c),a.remove(),f.add(c),n.lastConditionParams=l.params,n.lastConditionalRule=i,n.conditionalRules.push(l)})}),g.walk(e=>{const t=p.get(e);t&&0!==t.conditionalRules.length&&("atrule"===e.type&&h.test(e.name)?e.append(t.conditionalRules):t.conditionalRules.reverse().forEach(t=>{e.after(t)}))})}}}});creator.postcss=!0;export{creator as default,creator as"module.exports"}; diff --git a/plugins/postcss-gamut-mapping/src/index.ts b/plugins/postcss-gamut-mapping/src/index.ts index 217a67d003..7b0a1e2fdd 100644 --- a/plugins/postcss-gamut-mapping/src/index.ts +++ b/plugins/postcss-gamut-mapping/src/index.ts @@ -1,4 +1,4 @@ -import type { AtRule, Container, Declaration, Document, Node, Plugin, PluginCreator } from 'postcss'; +import type { AtRule, ChildNode, Container, Declaration, Document, Node, Plugin, PluginCreator } from 'postcss'; import { hasConditionalAncestor } from './has-conditional-ancestor'; import { tokenize } from '@csstools/css-tokenizer'; import { isFunctionNode, parseCommaSeparatedListOfComponentValues, replaceComponentValues, stringify } from '@csstools/css-parser-algorithms'; @@ -12,6 +12,7 @@ const HAS_WIDE_GAMUT_COLOR_FUNCTION_REGEX = /\b(?:color|lab|lch|oklab|oklch)\(/i const HAS_WIDE_GAMUT_COLOR_NAME_REGEX = /^(?:color|lab|lch|oklab|oklch)$/i; const IS_PROPERTY_REGEX = /^property$/i; const IS_KEYFRAMES_REGEX = /^keyframes$/i; +const IS_FUNCTION_REGEX = /^function$/i; type State = { conditionalRules: Array, @@ -179,22 +180,32 @@ const creator: PluginCreator = () => { }, }); - const parentClone = parent.clone(); - parentClone.removeAll(); + let conditionalRuleContainer: Container; - parentClone.raws.before = '\n'; + if (parent.type === 'atrule' && IS_FUNCTION_REGEX.test(parent.name)) { + // `@function` accepts conditional group rules in its body, + // so the conditional rule is nested instead of cloning the `@function`. + conditionalRuleContainer = atRule; + } else { + const parentClone = parent.clone(); + parentClone.removeAll(); + + parentClone.raws.before = '\n'; + + atRule.append(parentClone); + conditionalRuleContainer = parentClone; + } const clone = item.clone(); - parentClone.append(clone); + conditionalRuleContainer.append(clone); item.remove(); visited.add(clone); state.lastConditionParams = atRule.params; - state.lastConditionalRule = parentClone; + state.lastConditionalRule = conditionalRuleContainer; - atRule.append(parentClone); state.conditionalRules.push(atRule); }); }); @@ -209,6 +220,12 @@ const creator: PluginCreator = () => { return; } + if (node.type === 'atrule' && IS_FUNCTION_REGEX.test(node.name)) { + // Conditional rules belong inside the `@function` body. + node.append(state.conditionalRules); + return; + } + // rule.after reverses the at rule order. // reversing the call order gives in the correct order overall. state.conditionalRules.reverse().forEach((atSupports) => { diff --git a/plugins/postcss-gamut-mapping/test/basic.css b/plugins/postcss-gamut-mapping/test/basic.css index 508e523c8b..9cfec8de95 100644 --- a/plugins/postcss-gamut-mapping/test/basic.css +++ b/plugins/postcss-gamut-mapping/test/basic.css @@ -155,3 +155,13 @@ --foo: color(srgb 0.99 1.0001 0.99); } } + +@function --a() { + result: oklch(60% 0.4 0); +} + +@function --b() { + --a: oklch(60% 0.4 0); + + result: var(--a); +} diff --git a/plugins/postcss-gamut-mapping/test/basic.expect.css b/plugins/postcss-gamut-mapping/test/basic.expect.css index 64f202549e..617c392f18 100644 --- a/plugins/postcss-gamut-mapping/test/basic.expect.css +++ b/plugins/postcss-gamut-mapping/test/basic.expect.css @@ -226,3 +226,21 @@ --foo: color(srgb 0.99 1.0001 0.99); } } + +@function --a() { + result: rgb(230, 0, 122); + +@media (color-gamut: rec2020) { + result: oklch(60% 0.4 0); +} +} + +@function --b() { + --a: rgb(230, 0, 122); + + result: var(--a); + +@media (color-gamut: rec2020) { + --a: oklch(60% 0.4 0); +} +} diff --git a/plugins/postcss-gradients-interpolation-method/CHANGELOG.md b/plugins/postcss-gradients-interpolation-method/CHANGELOG.md index b28bb661f2..8743ad77b3 100644 --- a/plugins/postcss-gradients-interpolation-method/CHANGELOG.md +++ b/plugins/postcss-gradients-interpolation-method/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Gradients Interpolation Method +### Unreleased (patch) + +- Correctly nest conditional rules inside `@function` instead of cloning the `@function` rule. + ### 6.0.14 _October 1, 2026_ diff --git a/plugins/postcss-gradients-interpolation-method/test/basic.css b/plugins/postcss-gradients-interpolation-method/test/basic.css index 1b7f20bb99..e81629dc84 100644 --- a/plugins/postcss-gradients-interpolation-method/test/basic.css +++ b/plugins/postcss-gradients-interpolation-method/test/basic.css @@ -329,3 +329,13 @@ to-clone { --foo: conic-gradient(in oklch longer hue, rgb(255 150 150) 0deg, rgb(255 150 150) 360deg); } } + +@function --a() { + result: linear-gradient(in oklch 90deg, black 25% 50%, blue 50% 75%); +} + +@function --b() { + --a: linear-gradient(in oklch 90deg, black 25% 50%, blue 50% 75%); + + result: var(--a); +} diff --git a/plugins/postcss-gradients-interpolation-method/test/basic.expect.css b/plugins/postcss-gradients-interpolation-method/test/basic.expect.css index 8e008736c2..465f976ccd 100644 --- a/plugins/postcss-gradients-interpolation-method/test/basic.expect.css +++ b/plugins/postcss-gradients-interpolation-method/test/basic.expect.css @@ -447,3 +447,18 @@ to-clone { } } } + +@function --a() { + result: linear-gradient(90deg, rgb(0, 0, 0) 25%, rgb(0, 0, 0) 50%, rgb(0, 0, 255) 50%, rgb(0, 0, 255) 75%); + result: linear-gradient(in oklch 90deg, black 25% 50%, blue 50% 75%); +} + +@function --b() { + --a: linear-gradient(90deg, rgb(0, 0, 0) 25%, rgb(0, 0, 0) 50%, rgb(0, 0, 255) 50%, rgb(0, 0, 255) 75%); + + result: var(--a); + +@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) { + --a: linear-gradient(in oklch 90deg, black 25% 50%, blue 50% 75%); +} +} diff --git a/plugins/postcss-gradients-interpolation-method/test/basic.preserve-false.expect.css b/plugins/postcss-gradients-interpolation-method/test/basic.preserve-false.expect.css index 98d0ef0ddd..4a391ccdf1 100644 --- a/plugins/postcss-gradients-interpolation-method/test/basic.preserve-false.expect.css +++ b/plugins/postcss-gradients-interpolation-method/test/basic.preserve-false.expect.css @@ -360,3 +360,13 @@ to-clone { } } } + +@function --a() { + result: linear-gradient(90deg, rgb(0, 0, 0) 25%, rgb(0, 0, 0) 50%, rgb(0, 0, 255) 50%, rgb(0, 0, 255) 75%); +} + +@function --b() { + --a: linear-gradient(90deg, rgb(0, 0, 0) 25%, rgb(0, 0, 0) 50%, rgb(0, 0, 255) 50%, rgb(0, 0, 255) 75%); + + result: var(--a); +} diff --git a/plugins/postcss-gradients-interpolation-method/test/basic.with-cloned-rules.expect.css b/plugins/postcss-gradients-interpolation-method/test/basic.with-cloned-rules.expect.css index a347b80390..a7017d1add 100644 --- a/plugins/postcss-gradients-interpolation-method/test/basic.with-cloned-rules.expect.css +++ b/plugins/postcss-gradients-interpolation-method/test/basic.with-cloned-rules.expect.css @@ -452,3 +452,18 @@ to-clone { } } } + +@function --a() { + result: linear-gradient(90deg, rgb(0, 0, 0) 25%, rgb(0, 0, 0) 50%, rgb(0, 0, 255) 50%, rgb(0, 0, 255) 75%); + result: linear-gradient(in oklch 90deg, black 25% 50%, blue 50% 75%); +} + +@function --b() { + --a: linear-gradient(90deg, rgb(0, 0, 0) 25%, rgb(0, 0, 0) 50%, rgb(0, 0, 255) 50%, rgb(0, 0, 255) 75%); + + result: var(--a); + +@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) { + --a: linear-gradient(in oklch 90deg, black 25% 50%, blue 50% 75%); +} +} diff --git a/plugins/postcss-hwb-function/CHANGELOG.md b/plugins/postcss-hwb-function/CHANGELOG.md index b45e7593dc..578c2ef817 100644 --- a/plugins/postcss-hwb-function/CHANGELOG.md +++ b/plugins/postcss-hwb-function/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS HWB Function +### Unreleased (patch) + +- Correctly nest conditional rules inside `@function` instead of cloning the `@function` rule. + ### 5.0.14 _October 1, 2026_ diff --git a/plugins/postcss-hwb-function/test/basic.css b/plugins/postcss-hwb-function/test/basic.css index 664ebfe89b..7ae03764bd 100644 --- a/plugins/postcss-hwb-function/test/basic.css +++ b/plugins/postcss-hwb-function/test/basic.css @@ -33,3 +33,13 @@ to-clone { --foo: hwb(50deg 20% 30%); } } + +@function --a() { + result: hwb(0 60% 40% / var(--alpha)); +} + +@function --b() { + --a: hwb(0 60% 40% / var(--alpha)); + + result: var(--a); +} diff --git a/plugins/postcss-hwb-function/test/basic.expect.css b/plugins/postcss-hwb-function/test/basic.expect.css index 07e1be550c..e4306ad358 100644 --- a/plugins/postcss-hwb-function/test/basic.expect.css +++ b/plugins/postcss-hwb-function/test/basic.expect.css @@ -33,3 +33,13 @@ to-clone { --foo: rgb(179, 157, 51); } } + +@function --a() { + result: rgba(153, 153, 153, var(--alpha)); +} + +@function --b() { + --a: rgba(153, 153, 153, var(--alpha)); + + result: var(--a); +} diff --git a/plugins/postcss-hwb-function/test/basic.preserve-true.expect.css b/plugins/postcss-hwb-function/test/basic.preserve-true.expect.css index 5d1e071991..a6a5efae97 100644 --- a/plugins/postcss-hwb-function/test/basic.preserve-true.expect.css +++ b/plugins/postcss-hwb-function/test/basic.preserve-true.expect.css @@ -66,3 +66,21 @@ to-clone { } } } + +@function --a() { + result: rgba(153, 153, 153, var(--alpha)); + +@supports (color: hwb(0 0% 0%)) { + result: hwb(0 60% 40% / var(--alpha)); +} +} + +@function --b() { + --a: rgba(153, 153, 153, var(--alpha)); + + result: var(--a); + +@supports (color: hwb(0 0% 0%)) { + --a: hwb(0 60% 40% / var(--alpha)); +} +} diff --git a/plugins/postcss-hwb-function/test/basic.with-cloned-rules.expect.css b/plugins/postcss-hwb-function/test/basic.with-cloned-rules.expect.css index 42737f5ecb..af93b4c6b4 100644 --- a/plugins/postcss-hwb-function/test/basic.with-cloned-rules.expect.css +++ b/plugins/postcss-hwb-function/test/basic.with-cloned-rules.expect.css @@ -71,3 +71,21 @@ to-clone { } } } + +@function --a() { + result: rgba(153, 153, 153, var(--alpha)); + +@supports (color: hwb(0 0% 0%)) { + result: hwb(0 60% 40% / var(--alpha)); +} +} + +@function --b() { + --a: rgba(153, 153, 153, var(--alpha)); + + result: var(--a); + +@supports (color: hwb(0 0% 0%)) { + --a: hwb(0 60% 40% / var(--alpha)); +} +} diff --git a/plugins/postcss-ic-unit/CHANGELOG.md b/plugins/postcss-ic-unit/CHANGELOG.md index 76d105c68a..a86480a6c1 100644 --- a/plugins/postcss-ic-unit/CHANGELOG.md +++ b/plugins/postcss-ic-unit/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS IC Unit +### Unreleased (patch) + +- Correctly nest conditional rules inside `@function` instead of cloning the `@function` rule. + ### 5.0.4 _September 6, 2026_ diff --git a/plugins/postcss-ic-unit/test/basic.css b/plugins/postcss-ic-unit/test/basic.css index e2fb4191d7..19d367af6e 100644 --- a/plugins/postcss-ic-unit/test/basic.css +++ b/plugins/postcss-ic-unit/test/basic.css @@ -23,3 +23,13 @@ to-clone { --foo: 2ic; } } + +@function --a() { + result: 2ic; +} + +@function --b() { + --a: 2ic; + + result: var(--a); +} diff --git a/plugins/postcss-ic-unit/test/basic.expect.css b/plugins/postcss-ic-unit/test/basic.expect.css index 1ecd56cd6d..3322d1cabb 100644 --- a/plugins/postcss-ic-unit/test/basic.expect.css +++ b/plugins/postcss-ic-unit/test/basic.expect.css @@ -23,3 +23,13 @@ to-clone { --foo: 2em; } } + +@function --a() { + result: 2em; +} + +@function --b() { + --a: 2em; + + result: var(--a); +} diff --git a/plugins/postcss-ic-unit/test/basic.preserve-true.expect.css b/plugins/postcss-ic-unit/test/basic.preserve-true.expect.css index 9b70f649e6..3935ff8b67 100644 --- a/plugins/postcss-ic-unit/test/basic.preserve-true.expect.css +++ b/plugins/postcss-ic-unit/test/basic.preserve-true.expect.css @@ -50,3 +50,18 @@ to-clone { } } } + +@function --a() { + result: 2em; + result: 2ic; +} + +@function --b() { + --a: 2em; + + result: var(--a); + +@supports (font-size: 1ic) { + --a: 2ic; +} +} diff --git a/plugins/postcss-ic-unit/test/basic.with-cloned-rules.expect.css b/plugins/postcss-ic-unit/test/basic.with-cloned-rules.expect.css index ffad22ed2d..d87f0b0f6c 100644 --- a/plugins/postcss-ic-unit/test/basic.with-cloned-rules.expect.css +++ b/plugins/postcss-ic-unit/test/basic.with-cloned-rules.expect.css @@ -55,3 +55,18 @@ to-clone { } } } + +@function --a() { + result: 2em; + result: 2ic; +} + +@function --b() { + --a: 2em; + + result: var(--a); + +@supports (font-size: 1ic) { + --a: 2ic; +} +} diff --git a/plugins/postcss-image-function/CHANGELOG.md b/plugins/postcss-image-function/CHANGELOG.md index c62db5f7ab..5c3eb74df8 100644 --- a/plugins/postcss-image-function/CHANGELOG.md +++ b/plugins/postcss-image-function/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Image Function +### Unreleased (patch) + +- Correctly nest conditional rules inside `@function` instead of cloning the `@function` rule. + ### 1.0.5 _October 1, 2026_ diff --git a/plugins/postcss-image-function/test/basic.css b/plugins/postcss-image-function/test/basic.css index 0695b49bfa..a11af5dc31 100644 --- a/plugins/postcss-image-function/test/basic.css +++ b/plugins/postcss-image-function/test/basic.css @@ -34,3 +34,13 @@ --foo: image(red); } } + +@function --a() { + result: image(red); +} + +@function --b() { + --a: image(red); + + result: var(--a); +} diff --git a/plugins/postcss-image-function/test/basic.expect.css b/plugins/postcss-image-function/test/basic.expect.css index 7fd99e1172..4ce8cd907b 100644 --- a/plugins/postcss-image-function/test/basic.expect.css +++ b/plugins/postcss-image-function/test/basic.expect.css @@ -34,3 +34,13 @@ --foo: linear-gradient(red,red); } } + +@function --a() { + result: linear-gradient(red,red); +} + +@function --b() { + --a: linear-gradient(red,red); + + result: var(--a); +} diff --git a/plugins/postcss-image-function/test/basic.preserve-true.expect.css b/plugins/postcss-image-function/test/basic.preserve-true.expect.css index 918f25ee41..2ea46206ed 100644 --- a/plugins/postcss-image-function/test/basic.preserve-true.expect.css +++ b/plugins/postcss-image-function/test/basic.preserve-true.expect.css @@ -59,3 +59,18 @@ } } } + +@function --a() { + result: linear-gradient(red,red); + result: image(red); +} + +@function --b() { + --a: linear-gradient(red,red); + + result: var(--a); + +@supports (background-image: image(red)) { + --a: image(red); +} +} diff --git a/plugins/postcss-image-set-function/CHANGELOG.md b/plugins/postcss-image-set-function/CHANGELOG.md index ac6d405f94..b8b76359b2 100644 --- a/plugins/postcss-image-set-function/CHANGELOG.md +++ b/plugins/postcss-image-set-function/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS image-set() Function +### Unreleased (patch) + +- Correctly nest conditional rules inside `@function` instead of cloning the `@function` rule. + ### 8.0.1 _September 6, 2026_ diff --git a/plugins/postcss-image-set-function/dist/index.mjs b/plugins/postcss-image-set-function/dist/index.mjs index e57eb18e8b..3cf85b5ad1 100644 --- a/plugins/postcss-image-set-function/dist/index.mjs +++ b/plugins/postcss-image-set-function/dist/index.mjs @@ -1 +1 @@ -import e from"postcss-value-parser";import{hasFallback as t}from"@csstools/utilities";function isComma(e){return!!e&&"div"===e.type&&","===e.value}const n=/^(?:cross-fade|image|(?:repeating-)?(?:conic|linear|radial)-gradient|url|var)$/i;function getImage(t){return!(!t||!t.type)&&("string"===t.type?"url("+e.stringify(t)+")":!("function"!==t.type||!n.test(t.value))&&e.stringify(t))}const r=new Map([["dpcm",2.54],["dpi",1],["dppx",96],["x",96]]);function getMedia(e,t,n){if("boolean"==typeof e)return!1;const r=Math.floor(e/96*100)/100;return t.atRule({name:"media",params:`(-webkit-min-device-pixel-ratio: ${r}), (min-resolution: ${e}dpi)`,source:n.source})}function getMediaDPI(t){if(!t)return!1;if("word"!==t.type)return!1;if(!isNumericNode(t))return!1;const n=e.unit(t.value);if(!n)return!1;const i=r.get(n.unit.toLowerCase());return!!i&&Number(n.number)*i}function isNumericNode(t){if(!t||!t.value)return!1;try{return!1!==e.unit(t.value)}catch{return!1}}const handleInvalidation=(e,t,n)=>{if("warn"===e.oninvalid)e.decl.warn(e.result,t,{word:String(n)});else if("throw"===e.oninvalid)throw e.decl.error(t,{word:String(n)})},processImageSet=(t,n,r)=>{const i=n.parent;if(!i)return;const o=new Map,a=n.value;for(let i=0;ie-t),u=s.map(e=>o.get(e)?.atRule).filter(e=>!!e);if(!u.length)return;const l=o.get(s[0])?.value;if(!l)return;const c=u.slice(1);c.length&&i.after(c),n.cloneBefore({value:l.trim()}),r.preserve||(n.remove(),i.nodes?.length||i.remove())},i=/(?:^|[^\w-])(?:-webkit-)?image-set\(/i,o=/^(?:-webkit-)?image-set$/i,a=/^property$/i,s=/^keyframes$/i;function inKeyframes(e){let t=e.parent;for(;t;){if("atrule"===t.type&&s.test(t.name))return t;t=t.parent}}const creator=n=>{const r=!("preserve"in Object(n))||Boolean(n?.preserve),s="onInvalid"in Object(n)?n?.onInvalid:"ignore";if("oninvalid"in Object(n))throw new Error('"oninvalid" was changed to "onInvalid" to match other plugins with similar options');return{postcssPlugin:"postcss-image-set-function",Declaration(n,{result:u,postcss:l}){const c=n.value;if(!i.test(c))return;if(t(n))return;if(inKeyframes(n))return;if("atrule"===n.parent?.type&&a.test(n.parent.name))return;let f;try{f=e(c)}catch{n.warn(u,`Failed to parse value '${c}' as an image-set function. Leaving the original value intact.`)}if(void 0===f)return;const p=[];f.walk(t=>{if("function"!==t.type)return;if(!o.test(t.value))return;let r=!1;if(e.walk(t.nodes,e=>{"function"===e.type&&o.test(e.value)&&(r=!0)}),r)return handleInvalidation({decl:n,oninvalid:s,result:u},"nested image-set functions are not allowed",e.stringify(t)),!1;const i=t.nodes.filter(e=>"comment"!==e.type&&"space"!==e.type);p.push({imageSetFunction:t,imageSetOptionNodes:i})}),processImageSet(p,n,{decl:n,oninvalid:s,preserve:r,result:u,postcss:l})}}};creator.postcss=!0;export{creator as default,creator as"module.exports"}; +import e from"postcss-value-parser";import{hasFallback as t}from"@csstools/utilities";function isComma(e){return!!e&&"div"===e.type&&","===e.value}const n=/^(?:cross-fade|image|(?:repeating-)?(?:conic|linear|radial)-gradient|url|var)$/i;function getImage(t){return!(!t||!t.type)&&("string"===t.type?"url("+e.stringify(t)+")":!("function"!==t.type||!n.test(t.value))&&e.stringify(t))}const r=new Map([["dpcm",2.54],["dpi",1],["dppx",96],["x",96]]);function getMedia(e,t,n){if("boolean"==typeof e)return!1;const r=Math.floor(e/96*100)/100;return t.atRule({name:"media",params:`(-webkit-min-device-pixel-ratio: ${r}), (min-resolution: ${e}dpi)`,source:n.source})}function getMediaDPI(t){if(!t)return!1;if("word"!==t.type)return!1;if(!isNumericNode(t))return!1;const n=e.unit(t.value);if(!n)return!1;const i=r.get(n.unit.toLowerCase());return!!i&&Number(n.number)*i}function isNumericNode(t){if(!t||!t.value)return!1;try{return!1!==e.unit(t.value)}catch{return!1}}const handleInvalidation=(e,t,n)=>{if("warn"===e.oninvalid)e.decl.warn(e.result,t,{word:String(n)});else if("throw"===e.oninvalid)throw e.decl.error(t,{word:String(n)})},i=/^function$/i,processImageSet=(t,n,r)=>{const o=n.parent;if(!o)return;const a=new Map,s=n.value;for(let i=0;ie-t),l=u.map(e=>a.get(e)?.atRule).filter(e=>!!e);if(!l.length)return;const c=a.get(u[0])?.value;if(!c)return;const f=l.slice(1);if(f.length)if("atrule"===o.type&&i.test(o.name))for(const e of f)o.append(e);else o.after(f);n.cloneBefore({value:c.trim()}),r.preserve||(n.remove(),o.nodes?.length||o.remove())},o=/(?:^|[^\w-])(?:-webkit-)?image-set\(/i,a=/^(?:-webkit-)?image-set$/i,s=/^property$/i,u=/^keyframes$/i;function inKeyframes(e){let t=e.parent;for(;t;){if("atrule"===t.type&&u.test(t.name))return t;t=t.parent}}const creator=n=>{const r=!("preserve"in Object(n))||Boolean(n?.preserve),i="onInvalid"in Object(n)?n?.onInvalid:"ignore";if("oninvalid"in Object(n))throw new Error('"oninvalid" was changed to "onInvalid" to match other plugins with similar options');return{postcssPlugin:"postcss-image-set-function",Declaration(n,{result:u,postcss:l}){const c=n.value;if(!o.test(c))return;if(t(n))return;if(inKeyframes(n))return;if("atrule"===n.parent?.type&&s.test(n.parent.name))return;let f;try{f=e(c)}catch{n.warn(u,`Failed to parse value '${c}' as an image-set function. Leaving the original value intact.`)}if(void 0===f)return;const p=[];f.walk(t=>{if("function"!==t.type)return;if(!a.test(t.value))return;let r=!1;if(e.walk(t.nodes,e=>{"function"===e.type&&a.test(e.value)&&(r=!0)}),r)return handleInvalidation({decl:n,oninvalid:i,result:u},"nested image-set functions are not allowed",e.stringify(t)),!1;const o=t.nodes.filter(e=>"comment"!==e.type&&"space"!==e.type);p.push({imageSetFunction:t,imageSetOptionNodes:o})}),processImageSet(p,n,{decl:n,oninvalid:i,preserve:r,result:u,postcss:l})}}};creator.postcss=!0;export{creator as default,creator as"module.exports"}; diff --git a/plugins/postcss-image-set-function/src/lib/process-image-set.ts b/plugins/postcss-image-set-function/src/lib/process-image-set.ts index 796056ba86..526f5498f3 100644 --- a/plugins/postcss-image-set-function/src/lib/process-image-set.ts +++ b/plugins/postcss-image-set-function/src/lib/process-image-set.ts @@ -6,6 +6,8 @@ import { handleInvalidation } from './handle-invalidation'; import type { AtRule, Declaration, Result, Postcss } from 'postcss'; import type { Node } from 'postcss-value-parser'; +const IS_FUNCTION_REGEX = /^function$/i; + type imageSetFunction = { imageSetFunction: Node; imageSetOptionNodes: Array; @@ -70,12 +72,19 @@ export const processImageSet = (imageSetFunctions: Array, decl } for (const { atRule, value } of mediasByDpr.values()) { - // prepare @media { decl: } - const parentClone = parent.clone().removeAll(); const declClone = decl.clone({ value: value }); - parentClone.append(declClone); - atRule.append(parentClone); + if (parent.type === 'atrule' && IS_FUNCTION_REGEX.test(parent.name)) { + // `@function` accepts conditional group rules in its body, + // so the conditional rule is nested instead of cloning the `@function`. + atRule.append(declClone); + } else { + // prepare @media { decl: } + const parentClone = parent.clone().removeAll(); + + parentClone.append(declClone); + atRule.append(parentClone); + } } const mediaSizes = Array.from(mediasByDpr.keys()) @@ -97,7 +106,14 @@ export const processImageSet = (imageSetFunctions: Array, decl const mediasWithoutSmallest = medias.slice(1); if (mediasWithoutSmallest.length) { - parent.after(mediasWithoutSmallest); + if (parent.type === 'atrule' && IS_FUNCTION_REGEX.test(parent.name)) { + // Conditional rules belong inside the `@function` body. + for (const media of mediasWithoutSmallest) { + parent.append(media); + } + } else { + parent.after(mediasWithoutSmallest); + } } decl.cloneBefore({ value: smallestValue.trim() }); diff --git a/plugins/postcss-image-set-function/test/basic.css b/plugins/postcss-image-set-function/test/basic.css index bd23639d1e..1680cd5f45 100644 --- a/plugins/postcss-image-set-function/test/basic.css +++ b/plugins/postcss-image-set-function/test/basic.css @@ -126,3 +126,13 @@ to-clone { --foo: image-set(url(img-a.png) 1x, url(img-a@2x.png) 2x); } } + +@function --a() { + result: image-set(url(img/test.png) 1x, url(img/test-2x.png) 2x); +} + +@function --b() { + --a: image-set(url(img/test.png) 1x, url(img/test-2x.png) 2x); + + result: var(--a); +} diff --git a/plugins/postcss-image-set-function/test/basic.expect.css b/plugins/postcss-image-set-function/test/basic.expect.css index 4a2083d8c8..a868fbd3b1 100644 --- a/plugins/postcss-image-set-function/test/basic.expect.css +++ b/plugins/postcss-image-set-function/test/basic.expect.css @@ -304,3 +304,22 @@ to-clone { --foo: image-set(url(img-a.png) 1x, url(img-a@2x.png) 2x); } } + +@function --a() { + result: url(img/test.png); + result: image-set(url(img/test.png) 1x, url(img/test-2x.png) 2x); + @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + result: url(img/test-2x.png); + } +} + +@function --b() { + --a: url(img/test.png); + --a: image-set(url(img/test.png) 1x, url(img/test-2x.png) 2x); + + result: var(--a); + + @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + --a: url(img/test-2x.png); + } +} diff --git a/plugins/postcss-image-set-function/test/basic.no-preserve.expect.css b/plugins/postcss-image-set-function/test/basic.no-preserve.expect.css index 4c1e42caa8..6ff3bfde82 100644 --- a/plugins/postcss-image-set-function/test/basic.no-preserve.expect.css +++ b/plugins/postcss-image-set-function/test/basic.no-preserve.expect.css @@ -235,3 +235,20 @@ to-clone { --foo: image-set(url(img-a.png) 1x, url(img-a@2x.png) 2x); } } + +@function --a() { + result: url(img/test.png); + @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + result: url(img/test-2x.png); + } +} + +@function --b() { + --a: url(img/test.png); + + result: var(--a); + + @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + --a: url(img/test-2x.png); + } +} diff --git a/plugins/postcss-image-set-function/test/basic.with-cloned-rules.expect.css b/plugins/postcss-image-set-function/test/basic.with-cloned-rules.expect.css index 5651b13e89..b33d2782f7 100644 --- a/plugins/postcss-image-set-function/test/basic.with-cloned-rules.expect.css +++ b/plugins/postcss-image-set-function/test/basic.with-cloned-rules.expect.css @@ -316,3 +316,22 @@ to-clone { --foo: image-set(url(img-a.png) 1x, url(img-a@2x.png) 2x); } } + +@function --a() { + result: url(img/test.png); + result: image-set(url(img/test.png) 1x, url(img/test-2x.png) 2x); + @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + result: url(img/test-2x.png); + } +} + +@function --b() { + --a: url(img/test.png); + --a: image-set(url(img/test.png) 1x, url(img/test-2x.png) 2x); + + result: var(--a); + + @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { + --a: url(img/test-2x.png); + } +} diff --git a/plugins/postcss-lab-function/CHANGELOG.md b/plugins/postcss-lab-function/CHANGELOG.md index c4f3639f55..40a5d0779f 100644 --- a/plugins/postcss-lab-function/CHANGELOG.md +++ b/plugins/postcss-lab-function/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Lab Function +### Unreleased (patch) + +- Correctly nest conditional rules inside `@function` instead of cloning the `@function` rule. + ### 8.0.14 _October 1, 2026_ diff --git a/plugins/postcss-lab-function/test/basic.css b/plugins/postcss-lab-function/test/basic.css index 0cb41423b9..16edb6fd95 100644 --- a/plugins/postcss-lab-function/test/basic.css +++ b/plugins/postcss-lab-function/test/basic.css @@ -208,3 +208,13 @@ to-clone { --foo: lch(60% 50 180); } } + +@function --a() { + result: lab(40% 56.6 39); +} + +@function --b() { + --a: lab(40% 56.6 39); + + result: var(--a); +} diff --git a/plugins/postcss-lab-function/test/basic.display-p3-false.expect.css b/plugins/postcss-lab-function/test/basic.display-p3-false.expect.css index 2c01d5e41a..bc3e7cb50c 100644 --- a/plugins/postcss-lab-function/test/basic.display-p3-false.expect.css +++ b/plugins/postcss-lab-function/test/basic.display-p3-false.expect.css @@ -208,3 +208,13 @@ to-clone { --foo: rgb(0, 163, 142); } } + +@function --a() { + result: rgb(179, 35, 35); +} + +@function --b() { + --a: rgb(179, 35, 35); + + result: var(--a); +} diff --git a/plugins/postcss-lab-function/test/basic.display-p3-false.preserve-true.expect.css b/plugins/postcss-lab-function/test/basic.display-p3-false.preserve-true.expect.css index ed0b82b367..da2c6f9cc2 100644 --- a/plugins/postcss-lab-function/test/basic.display-p3-false.preserve-true.expect.css +++ b/plugins/postcss-lab-function/test/basic.display-p3-false.preserve-true.expect.css @@ -326,3 +326,18 @@ to-clone { } } } + +@function --a() { + result: rgb(179, 35, 35); + result: lab(40% 56.6 39); +} + +@function --b() { + --a: rgb(179, 35, 35); + + result: var(--a); + +@supports (color: lab(0% 0 0%)) { + --a: lab(40% 56.6 39); +} +} diff --git a/plugins/postcss-lab-function/test/basic.expect.css b/plugins/postcss-lab-function/test/basic.expect.css index 11c1096ddc..b0dd40c601 100644 --- a/plugins/postcss-lab-function/test/basic.expect.css +++ b/plugins/postcss-lab-function/test/basic.expect.css @@ -257,3 +257,13 @@ to-clone { } } } + +@function --a() { + result: rgb(179, 35, 35); +} + +@function --b() { + --a: rgb(179, 35, 35); + + result: var(--a); +} diff --git a/plugins/postcss-lab-function/test/basic.preserve-true.expect.css b/plugins/postcss-lab-function/test/basic.preserve-true.expect.css index 422a53f9e0..d764134371 100644 --- a/plugins/postcss-lab-function/test/basic.preserve-true.expect.css +++ b/plugins/postcss-lab-function/test/basic.preserve-true.expect.css @@ -366,3 +366,18 @@ to-clone { } } } + +@function --a() { + result: rgb(179, 35, 35); + result: lab(40% 56.6 39); +} + +@function --b() { + --a: rgb(179, 35, 35); + + result: var(--a); + +@supports (color: lab(0% 0 0%)) { + --a: lab(40% 56.6 39); +} +} diff --git a/plugins/postcss-lab-function/test/basic.with-cloned-rules.expect.css b/plugins/postcss-lab-function/test/basic.with-cloned-rules.expect.css index af23ca2bee..860781cdd8 100644 --- a/plugins/postcss-lab-function/test/basic.with-cloned-rules.expect.css +++ b/plugins/postcss-lab-function/test/basic.with-cloned-rules.expect.css @@ -371,3 +371,18 @@ to-clone { } } } + +@function --a() { + result: rgb(179, 35, 35); + result: lab(40% 56.6 39); +} + +@function --b() { + --a: rgb(179, 35, 35); + + result: var(--a); + +@supports (color: lab(0% 0 0%)) { + --a: lab(40% 56.6 39); +} +} diff --git a/plugins/postcss-light-dark-function/test/basic.css b/plugins/postcss-light-dark-function/test/basic.css index feb608faad..710b31cd50 100644 --- a/plugins/postcss-light-dark-function/test/basic.css +++ b/plugins/postcss-light-dark-function/test/basic.css @@ -96,3 +96,13 @@ color-scheme: dark; } } + +@function --a() { + result: light-dark(green, blue); +} + +@function --b() { + --a: light-dark(green, blue); + + result: var(--a); +} diff --git a/plugins/postcss-light-dark-function/test/basic.expect.css b/plugins/postcss-light-dark-function/test/basic.expect.css index d127fb194a..93e5fbc5ae 100644 --- a/plugins/postcss-light-dark-function/test/basic.expect.css +++ b/plugins/postcss-light-dark-function/test/basic.expect.css @@ -153,3 +153,28 @@ color-scheme: dark; } } + +@function --a() { + --csstools-light-dark-toggle--14: var(--csstools-color-scheme--light) blue; + result: var(--csstools-light-dark-toggle--14, green); + result: light-dark(green, blue); +} + +@function --b() { + --csstools-light-dark-toggle--15: var(--csstools-color-scheme--light) blue; + --a: var(--csstools-light-dark-toggle--15, green); + + result: var(--a); + + @supports not (color: light-dark(tan, tan)) { + + & * { + --csstools-light-dark-toggle--15: var(--csstools-color-scheme--light) blue; + --a: var(--csstools-light-dark-toggle--15, green); + } + } + +@supports (color: light-dark(red, red)) { + --a: light-dark(green, blue); +} +} diff --git a/plugins/postcss-light-dark-function/test/basic.preserve-false.expect.css b/plugins/postcss-light-dark-function/test/basic.preserve-false.expect.css index 5ea3c14428..8b4be3a718 100644 --- a/plugins/postcss-light-dark-function/test/basic.preserve-false.expect.css +++ b/plugins/postcss-light-dark-function/test/basic.preserve-false.expect.css @@ -132,3 +132,20 @@ color-scheme: dark; } } + +@function --a() { + --csstools-light-dark-toggle--14: var(--csstools-color-scheme--light) blue; + result: var(--csstools-light-dark-toggle--14, green); +} + +@function --b() { + --csstools-light-dark-toggle--15: var(--csstools-color-scheme--light) blue; + --a: var(--csstools-light-dark-toggle--15, green); + + result: var(--a); + + & * { + --csstools-light-dark-toggle--15: var(--csstools-color-scheme--light) blue; + --a: var(--csstools-light-dark-toggle--15, green); + } +} diff --git a/plugins/postcss-logical-viewport-units/CHANGELOG.md b/plugins/postcss-logical-viewport-units/CHANGELOG.md index 8ec2f5a964..00f1d7bf5f 100644 --- a/plugins/postcss-logical-viewport-units/CHANGELOG.md +++ b/plugins/postcss-logical-viewport-units/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Logical Viewport Units +### Unreleased (patch) + +- Correctly nest conditional rules inside `@function` instead of cloning the `@function` rule. + ### 4.0.2 _September 25, 2026_ diff --git a/plugins/postcss-logical-viewport-units/test/basic.css b/plugins/postcss-logical-viewport-units/test/basic.css index 4545a3d1e5..1e501e4718 100644 --- a/plugins/postcss-logical-viewport-units/test/basic.css +++ b/plugins/postcss-logical-viewport-units/test/basic.css @@ -59,3 +59,13 @@ to-clone { --foo: 5vi; } } + +@function --a() { + result: 2vi; +} + +@function --b() { + --a: 2vi; + + result: var(--a); +} diff --git a/plugins/postcss-logical-viewport-units/test/basic.expect.css b/plugins/postcss-logical-viewport-units/test/basic.expect.css index 7279d74727..69506b9c6c 100644 --- a/plugins/postcss-logical-viewport-units/test/basic.expect.css +++ b/plugins/postcss-logical-viewport-units/test/basic.expect.css @@ -87,3 +87,18 @@ to-clone { } } } + +@function --a() { + result: 2vw; + result: 2vi; +} + +@function --b() { + --a: 2vw; + + result: var(--a); + +@supports (width: 1vi) { + --a: 2vi; +} +} diff --git a/plugins/postcss-logical-viewport-units/test/basic.hebrew.expect.css b/plugins/postcss-logical-viewport-units/test/basic.hebrew.expect.css index 7279d74727..69506b9c6c 100644 --- a/plugins/postcss-logical-viewport-units/test/basic.hebrew.expect.css +++ b/plugins/postcss-logical-viewport-units/test/basic.hebrew.expect.css @@ -87,3 +87,18 @@ to-clone { } } } + +@function --a() { + result: 2vw; + result: 2vi; +} + +@function --b() { + --a: 2vw; + + result: var(--a); + +@supports (width: 1vi) { + --a: 2vi; +} +} diff --git a/plugins/postcss-logical-viewport-units/test/basic.preserve-false.expect.css b/plugins/postcss-logical-viewport-units/test/basic.preserve-false.expect.css index a88b7970fe..7f8c9152d7 100644 --- a/plugins/postcss-logical-viewport-units/test/basic.preserve-false.expect.css +++ b/plugins/postcss-logical-viewport-units/test/basic.preserve-false.expect.css @@ -59,3 +59,13 @@ to-clone { --foo: 5vw; } } + +@function --a() { + result: 2vw; +} + +@function --b() { + --a: 2vw; + + result: var(--a); +} diff --git a/plugins/postcss-logical-viewport-units/test/basic.vertical.expect.css b/plugins/postcss-logical-viewport-units/test/basic.vertical.expect.css index b0d2fb6653..7ede49627a 100644 --- a/plugins/postcss-logical-viewport-units/test/basic.vertical.expect.css +++ b/plugins/postcss-logical-viewport-units/test/basic.vertical.expect.css @@ -87,3 +87,18 @@ to-clone { } } } + +@function --a() { + result: 2vh; + result: 2vi; +} + +@function --b() { + --a: 2vh; + + result: var(--a); + +@supports (width: 1vi) { + --a: 2vi; +} +} diff --git a/plugins/postcss-logical-viewport-units/test/basic.with-cloned-rules.expect.css b/plugins/postcss-logical-viewport-units/test/basic.with-cloned-rules.expect.css index ab10df3c8a..dd57c11854 100644 --- a/plugins/postcss-logical-viewport-units/test/basic.with-cloned-rules.expect.css +++ b/plugins/postcss-logical-viewport-units/test/basic.with-cloned-rules.expect.css @@ -92,3 +92,18 @@ to-clone { } } } + +@function --a() { + result: 2vw; + result: 2vi; +} + +@function --b() { + --a: 2vw; + + result: var(--a); + +@supports (width: 1vi) { + --a: 2vi; +} +} diff --git a/plugins/postcss-minify/test/basic.css b/plugins/postcss-minify/test/basic.css index b508a894a8..eda04758ab 100644 --- a/plugins/postcss-minify/test/basic.css +++ b/plugins/postcss-minify/test/basic.css @@ -49,3 +49,13 @@ div/*foo*/.foo { div/*foo*//*bar*/.foo { color:purple; } + +@function --a() { + result: color(display-p3 0.1 0.1 0.1); +} + +@function --b() { + --a: color(display-p3 0.1 0.1 0.1); + + result: var(--a); +} diff --git a/plugins/postcss-minify/test/basic.expect.css b/plugins/postcss-minify/test/basic.expect.css index f1484d4ea7..8607e7fcea 100644 --- a/plugins/postcss-minify/test/basic.expect.css +++ b/plugins/postcss-minify/test/basic.expect.css @@ -1 +1 @@ -@charset "UTF-8";@layer foo;.foo{--var: /* a comment */;bar:red}.foo{color:red}.foo{color:red}.foo{color:rgb(0 0 0)}.foo{color:rgb(0 0 0)}.foo{color:rgb(0 0 0)}@media screen and (min-width: 700px){.foo{color:red;@layer bar{}}}.b{width: auto c{color:red}}div/**/.foo{color:red}div/**/.foo{color:purple} +@charset "UTF-8";@layer foo;.foo{--var: /* a comment */;bar:red}.foo{color:red}.foo{color:red}.foo{color:rgb(0 0 0)}.foo{color:rgb(0 0 0)}.foo{color:rgb(0 0 0)}@media screen and (min-width: 700px){.foo{color:red;@layer bar{}}}.b{width: auto c{color:red}}div/**/.foo{color:red}div/**/.foo{color:purple}@function --a(){result:color(display-p3 0.1 0.1 0.1)}@function --b(){--a: color(display-p3 0.1 0.1 0.1);result:var(--a)} diff --git a/plugins/postcss-nested-calc/test/basic.css b/plugins/postcss-nested-calc/test/basic.css index a1b3c18074..9ffef75ebf 100644 --- a/plugins/postcss-nested-calc/test/basic.css +++ b/plugins/postcss-nested-calc/test/basic.css @@ -60,3 +60,13 @@ to-clone { --foo: calc(10px + calc(2px * 2)); } } + +@function --a() { + result: calc(1 + calc(2 * 2)); +} + +@function --b() { + --a: calc(1 + calc(2 * 2)); + + result: var(--a); +} diff --git a/plugins/postcss-nested-calc/test/basic.expect.css b/plugins/postcss-nested-calc/test/basic.expect.css index 88999b5194..466b2d3de6 100644 --- a/plugins/postcss-nested-calc/test/basic.expect.css +++ b/plugins/postcss-nested-calc/test/basic.expect.css @@ -75,3 +75,14 @@ to-clone { --foo: calc(10px + calc(2px * 2)); } } + +@function --a() { + result: calc(1 + (2 * 2)); + result: calc(1 + calc(2 * 2)); +} + +@function --b() { + --a: calc(1 + calc(2 * 2)); + + result: var(--a); +} diff --git a/plugins/postcss-nested-calc/test/basic.preserve-false.expect.css b/plugins/postcss-nested-calc/test/basic.preserve-false.expect.css index 9c30f912c7..aa26098af5 100644 --- a/plugins/postcss-nested-calc/test/basic.preserve-false.expect.css +++ b/plugins/postcss-nested-calc/test/basic.preserve-false.expect.css @@ -60,3 +60,13 @@ to-clone { --foo: calc(10px + calc(2px * 2)); } } + +@function --a() { + result: calc(1 + (2 * 2)); +} + +@function --b() { + --a: calc(1 + calc(2 * 2)); + + result: var(--a); +} diff --git a/plugins/postcss-nested-calc/test/basic.with-cloned-rules.expect.css b/plugins/postcss-nested-calc/test/basic.with-cloned-rules.expect.css index a232d18bb4..f799444957 100644 --- a/plugins/postcss-nested-calc/test/basic.with-cloned-rules.expect.css +++ b/plugins/postcss-nested-calc/test/basic.with-cloned-rules.expect.css @@ -80,3 +80,14 @@ to-clone { --foo: calc(10px + calc(2px * 2)); } } + +@function --a() { + result: calc(1 + (2 * 2)); + result: calc(1 + calc(2 * 2)); +} + +@function --b() { + --a: calc(1 + calc(2 * 2)); + + result: var(--a); +} diff --git a/plugins/postcss-oklab-function/CHANGELOG.md b/plugins/postcss-oklab-function/CHANGELOG.md index fd1d00cc30..61525f17fc 100644 --- a/plugins/postcss-oklab-function/CHANGELOG.md +++ b/plugins/postcss-oklab-function/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS OKLab Function +### Unreleased (patch) + +- Correctly nest conditional rules inside `@function` instead of cloning the `@function` rule. + ### 5.0.14 _October 1, 2026_ diff --git a/plugins/postcss-oklab-function/test/basic.css b/plugins/postcss-oklab-function/test/basic.css index 505ab92d10..22183919a8 100644 --- a/plugins/postcss-oklab-function/test/basic.css +++ b/plugins/postcss-oklab-function/test/basic.css @@ -177,3 +177,13 @@ --foo: oklch(60% 0.1250 180); } } + +@function --a() { + result: oklch(50% 50% 0); +} + +@function --b() { + --a: oklch(50% 50% 0); + + result: var(--a); +} diff --git a/plugins/postcss-oklab-function/test/basic.expect.css b/plugins/postcss-oklab-function/test/basic.expect.css index deb263da87..94876974aa 100644 --- a/plugins/postcss-oklab-function/test/basic.expect.css +++ b/plugins/postcss-oklab-function/test/basic.expect.css @@ -229,3 +229,13 @@ } } } + +@function --a() { + result: rgb(180, 6, 95); +} + +@function --b() { + --a: rgb(180, 6, 95); + + result: var(--a); +} diff --git a/plugins/postcss-oklab-function/test/basic.preserve-true.display-p3-false.expect.css b/plugins/postcss-oklab-function/test/basic.preserve-true.display-p3-false.expect.css index 9808f301e8..fed63ca6e4 100644 --- a/plugins/postcss-oklab-function/test/basic.preserve-true.display-p3-false.expect.css +++ b/plugins/postcss-oklab-function/test/basic.preserve-true.display-p3-false.expect.css @@ -290,3 +290,18 @@ } } } + +@function --a() { + result: rgb(180, 6, 95); + result: oklch(50% 50% 0); +} + +@function --b() { + --a: rgb(180, 6, 95); + + result: var(--a); + +@supports (color: oklab(0% 0 0%)) { + --a: oklch(50% 50% 0); +} +} diff --git a/plugins/postcss-oklab-function/test/basic.preserve-true.expect.css b/plugins/postcss-oklab-function/test/basic.preserve-true.expect.css index 1aff5a0755..898d00bcde 100644 --- a/plugins/postcss-oklab-function/test/basic.preserve-true.expect.css +++ b/plugins/postcss-oklab-function/test/basic.preserve-true.expect.css @@ -333,3 +333,18 @@ } } } + +@function --a() { + result: rgb(180, 6, 95); + result: oklch(50% 50% 0); +} + +@function --b() { + --a: rgb(180, 6, 95); + + result: var(--a); + +@supports (color: oklab(0% 0 0%)) { + --a: oklch(50% 50% 0); +} +} diff --git a/plugins/postcss-progressive-custom-properties/CHANGELOG.md b/plugins/postcss-progressive-custom-properties/CHANGELOG.md index 7050c7d91d..de16da0e13 100644 --- a/plugins/postcss-progressive-custom-properties/CHANGELOG.md +++ b/plugins/postcss-progressive-custom-properties/CHANGELOG.md @@ -3,6 +3,7 @@ ### Unreleased (patch) - Improve performance when inserting generated `@supports` rules. +- Correctly nest conditional rules inside `@function` instead of cloning the `@function` rule. ### 5.1.3 diff --git a/plugins/postcss-progressive-custom-properties/dist/index.mjs b/plugins/postcss-progressive-custom-properties/dist/index.mjs index c72404ab4d..90dadb642d 100644 --- a/plugins/postcss-progressive-custom-properties/dist/index.mjs +++ b/plugins/postcss-progressive-custom-properties/dist/index.mjs @@ -1 +1 @@ -import e from"postcss-value-parser";const r=["at","bottom","center","circle","closest-corner","closest-side","ellipse","farthest-corner","farthest-side","from","in","left","right","to","top"];function doublePositionGradients(e){const t=[],a=e.value.toLowerCase();if("function"===e.type&&("conic-gradient"===a||"linear-gradient"===a||"radial-gradient"===a||"repeating-conic-gradient"===a||"repeating-linear-gradient"===a||"repeating-radial-gradient"===a)){let a=0,o=!1,i=!1;e:for(let s=0;si.includes(e.sniff)&&(e.only_on_property??r.prop)===r.prop);let p=!1;try{e(i).walk(r=>{"function"===r.type&&a.test(r.value)&&(p=!0);try{const t=e.unit(r.value);!1!==t&&(r.dimension=t)}catch{}for(let e=0;e{"decl"===t.type&&t.prop===r.prop||e.append(t.clone())}),void e.append(r.clone());const t=o.get(r.prop.toLowerCase());if(!t?.length)return void e.append(r.clone());const a=[r];let i=r.next();for(;i;)"decl"===i.type&&t.includes(i.prop)&&a.push(i),i=i.next();a.forEach(r=>{e.append(r.clone())})}const creator=()=>({postcssPlugin:"postcss-progressive-custom-properties",prepare(){const e=new WeakMap;return{postcssPlugin:"postcss-progressive-custom-properties",OnceExit(r,{postcss:t}){r.walkAtRules(e=>{if(!p.test(e.name))return;if(inSupports(e))return;const r=[],a={propNames:new Set},o=e.clone();if(e.walkDecls(e=>{let t=e.prop;if(e.variable||(t=e.prop.toLowerCase()),!a.propNames.has(t))return void a.propNames.add(t);if(!e.variable&&!i.test(e.value))return;if(s.test(e.value))return;if(d.test(e.value))return;const o=conditionsFromValue(e,!e.variable);o.length&&(r.push(...o),e.remove())}),!r.length)return;const n=Array.from(new Set(r)).sort().join(" and ");if(!n)return;const l=t.atRule({name:"supports",params:n,source:e.source,raws:{before:"\n\n",after:"\n"}});l.append(o),e.after(l)}),r.walkDecls(r=>{if(!r.parent)return;if(inKeyframes(r))return;const a=e.get(r.parent)||{conditionalRules:[],propNames:new Set,lastConditionParams:void 0,lastConditionalRule:void 0};if(e.set(r.parent,a),r.variable){if(!a.propNames.has(r.prop))return void a.propNames.add(r.prop)}else{const e=r.prop.toLowerCase();if(!a.propNames.has(e))return void a.propNames.add(e)}if(!(r.variable||"atrule"===r.parent.type&&n.test(r.parent.name)||i.test(r.value)))return;if(s.test(r.value))return;if(d.test(r.value))return;const o=conditionsFromValue(r,!(r.variable||"atrule"===r.parent.type&&n.test(r.parent.name))).join(" and ");if(!o)return;if(a.lastConditionParams!==o&&(a.lastConditionalRule=void 0),a.lastConditionalRule)return cloneDeclarations(a.lastConditionalRule,r),void r.remove();const p=[];if(o&&p.push(t.atRule({name:"supports",params:o,source:r.parent.source,raws:{before:"\n\n",after:"\n"}})),!p.length)return;for(let e=0;e{const t=e.get(r);t&&0!==t.conditionalRules.length&&r.after(t.conditionalRules)})}}}});creator.postcss=!0;export{creator as default,creator as"module.exports"}; +import e from"postcss-value-parser";const r=["at","bottom","center","circle","closest-corner","closest-side","ellipse","farthest-corner","farthest-side","from","in","left","right","to","top"];function doublePositionGradients(e){const t=[],a=e.value.toLowerCase();if("function"===e.type&&("conic-gradient"===a||"linear-gradient"===a||"radial-gradient"===a||"repeating-conic-gradient"===a||"repeating-linear-gradient"===a||"repeating-radial-gradient"===a)){let a=0,o=!1,i=!1;e:for(let s=0;si.includes(e.sniff)&&(e.only_on_property??r.prop)===r.prop);let p=!1;try{e(i).walk(r=>{"function"===r.type&&a.test(r.value)&&(p=!0);try{const t=e.unit(r.value);!1!==t&&(r.dimension=t)}catch{}for(let e=0;e{"decl"===t.type&&t.prop===r.prop||e.append(t.clone())}),void e.append(r.clone());const t=o.get(r.prop.toLowerCase());if(!t?.length)return void e.append(r.clone());const a=[r];let i=r.next();for(;i;)"decl"===i.type&&t.includes(i.prop)&&a.push(i),i=i.next();a.forEach(r=>{e.append(r.clone())})}const creator=()=>({postcssPlugin:"postcss-progressive-custom-properties",prepare(){const e=new WeakMap;return{postcssPlugin:"postcss-progressive-custom-properties",OnceExit(r,{postcss:t}){r.walkAtRules(e=>{if(!p.test(e.name))return;if(inSupports(e))return;const r=[],a={propNames:new Set},o=e.clone();if(e.walkDecls(e=>{let t=e.prop;if(e.variable||(t=e.prop.toLowerCase()),!a.propNames.has(t))return void a.propNames.add(t);if(!e.variable&&!i.test(e.value))return;if(s.test(e.value))return;if(c.test(e.value))return;const o=conditionsFromValue(e,!e.variable);o.length&&(r.push(...o),e.remove())}),!r.length)return;const n=Array.from(new Set(r)).sort().join(" and ");if(!n)return;const l=t.atRule({name:"supports",params:n,source:e.source,raws:{before:"\n\n",after:"\n"}});l.append(o),e.after(l)}),r.walkDecls(r=>{if(!r.parent)return;if(inKeyframes(r))return;const a=e.get(r.parent)||{conditionalRules:[],propNames:new Set,lastConditionParams:void 0,lastConditionalRule:void 0};if(e.set(r.parent,a),r.variable){if(!a.propNames.has(r.prop))return void a.propNames.add(r.prop)}else{const e=r.prop.toLowerCase();if(!a.propNames.has(e))return void a.propNames.add(e)}if(!(r.variable||"atrule"===r.parent.type&&n.test(r.parent.name)||i.test(r.value)))return;if(s.test(r.value))return;if(c.test(r.value))return;const o=conditionsFromValue(r,!(r.variable||"atrule"===r.parent.type&&n.test(r.parent.name))).join(" and ");if(!o)return;if(a.lastConditionParams!==o&&(a.lastConditionalRule=void 0),a.lastConditionalRule)return cloneDeclarations(a.lastConditionalRule,r),void r.remove();const p=[];if(o&&p.push(t.atRule({name:"supports",params:o,source:r.parent.source,raws:{before:"\n\n",after:"\n"}})),!p.length)return;for(let e=0;e{const t=e.get(r);t&&0!==t.conditionalRules.length&&("atrule"===r.type&&l.test(r.name)?r.append(t.conditionalRules):r.after(t.conditionalRules))})}}}});creator.postcss=!0;export{creator as default,creator as"module.exports"}; diff --git a/plugins/postcss-progressive-custom-properties/src/index.ts b/plugins/postcss-progressive-custom-properties/src/index.ts index 5c9faca882..8c3d1be1e6 100644 --- a/plugins/postcss-progressive-custom-properties/src/index.ts +++ b/plugins/postcss-progressive-custom-properties/src/index.ts @@ -7,6 +7,7 @@ const HAS_VARIABLE_FUNCTION_REGEX = /var\(/i; const IS_INITIAL_REGEX = /^initial$/i; const IS_PROPERTY_REGEX = /^property$/i; const IS_KEYFRAMES_REGEX = /^keyframes$/i; +const IS_FUNCTION_REGEX = /^function$/i; const IS_SUPPORTS_REGEX = /^supports$/i; const EMPTY_OR_WHITESPACE_REGEX = /^\s*$/; @@ -266,18 +267,28 @@ const creator: PluginCreator = () => { const outerAtRule = atRules[0]; const innerAtRule = atRules[atRules.length - 1]; - const parentClone = decl.parent.clone(); - parentClone.removeAll(); + let conditionalRuleContainer: Container; - parentClone.raws.before = '\n'; + if (decl.parent.type === 'atrule' && IS_FUNCTION_REGEX.test(decl.parent.name)) { + // `@function` accepts conditional group rules in its body, + // so the conditional rule is nested instead of cloning the `@function`. + conditionalRuleContainer = innerAtRule; + } else { + const parentClone = decl.parent.clone(); + parentClone.removeAll(); + + parentClone.raws.before = '\n'; + + innerAtRule.append(parentClone); + conditionalRuleContainer = parentClone; + } - cloneDeclarations(parentClone, decl); + cloneDeclarations(conditionalRuleContainer, decl); decl.remove(); state.lastConditionParams = supportParams; - state.lastConditionalRule = parentClone; + state.lastConditionalRule = conditionalRuleContainer; - innerAtRule.append(parentClone); state.conditionalRules.push(outerAtRule); }); @@ -291,6 +302,12 @@ const creator: PluginCreator = () => { return; } + if (node.type === 'atrule' && IS_FUNCTION_REGEX.test(node.name)) { + // Conditional rules belong inside the `@function` body. + node.append(state.conditionalRules); + return; + } + // `after` inserts an array of nodes in order. node.after(state.conditionalRules); }); diff --git a/plugins/postcss-progressive-custom-properties/test/basic.css b/plugins/postcss-progressive-custom-properties/test/basic.css index 1d7eacf480..29e9cdf94d 100644 --- a/plugins/postcss-progressive-custom-properties/test/basic.css +++ b/plugins/postcss-progressive-custom-properties/test/basic.css @@ -379,3 +379,14 @@ --prop-8: 1px; --prop-8: 2lvb; } + +@function --a() { + result: color(display-p3 0.1 0.1 0.1); +} + +@function --b() { + --a: rgb(26, 26, 26); + --a: color(display-p3 0.1 0.1 0.1); + + result: var(--a); +} diff --git a/plugins/postcss-progressive-custom-properties/test/basic.expect.css b/plugins/postcss-progressive-custom-properties/test/basic.expect.css index acea08c616..798c42fd45 100644 --- a/plugins/postcss-progressive-custom-properties/test/basic.expect.css +++ b/plugins/postcss-progressive-custom-properties/test/basic.expect.css @@ -685,3 +685,17 @@ --prop-8: 2lvb; } } + +@function --a() { + result: color(display-p3 0.1 0.1 0.1); +} + +@function --b() { + --a: rgb(26, 26, 26); + + result: var(--a); + +@supports (color: color(display-p3 0 0 0%)) { + --a: color(display-p3 0.1 0.1 0.1); +} +} diff --git a/plugins/postcss-random-function/test/basic.css b/plugins/postcss-random-function/test/basic.css index ea80ea6e11..eccb3877d9 100644 --- a/plugins/postcss-random-function/test/basic.css +++ b/plugins/postcss-random-function/test/basic.css @@ -110,3 +110,13 @@ --foo: random(0, 10); } } + +@function --a() { + result: random(0px, 10px); +} + +@function --b() { + --a: random(0px, 10px); + + result: var(--a); +} diff --git a/plugins/postcss-random-function/test/basic.expect.css b/plugins/postcss-random-function/test/basic.expect.css index 67a2968b57..b725f4dd55 100644 --- a/plugins/postcss-random-function/test/basic.expect.css +++ b/plugins/postcss-random-function/test/basic.expect.css @@ -1,5 +1,5 @@ .random-1 { - z-index: calc(2.09594); + z-index: calc(7.35131); } .random-2 { @@ -7,15 +7,15 @@ } .random-3 { - z-index: calc(0.56703); + z-index: calc(5.34723); } .random-4 { - z-index: calc(6.78979); + z-index: calc(1.33748); } .random-11 { - width: calc(2.09594px); + width: calc(7.35131px); } .random-12 { @@ -23,68 +23,68 @@ } .random-13 { - width: calc(0.56703px); + width: calc(5.34723px); } .random-14 { - width: calc(6.78979px); + width: calc(1.33748px); } .random-15 { padding: calc(5px) calc(5px); - margin: calc(2.09594px) calc(2.09594px); - inset: calc(0.56703px) calc(0.56703px); - border-top-right-radius: calc(2.09594px); - border-top-left-radius: calc(2.09594px); - border-bottom-right-radius: calc(0.56703px); - border-bottom-left-radius: calc(0.56703px); + margin: calc(7.35131px) calc(7.35131px); + inset: calc(5.34723px) calc(5.34723px); + border-top-right-radius: calc(7.35131px); + border-top-left-radius: calc(7.35131px); + border-bottom-right-radius: calc(5.34723px); + border-bottom-left-radius: calc(5.34723px); } .random-15 { padding: calc(5px) calc(5px); - margin: calc(2.09594px) calc(2.09594px); - inset: calc(0.56703px) calc(0.56703px); - border-top-right-radius: calc(2.09594px); - border-top-left-radius: calc(2.09594px); - border-bottom-right-radius: calc(0.56703px); - border-bottom-left-radius: calc(0.56703px); + margin: calc(7.35131px) calc(7.35131px); + inset: calc(5.34723px) calc(5.34723px); + border-top-right-radius: calc(7.35131px); + border-top-left-radius: calc(7.35131px); + border-bottom-right-radius: calc(5.34723px); + border-bottom-left-radius: calc(5.34723px); } .random-15-b { padding: calc(5px) calc(5px); - margin: calc(2.09594px) calc(2.09594px); - inset: calc(0.56703px) calc(0.56703px); - border-top-right-radius: calc(2.09594px); - border-top-left-radius: calc(2.09594px); - border-bottom-right-radius: calc(0.56703px); - border-bottom-left-radius: calc(0.56703px); + margin: calc(7.35131px) calc(7.35131px); + inset: calc(5.34723px) calc(5.34723px); + border-top-right-radius: calc(7.35131px); + border-top-left-radius: calc(7.35131px); + border-bottom-right-radius: calc(5.34723px); + border-bottom-left-radius: calc(5.34723px); } .random-16 { - margin: calc(2.90875px) calc(2.90875px); - inset: calc(4.37511px) calc(4.37511px); - border-top-right-radius: calc(2.90875px); - border-top-left-radius: calc(2.90875px); - border-bottom-right-radius: calc(4.37511px); - border-bottom-left-radius: calc(4.37511px); + margin: calc(7.56246px) calc(7.56246px); + inset: calc(4.3901px) calc(4.3901px); + border-top-right-radius: calc(7.56246px); + border-top-left-radius: calc(7.56246px); + border-bottom-right-radius: calc(4.3901px); + border-bottom-left-radius: calc(4.3901px); } .random-16 { - margin: calc(2.90875px) calc(2.90875px); - inset: calc(4.37511px) calc(4.37511px); - border-top-right-radius: calc(2.90875px); - border-top-left-radius: calc(2.90875px); - border-bottom-right-radius: calc(4.37511px); - border-bottom-left-radius: calc(4.37511px); + margin: calc(7.56246px) calc(7.56246px); + inset: calc(4.3901px) calc(4.3901px); + border-top-right-radius: calc(7.56246px); + border-top-left-radius: calc(7.56246px); + border-bottom-right-radius: calc(4.3901px); + border-bottom-left-radius: calc(4.3901px); } .random-16-b { - margin: calc(5.45597px) calc(5.45597px); - inset: calc(7.17757px) calc(7.17757px); - border-top-right-radius: calc(5.45597px); - border-top-left-radius: calc(5.45597px); - border-bottom-right-radius: calc(7.17757px); - border-bottom-left-radius: calc(7.17757px); + margin: calc(8.94629px) calc(8.94629px); + inset: calc(2.92643px) calc(2.92643px); + border-top-right-radius: calc(8.94629px); + border-top-left-radius: calc(8.94629px); + border-bottom-right-radius: calc(2.92643px); + border-bottom-left-radius: calc(2.92643px); } .ignore-1 { @@ -102,11 +102,21 @@ @property --foo { inherits: false; - initial-value: calc(2.09594); + initial-value: calc(7.35131); } @keyframes --foo { to { - --foo: calc(2.09594); + --foo: calc(7.35131); } } + +@function --a() { + result: calc(7.35131px); +} + +@function --b() { + --a: calc(7.35131px); + + result: var(--a); +} diff --git a/plugins/postcss-random-function/test/basic.preserve-true.expect.css b/plugins/postcss-random-function/test/basic.preserve-true.expect.css index 80b8e9a0ea..f9f6696e1f 100644 --- a/plugins/postcss-random-function/test/basic.preserve-true.expect.css +++ b/plugins/postcss-random-function/test/basic.preserve-true.expect.css @@ -1,5 +1,5 @@ .random-1 { - z-index: calc(2.09594); + z-index: calc(7.35131); z-index: random(0, 10); } @@ -8,17 +8,17 @@ } .random-3 { - z-index: calc(0.56703); + z-index: calc(5.34723); z-index: random(--foo, 0, 10); } .random-4 { - z-index: calc(6.78979); + z-index: calc(1.33748); z-index: random(--bar, 0, 10); } .random-11 { - width: calc(2.09594px); + width: calc(7.35131px); width: random(0px, 10px); } @@ -27,108 +27,108 @@ } .random-13 { - width: calc(0.56703px); + width: calc(5.34723px); width: random(--foo, 0px, 10px); } .random-14 { - width: calc(6.78979px); + width: calc(1.33748px); width: random(--bar, 0px, 10px); } .random-15 { padding: calc(5px) calc(5px); padding: random(fixed 0.5, 0px, 10px) random(fixed 0.5, 0px, 10px); - margin: calc(2.09594px) calc(2.09594px); + margin: calc(7.35131px) calc(7.35131px); margin: random(0px, 10px) random(0px, 10px); - inset: calc(0.56703px) calc(0.56703px); + inset: calc(5.34723px) calc(5.34723px); inset: random(--foo, 0px, 10px) random(--foo, 0px, 10px); - border-top-right-radius: calc(2.09594px); + border-top-right-radius: calc(7.35131px); border-top-right-radius: random(0px, 10px); - border-top-left-radius: calc(2.09594px); + border-top-left-radius: calc(7.35131px); border-top-left-radius: random(0px, 10px); - border-bottom-right-radius: calc(0.56703px); + border-bottom-right-radius: calc(5.34723px); border-bottom-right-radius: random(--foo, 0px, 10px); - border-bottom-left-radius: calc(0.56703px); + border-bottom-left-radius: calc(5.34723px); border-bottom-left-radius: random(--foo, 0px, 10px); } .random-15 { padding: calc(5px) calc(5px); padding: random(fixed 0.5, 0px, 10px) random(fixed 0.5, 0px, 10px); - margin: calc(2.09594px) calc(2.09594px); + margin: calc(7.35131px) calc(7.35131px); margin: random(0px, 10px) random(0px, 10px); - inset: calc(0.56703px) calc(0.56703px); + inset: calc(5.34723px) calc(5.34723px); inset: random(--foo, 0px, 10px) random(--foo, 0px, 10px); - border-top-right-radius: calc(2.09594px); + border-top-right-radius: calc(7.35131px); border-top-right-radius: random(0px, 10px); - border-top-left-radius: calc(2.09594px); + border-top-left-radius: calc(7.35131px); border-top-left-radius: random(0px, 10px); - border-bottom-right-radius: calc(0.56703px); + border-bottom-right-radius: calc(5.34723px); border-bottom-right-radius: random(--foo, 0px, 10px); - border-bottom-left-radius: calc(0.56703px); + border-bottom-left-radius: calc(5.34723px); border-bottom-left-radius: random(--foo, 0px, 10px); } .random-15-b { padding: calc(5px) calc(5px); padding: random(fixed 0.5, 0px, 10px) random(fixed 0.5, 0px, 10px); - margin: calc(2.09594px) calc(2.09594px); + margin: calc(7.35131px) calc(7.35131px); margin: random(0px, 10px) random(0px, 10px); - inset: calc(0.56703px) calc(0.56703px); + inset: calc(5.34723px) calc(5.34723px); inset: random(--foo, 0px, 10px) random(--foo, 0px, 10px); - border-top-right-radius: calc(2.09594px); + border-top-right-radius: calc(7.35131px); border-top-right-radius: random(0px, 10px); - border-top-left-radius: calc(2.09594px); + border-top-left-radius: calc(7.35131px); border-top-left-radius: random(0px, 10px); - border-bottom-right-radius: calc(0.56703px); + border-bottom-right-radius: calc(5.34723px); border-bottom-right-radius: random(--foo, 0px, 10px); - border-bottom-left-radius: calc(0.56703px); + border-bottom-left-radius: calc(5.34723px); border-bottom-left-radius: random(--foo, 0px, 10px); } .random-16 { - margin: calc(2.90875px) calc(2.90875px); + margin: calc(7.56246px) calc(7.56246px); margin: random(element-scoped, 0px, 10px) random(element-scoped, 0px, 10px); - inset: calc(4.37511px) calc(4.37511px); + inset: calc(4.3901px) calc(4.3901px); inset: random(--foo element-scoped, 0px, 10px) random(--foo element-scoped, 0px, 10px); - border-top-right-radius: calc(2.90875px); + border-top-right-radius: calc(7.56246px); border-top-right-radius: random(element-scoped, 0px, 10px); - border-top-left-radius: calc(2.90875px); + border-top-left-radius: calc(7.56246px); border-top-left-radius: random(element-scoped, 0px, 10px); - border-bottom-right-radius: calc(4.37511px); + border-bottom-right-radius: calc(4.3901px); border-bottom-right-radius: random(--foo element-scoped, 0px, 10px); - border-bottom-left-radius: calc(4.37511px); + border-bottom-left-radius: calc(4.3901px); border-bottom-left-radius: random(--foo element-scoped, 0px, 10px); } .random-16 { - margin: calc(2.90875px) calc(2.90875px); + margin: calc(7.56246px) calc(7.56246px); margin: random(element-scoped, 0px, 10px) random(element-scoped, 0px, 10px); - inset: calc(4.37511px) calc(4.37511px); + inset: calc(4.3901px) calc(4.3901px); inset: random(--foo element-scoped, 0px, 10px) random(--foo element-scoped, 0px, 10px); - border-top-right-radius: calc(2.90875px); + border-top-right-radius: calc(7.56246px); border-top-right-radius: random(element-scoped, 0px, 10px); - border-top-left-radius: calc(2.90875px); + border-top-left-radius: calc(7.56246px); border-top-left-radius: random(element-scoped, 0px, 10px); - border-bottom-right-radius: calc(4.37511px); + border-bottom-right-radius: calc(4.3901px); border-bottom-right-radius: random(--foo element-scoped, 0px, 10px); - border-bottom-left-radius: calc(4.37511px); + border-bottom-left-radius: calc(4.3901px); border-bottom-left-radius: random(--foo element-scoped, 0px, 10px); } .random-16-b { - margin: calc(5.45597px) calc(5.45597px); + margin: calc(8.94629px) calc(8.94629px); margin: random(element-scoped, 0px, 10px) random(element-scoped, 0px, 10px); - inset: calc(7.17757px) calc(7.17757px); + inset: calc(2.92643px) calc(2.92643px); inset: random(--foo element-scoped, 0px, 10px) random(--foo element-scoped, 0px, 10px); - border-top-right-radius: calc(5.45597px); + border-top-right-radius: calc(8.94629px); border-top-right-radius: random(element-scoped, 0px, 10px); - border-top-left-radius: calc(5.45597px); + border-top-left-radius: calc(8.94629px); border-top-left-radius: random(element-scoped, 0px, 10px); - border-bottom-right-radius: calc(7.17757px); + border-bottom-right-radius: calc(2.92643px); border-bottom-right-radius: random(--foo element-scoped, 0px, 10px); - border-bottom-left-radius: calc(7.17757px); + border-bottom-left-radius: calc(2.92643px); border-bottom-left-radius: random(--foo element-scoped, 0px, 10px); } @@ -152,7 +152,19 @@ @keyframes --foo { to { - --foo: calc(2.09594); + --foo: calc(7.35131); --foo: random(0, 10); } } + +@function --a() { + result: calc(7.35131px); + result: random(0px, 10px); +} + +@function --b() { + --a: calc(7.35131px); + --a: random(0px, 10px); + + result: var(--a); +} diff --git a/plugins/postcss-rebase-url/test/basic.css b/plugins/postcss-rebase-url/test/basic.css index 078b70818c..aa7f0d90f1 100644 --- a/plugins/postcss-rebase-url/test/basic.css +++ b/plugins/postcss-rebase-url/test/basic.css @@ -8,3 +8,13 @@ .outside_root { background: url("../../../images/green.png"); } + +@function --a() { + result: url(./images/green.png); +} + +@function --b() { + --a: url(./images/green.png); + + result: var(--a); +} diff --git a/plugins/postcss-rebase-url/test/basic.expect.css b/plugins/postcss-rebase-url/test/basic.expect.css index 29c7f537e9..1161c05ba9 100644 --- a/plugins/postcss-rebase-url/test/basic.expect.css +++ b/plugins/postcss-rebase-url/test/basic.expect.css @@ -67,3 +67,13 @@ .outside_root { background: url("../../../images/green.png"); } + +@function --a() { + result: url(images/green.png); +} + +@function --b() { + --a: url(./images/green.png); + + result: var(--a); +} diff --git a/plugins/postcss-relative-color-syntax/CHANGELOG.md b/plugins/postcss-relative-color-syntax/CHANGELOG.md index 6f2af2d3c2..e8f01bd2bb 100644 --- a/plugins/postcss-relative-color-syntax/CHANGELOG.md +++ b/plugins/postcss-relative-color-syntax/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Relative Color Syntax +### Unreleased (patch) + +- Correctly nest conditional rules inside `@function` instead of cloning the `@function` rule. + ### 4.0.14 _October 1, 2026_ diff --git a/plugins/postcss-relative-color-syntax/test/basic.css b/plugins/postcss-relative-color-syntax/test/basic.css index 9ee349b801..1316e75532 100644 --- a/plugins/postcss-relative-color-syntax/test/basic.css +++ b/plugins/postcss-relative-color-syntax/test/basic.css @@ -123,3 +123,13 @@ --foo: hsla(from blue h s l / alpha); } } + +@function --a() { + result: rgb(from blue r g b); +} + +@function --b() { + --a: rgb(from blue r g b); + + result: var(--a); +} diff --git a/plugins/postcss-relative-color-syntax/test/basic.expect.css b/plugins/postcss-relative-color-syntax/test/basic.expect.css index 19a3cd7c0a..5fe4f98f4e 100644 --- a/plugins/postcss-relative-color-syntax/test/basic.expect.css +++ b/plugins/postcss-relative-color-syntax/test/basic.expect.css @@ -133,3 +133,13 @@ --foo: rgb(0, 0, 255); } } + +@function --a() { + result: rgb(0, 0, 255); +} + +@function --b() { + --a: rgb(0, 0, 255); + + result: var(--a); +} diff --git a/plugins/postcss-relative-color-syntax/test/basic.preserve-true.expect.css b/plugins/postcss-relative-color-syntax/test/basic.preserve-true.expect.css index 3daab7ae16..b4820485c0 100644 --- a/plugins/postcss-relative-color-syntax/test/basic.preserve-true.expect.css +++ b/plugins/postcss-relative-color-syntax/test/basic.preserve-true.expect.css @@ -243,3 +243,18 @@ } } } + +@function --a() { + result: rgb(0, 0, 255); + result: rgb(from blue r g b); +} + +@function --b() { + --a: rgb(0, 0, 255); + + result: var(--a); + +@supports (color: lab(from red l 1 1% / calc(alpha + 0.1))) { + --a: rgb(from blue r g b); +} +} diff --git a/plugins/postcss-rewrite-url/test/basic.css b/plugins/postcss-rewrite-url/test/basic.css index eadf2f4eda..8e21aee064 100644 --- a/plugins/postcss-rewrite-url/test/basic.css +++ b/plugins/postcss-rewrite-url/test/basic.css @@ -41,3 +41,13 @@ /* A filter on the original values, only a single item should be removed */ background: rewrite-url('foo.png' --url-modifier-d crossorigin(use-credentials) referrerpolicy(no-referrer)); } + +@function --a() { + result: rewrite-url('foo.png'); +} + +@function --b() { + --a: rewrite-url('foo.png'); + + result: var(--a); +} diff --git a/plugins/postcss-rewrite-url/test/basic.expect.css b/plugins/postcss-rewrite-url/test/basic.expect.css index 43ca57f8fe..da4b2f69a0 100644 --- a/plugins/postcss-rewrite-url/test/basic.expect.css +++ b/plugins/postcss-rewrite-url/test/basic.expect.css @@ -41,3 +41,13 @@ /* A filter on the original values, only a single item should be removed */ background: url("foo.png#modified-d" crossorigin(use-credentials) referrerpolicy(no-referrer)); } + +@function --a() { + result: url("foo.png#modified"); +} + +@function --b() { + --a: url("foo.png#modified"); + + result: var(--a); +} diff --git a/plugins/postcss-sign-functions/test/basic.css b/plugins/postcss-sign-functions/test/basic.css index 12d94cfc3e..2c1f477430 100644 --- a/plugins/postcss-sign-functions/test/basic.css +++ b/plugins/postcss-sign-functions/test/basic.css @@ -80,3 +80,13 @@ --foo: sign(10px); } } + +@function --a() { + result: sign(-10px); +} + +@function --b() { + --a: sign(-10px); + + result: var(--a); +} diff --git a/plugins/postcss-sign-functions/test/basic.expect.css b/plugins/postcss-sign-functions/test/basic.expect.css index 2bb1299baf..1978c3c342 100644 --- a/plugins/postcss-sign-functions/test/basic.expect.css +++ b/plugins/postcss-sign-functions/test/basic.expect.css @@ -80,3 +80,13 @@ --foo: calc(1); } } + +@function --a() { + result: calc(-1); +} + +@function --b() { + --a: calc(-1); + + result: var(--a); +} diff --git a/plugins/postcss-sign-functions/test/basic.preserve-true.expect.css b/plugins/postcss-sign-functions/test/basic.preserve-true.expect.css index dc63bd71ec..c5c6782e04 100644 --- a/plugins/postcss-sign-functions/test/basic.preserve-true.expect.css +++ b/plugins/postcss-sign-functions/test/basic.preserve-true.expect.css @@ -97,3 +97,15 @@ --foo: sign(10px); } } + +@function --a() { + result: calc(-1); + result: sign(-10px); +} + +@function --b() { + --a: calc(-1); + --a: sign(-10px); + + result: var(--a); +} diff --git a/plugins/postcss-stepped-value-functions/test/basic.css b/plugins/postcss-stepped-value-functions/test/basic.css index a306a210ce..b37629cc6a 100644 --- a/plugins/postcss-stepped-value-functions/test/basic.css +++ b/plugins/postcss-stepped-value-functions/test/basic.css @@ -78,3 +78,13 @@ --foo: mod(-140deg, -90deg); } } + +@function --a() { + result: round(2.5px, 1px); +} + +@function --b() { + --a: round(2.5px, 1px); + + result: var(--a); +} diff --git a/plugins/postcss-stepped-value-functions/test/basic.expect.css b/plugins/postcss-stepped-value-functions/test/basic.expect.css index c66b9f1123..e1dc53bd8f 100644 --- a/plugins/postcss-stepped-value-functions/test/basic.expect.css +++ b/plugins/postcss-stepped-value-functions/test/basic.expect.css @@ -78,3 +78,13 @@ --foo: calc(-50deg); } } + +@function --a() { + result: calc(3px); +} + +@function --b() { + --a: calc(3px); + + result: var(--a); +} diff --git a/plugins/postcss-stepped-value-functions/test/basic.preserve-true.expect.css b/plugins/postcss-stepped-value-functions/test/basic.preserve-true.expect.css index 2a1c7550a6..59bc845424 100644 --- a/plugins/postcss-stepped-value-functions/test/basic.preserve-true.expect.css +++ b/plugins/postcss-stepped-value-functions/test/basic.preserve-true.expect.css @@ -107,3 +107,15 @@ --foo: mod(-140deg, -90deg); } } + +@function --a() { + result: calc(3px); + result: round(2.5px, 1px); +} + +@function --b() { + --a: calc(3px); + --a: round(2.5px, 1px); + + result: var(--a); +} diff --git a/plugins/postcss-system-ui-font-family/CHANGELOG.md b/plugins/postcss-system-ui-font-family/CHANGELOG.md index e056ceff89..e5643c5642 100644 --- a/plugins/postcss-system-ui-font-family/CHANGELOG.md +++ b/plugins/postcss-system-ui-font-family/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS System UI Font Family +### Unreleased (patch) + +- Add support for the `result` descriptor in `@function`. + ### 2.0.2 _October 1, 2026_ diff --git a/plugins/postcss-system-ui-font-family/dist/index.mjs b/plugins/postcss-system-ui-font-family/dist/index.mjs index 7800b2c946..e155837966 100644 --- a/plugins/postcss-system-ui-font-family/dist/index.mjs +++ b/plugins/postcss-system-ui-font-family/dist/index.mjs @@ -1 +1 @@ -import{parseCommaSeparatedListOfComponentValues as e,isWhiteSpaceOrCommentNode as s,isTokenNode as t,stringify as o,TokenNode as n}from"@csstools/css-parser-algorithms";import{tokenize as r,isTokenIdent as i,TokenType as l}from"@csstools/css-tokenizer";const a=/^font(?:-family)?$/i,c=["system-ui","-apple-system","Segoe UI","Roboto","Ubuntu","Cantarell","Noto Sans","sans-serif"];const u=c.join(","),creator=p=>{const f=Object.assign({preserve:!0},p);return{postcssPlugin:"postcss-system-ui-font-family",Declaration(p){if(!p.variable&&!a.test(p.prop))return;if(p.value.includes(u))return;const m=p.value,v=r({css:m}),g=e(v),y=new Map;let h=-1;e:for(let e=0;e!("system-ui"!==e||!j)||!b.has(e)).map(e=>[new n([l.Ident,e,-1,-1,{value:e}])]));var b,j;if(0===d.length)return;g.splice(h,1,...d);const w=o(g);w!==m&&(p.cloneBefore({prop:p.prop,value:w}),p.remove())}}};creator.postcss=!0;export{creator as default,creator as"module.exports"}; +import{parseCommaSeparatedListOfComponentValues as e,isWhiteSpaceOrCommentNode as t,isTokenNode as s,stringify as n,TokenNode as o}from"@csstools/css-parser-algorithms";import{tokenize as r,isTokenIdent as i,TokenType as u}from"@csstools/css-tokenizer";const l=/^font(?:-family)?$/i,a=/^function$/i,c=/^result$/i;function isInFunctionResult(e){if(!c.test(e.prop))return!1;let t=e.parent;for(;t;){if("atrule"===t.type&&a.test(t.name))return!0;t=t.parent}return!1}const p=["system-ui","-apple-system","Segoe UI","Roboto","Ubuntu","Cantarell","Noto Sans","sans-serif"];const f=p.join(","),creator=a=>{const c=Object.assign({preserve:!0},a);return{postcssPlugin:"postcss-system-ui-font-family",Declaration(a){const m=isInFunctionResult(a);if(!a.variable&&!l.test(a.prop)&&!m)return;if(a.value.includes(f))return;const v=a.value,y=r({css:v}),g=e(y),h=new Map;let d=-1;e:for(let e=0;e!("system-ui"!==e||!j)||!I.has(e)).map(e=>[new o([u.Ident,e,-1,-1,{value:e}])]));var I,j;if(0===b.length)return;g.splice(d,1,...b);const w=n(g);w!==v&&(a.cloneBefore({prop:a.prop,value:w}),m||a.remove())}}};creator.postcss=!0;export{creator as default,creator as"module.exports"}; diff --git a/plugins/postcss-system-ui-font-family/src/index.ts b/plugins/postcss-system-ui-font-family/src/index.ts index 671ab349ba..06e779703f 100644 --- a/plugins/postcss-system-ui-font-family/src/index.ts +++ b/plugins/postcss-system-ui-font-family/src/index.ts @@ -1,7 +1,7 @@ import type { ComponentValue} from '@csstools/css-parser-algorithms'; import { isTokenNode, isWhiteSpaceOrCommentNode, parseCommaSeparatedListOfComponentValues, stringify, TokenNode } from '@csstools/css-parser-algorithms'; import { isTokenIdent, tokenize, TokenType } from '@csstools/css-tokenizer'; -import type { PluginCreator } from 'postcss'; +import type { AtRule, Declaration, Document, PluginCreator } from 'postcss'; /** postcss-system-ui-font-family plugin options */ export type pluginOptions = { @@ -10,6 +10,25 @@ export type pluginOptions = { }; const PROPERTY_REGEX = /^font(?:-family)?$/i; +const IS_FUNCTION_REGEX = /^function$/i; +const RESULT_REGEX = /^result$/i; + +function isInFunctionResult(decl: Declaration): boolean { + if (!RESULT_REGEX.test(decl.prop)) { + return false; + } + + let parent: typeof decl.parent | Document = decl.parent; + while (parent) { + if (parent.type === 'atrule' && IS_FUNCTION_REGEX.test((parent as AtRule).name)) { + return true; + } + + parent = parent.parent; + } + + return false; +} const systemUiFamilies = [ 'system-ui', @@ -49,7 +68,9 @@ const creator: PluginCreator = (opts?: pluginOptions) => { return { postcssPlugin: 'postcss-system-ui-font-family', Declaration(decl): void { - if (!decl.variable && !PROPERTY_REGEX.test(decl.prop)) { + const isResultDescriptor = isInFunctionResult(decl); + + if (!decl.variable && !PROPERTY_REGEX.test(decl.prop) && !isResultDescriptor) { return; } @@ -120,6 +141,11 @@ const creator: PluginCreator = (opts?: pluginOptions) => { value: modified, }); + if (isResultDescriptor) { + // `result` descriptors are not properties: keep the original dynamic value. + return; + } + decl.remove(); }, }; diff --git a/plugins/postcss-system-ui-font-family/test/basic.css b/plugins/postcss-system-ui-font-family/test/basic.css index e1aabc4687..3a65cc3810 100644 --- a/plugins/postcss-system-ui-font-family/test/basic.css +++ b/plugins/postcss-system-ui-font-family/test/basic.css @@ -25,3 +25,13 @@ .comment-between-idents { font-family: system-ui, Segoe /* foo */UI; } + +@function --a() { + result: system-ui; +} + +@function --b() { + --a: system-ui; + + result: var(--a); +} diff --git a/plugins/postcss-system-ui-font-family/test/basic.expect.css b/plugins/postcss-system-ui-font-family/test/basic.expect.css index f04ac87b55..9bfefcc74a 100644 --- a/plugins/postcss-system-ui-font-family/test/basic.expect.css +++ b/plugins/postcss-system-ui-font-family/test/basic.expect.css @@ -25,3 +25,14 @@ .comment-between-idents { font-family: system-ui,-apple-system,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif, Segoe UI; } + +@function --a() { + result: system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif; + result: system-ui; +} + +@function --b() { + --a: system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif; + + result: var(--a); +} diff --git a/plugins/postcss-trigonometric-functions/test/basic.css b/plugins/postcss-trigonometric-functions/test/basic.css index f497ab48dd..8bc480051e 100644 --- a/plugins/postcss-trigonometric-functions/test/basic.css +++ b/plugins/postcss-trigonometric-functions/test/basic.css @@ -220,3 +220,13 @@ --foo: sin(45deg); } } + +@function --a() { + result: sin(45deg); +} + +@function --b() { + --a: sin(45deg); + + result: var(--a); +} diff --git a/plugins/postcss-trigonometric-functions/test/basic.expect.css b/plugins/postcss-trigonometric-functions/test/basic.expect.css index 2f2d4aeff4..b1b3d0095a 100644 --- a/plugins/postcss-trigonometric-functions/test/basic.expect.css +++ b/plugins/postcss-trigonometric-functions/test/basic.expect.css @@ -220,3 +220,13 @@ --foo: calc(0.70711); } } + +@function --a() { + result: calc(0.70711); +} + +@function --b() { + --a: calc(0.70711); + + result: var(--a); +} diff --git a/plugins/postcss-trigonometric-functions/test/basic.preserve-true.expect.css b/plugins/postcss-trigonometric-functions/test/basic.preserve-true.expect.css index 11d9f46c4a..47d25b0f0f 100644 --- a/plugins/postcss-trigonometric-functions/test/basic.preserve-true.expect.css +++ b/plugins/postcss-trigonometric-functions/test/basic.preserve-true.expect.css @@ -367,3 +367,15 @@ --foo: sin(45deg); } } + +@function --a() { + result: calc(0.70711); + result: sin(45deg); +} + +@function --b() { + --a: calc(0.70711); + --a: sin(45deg); + + result: var(--a); +} From 449d0bef7e017a1b5880e4d6e1e5b9a982007924 Mon Sep 17 00:00:00 2001 From: Romain Menke Date: Thu, 1 Oct 2026 22:52:33 +0200 Subject: [PATCH 2/5] more tests --- .../test/basic.css | 23 +++++++++++++ .../test/basic.expect.css | 33 +++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/plugins/postcss-progressive-custom-properties/test/basic.css b/plugins/postcss-progressive-custom-properties/test/basic.css index 29e9cdf94d..e2d6468f1c 100644 --- a/plugins/postcss-progressive-custom-properties/test/basic.css +++ b/plugins/postcss-progressive-custom-properties/test/basic.css @@ -390,3 +390,26 @@ result: var(--a); } + +:root { + --firebrick: rgba(255, 155, 186, 0.5); + --firebrick: color(display-p3 1 0.58119 0.72367 / 0.5); + --firebrick: oklch(80% 0.4 0.039 / 50%); +} + + +:root { + --firebrick-2: rgba(255, 155, 186, 0.5); +} + +@media (color-gamut: p3) { + :root { + --firebrick-2: color(display-p3 1 0.58119 0.72367 / 0.5); + } +} + +@media (color-gamut: rec2020) { + :root { + --firebrick-2: oklch(80% 0.4 0.039 / 50%); + } +} diff --git a/plugins/postcss-progressive-custom-properties/test/basic.expect.css b/plugins/postcss-progressive-custom-properties/test/basic.expect.css index 798c42fd45..3a46e6383f 100644 --- a/plugins/postcss-progressive-custom-properties/test/basic.expect.css +++ b/plugins/postcss-progressive-custom-properties/test/basic.expect.css @@ -699,3 +699,36 @@ --a: color(display-p3 0.1 0.1 0.1); } } + +:root { + --firebrick: rgba(255, 155, 186, 0.5); +} + +@supports (color: color(display-p3 0 0 0%)) { +:root { + --firebrick: color(display-p3 1 0.58119 0.72367 / 0.5); +} +} + +@supports (color: oklab(0% 0 0%)) { +:root { + --firebrick: oklch(80% 0.4 0.039 / 50%); +} +} + + +:root { + --firebrick-2: rgba(255, 155, 186, 0.5); +} + +@media (color-gamut: p3) { + :root { + --firebrick-2: color(display-p3 1 0.58119 0.72367 / 0.5); + } +} + +@media (color-gamut: rec2020) { + :root { + --firebrick-2: oklch(80% 0.4 0.039 / 50%); + } +} From 61fa00cf39b84170ef919960c6fffc7faaaf0145 Mon Sep 17 00:00:00 2001 From: Romain Menke Date: Thu, 1 Oct 2026 22:55:51 +0200 Subject: [PATCH 3/5] more tests --- .../postcss-preset-env/test/_tape.mjs | 15 + .../test/postcss-functions.expect.css | 65 ----- ...ostcss-functions.preserve-false.expect.css | 193 ++++++++++++ ...postcss-functions.preserve-true.expect.css | 275 ++++++++++++++++++ plugins/postcss-gamut-mapping/test/basic.css | 22 ++ .../test/basic.expect.css | 44 +++ .../postcss-oklab-function/test/variables.css | 5 + .../test/variables.expect.css | 11 + ....preserve-true.display-p3-false.expect.css | 11 + .../test/variables.preserve-true.expect.css | 17 ++ 10 files changed, 593 insertions(+), 65 deletions(-) create mode 100644 plugin-packs/postcss-preset-env/test/postcss-functions.preserve-false.expect.css create mode 100644 plugin-packs/postcss-preset-env/test/postcss-functions.preserve-true.expect.css diff --git a/plugin-packs/postcss-preset-env/test/_tape.mjs b/plugin-packs/postcss-preset-env/test/_tape.mjs index 56a02a1a4b..8097debb41 100644 --- a/plugin-packs/postcss-preset-env/test/_tape.mjs +++ b/plugin-packs/postcss-preset-env/test/_tape.mjs @@ -452,10 +452,25 @@ postcssTape(plugin)({ }, 'postcss-functions': { message: 'does not clone `@function` rules when generating conditional rules', + options: { + stage: 0, + browsers: '> 0%', + }, + }, + 'postcss-functions:preserve-true': { + message: 'does not clone `@function` rules when generating conditional rules with { preserve: true }', options: { preserve: true, stage: 0, browsers: '> 0%', }, }, + 'postcss-functions:preserve-false': { + message: 'does not clone `@function` rules when generating conditional rules with { preserve: false }', + options: { + preserve: false, + stage: 0, + browsers: '> 0%', + }, + }, }); diff --git a/plugin-packs/postcss-preset-env/test/postcss-functions.expect.css b/plugin-packs/postcss-preset-env/test/postcss-functions.expect.css index 0d6f526715..71e2cc2f45 100644 --- a/plugin-packs/postcss-preset-env/test/postcss-functions.expect.css +++ b/plugin-packs/postcss-preset-env/test/postcss-functions.expect.css @@ -12,113 +12,72 @@ @function --color-function() { result: rgb(26, 26, 26); - result: color(display-p3 0.1 0.1 0.1); } @function --color-function-var() { --local: rgb(26, 26, 26); result: var(--local); - -@supports (color: color(display-p3 0 0 0%)) { - --local: color(display-p3 0.1 0.1 0.1); -} } @function --lab-function() { result: rgb(179, 35, 35); - result: lab(40% 56.6 39); } @function --lab-function-var() { --local: rgb(179, 35, 35); result: var(--local); - -@supports (color: lab(0% 0 0%)) { - --local: lab(40% 56.6 39); -} } @function --oklab-function() { result: rgb(197, 84, 124); - result: oklch(60% 0.150 0); } @function --oklab-function-var() { --local: rgb(197, 84, 124); result: var(--local); - -@supports (color: oklab(0% 0 0%)) { - --local: oklch(60% 0.150 0); -} } @function --hwb-function() { result: rgba(153, 153, 153, var(--alpha)); - -@supports (color: hwb(0 0% 0%)) { - result: hwb(0 60% 40% / var(--alpha)); -} } @function --hwb-function-var() { --local: rgba(153, 153, 153, var(--alpha)); result: var(--local); - -@supports (color: hwb(0 0% 0%)) { - --local: hwb(0 60% 40% / var(--alpha)); -} } @function --color-functional-notation() { result: rgba(255, 0, 0, var(--alpha-50)); - -@supports (color: rgb(0 0 0 / 0)) { - result: rgb(255 0 0 / var(--alpha-50)); -} } @function --color-functional-notation-var() { --local: rgba(255, 0, 0, var(--alpha-50)); result: var(--local); - -@supports (color: rgb(0 0 0 / 0)) { - --local: rgb(255 0 0 / var(--alpha-50)); -} } @function --color-mix-function() { result: rgb(175, 92, 174); - result: color-mix(in lch, purple 50%, plum 50%); } @function --color-mix-function-var() { --local: rgb(175, 92, 174); result: var(--local); - -@supports (color: color-mix(in lch, red, blue)) { - --local: color-mix(in lch, purple 50%, plum 50%); -} } @function --relative-color-syntax() { result: rgb(0, 0, 255); - result: rgb(from blue r g b); } @function --relative-color-syntax-var() { --local: rgb(0, 0, 255); result: var(--local); - -@supports (color: lab(from red l 1 1% / calc(alpha + 0.1))) { - --local: rgb(from blue r g b); -} } @function --double-position-gradients() { @@ -153,17 +112,12 @@ @function --image-function() { result: linear-gradient(red,red); - result: image(red); } @function --image-function-var() { --local: linear-gradient(red,red); result: var(--local); - -@supports (background-image: image(red)) { - --local: image(red); -} } @function --image-set-function() { @@ -187,17 +141,12 @@ @function --ic-unit() { result: 2em; - result: 2ic; } @function --ic-unit-var() { --local: 2em; result: var(--local); - -@supports (font-size: 1ic) { - --local: 2ic; -} } @function --logical-viewport-units() { @@ -221,10 +170,6 @@ @media (color-gamut: p3) { result: color(display-p3 0.86333 0 0.47139); } - -@media (color-gamut: rec2020) { - result: oklch(60% 0.4 0); -} } @function --gamut-mapping-var() { @@ -241,16 +186,6 @@ --local: color(display-p3 0.86333 0 0.47139); } } - -@supports (color: oklab(0% 0 0%)) { - --local: rgb(230, 0, 122); -} - -@media (color-gamut: rec2020) { -@supports (color: oklab(0% 0 0%)) { - --local: oklch(60% 0.4 0); -} -} } @function --system-ui-font-family() { diff --git a/plugin-packs/postcss-preset-env/test/postcss-functions.preserve-false.expect.css b/plugin-packs/postcss-preset-env/test/postcss-functions.preserve-false.expect.css new file mode 100644 index 0000000000..e75f3424bc --- /dev/null +++ b/plugin-packs/postcss-preset-env/test/postcss-functions.preserve-false.expect.css @@ -0,0 +1,193 @@ +/* + * `@function` interaction coverage. + * + * A `@function` body accepts conditional group rules such as `@supports` and `@media`. + * Transpilers must nest those rules inside the existing `@function` and never clone the + * `@function` rule into a conditional group rule, as a cloned `@function` with the same + * name overrides the original definition. + * + * Each pair covers a direct assignment to the `result` descriptor and indirection + * through a local custom property. + */ + +@function --color-function() { + result: rgb(26, 26, 26); +} + +@function --color-function-var() { + --local: rgb(26, 26, 26); + + result: var(--local); +} + +@function --lab-function() { + result: rgb(179, 35, 35); +} + +@function --lab-function-var() { + --local: rgb(179, 35, 35); + + result: var(--local); +} + +@function --oklab-function() { + result: rgb(197, 84, 124); +} + +@function --oklab-function-var() { + --local: rgb(197, 84, 124); + + result: var(--local); +} + +@function --hwb-function() { + result: rgba(153, 153, 153, var(--alpha)); +} + +@function --hwb-function-var() { + --local: rgba(153, 153, 153, var(--alpha)); + + result: var(--local); +} + +@function --color-functional-notation() { + result: rgba(255, 0, 0, var(--alpha-50)); +} + +@function --color-functional-notation-var() { + --local: rgba(255, 0, 0, var(--alpha-50)); + + result: var(--local); +} + +@function --color-mix-function() { + result: rgb(175, 92, 174); +} + +@function --color-mix-function-var() { + --local: rgb(175, 92, 174); + + result: var(--local); +} + +@function --relative-color-syntax() { + result: rgb(0, 0, 255); +} + +@function --relative-color-syntax-var() { + --local: rgb(0, 0, 255); + + result: var(--local); +} + +@function --double-position-gradients() { + result: linear-gradient(90deg, black 25%,black 50%, blue 50%, blue 75%); +} + +@function --double-position-gradients-var() { + --local: linear-gradient(90deg, black 25%,black 50%, blue 50%, blue 75%); + + result: var(--local); +} + +@function --gradients-interpolation-method() { + result: linear-gradient(90deg, rgb(0, 0, 0) 25%, rgb(0, 0, 0) 50%, rgb(0, 0, 255) 50%, rgb(0, 0, 255) 75%); +} + +@function --gradients-interpolation-method-var() { + --local: linear-gradient(90deg, rgb(0, 0, 0) 25%, rgb(0, 0, 0) 50%, rgb(0, 0, 255) 50%, rgb(0, 0, 255) 75%); + + result: var(--local); +} + +@function --image-function() { + result: linear-gradient(red,red); +} + +@function --image-function-var() { + --local: linear-gradient(red,red); + + result: var(--local); +} + +@function --image-set-function() { + result: url(img/test.png); + @media (-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 2), (min-resolution: 192dpi) { + result: url(img/test-2x.png); + } +} + +@function --image-set-function-var() { + --local: url(img/test.png); + + result: var(--local); + + @media (-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 2), (min-resolution: 192dpi) { + --local: url(img/test-2x.png); + } +} + +@function --ic-unit() { + result: 2em; +} + +@function --ic-unit-var() { + --local: 2em; + + result: var(--local); +} + +@function --logical-viewport-units() { + result: 2vw; +} + +@function --logical-viewport-units-var() { + --local: 2vw; + + result: var(--local); +} + +@function --gamut-mapping() { + result: rgb(230, 0, 122); + +@media (color-gamut: p3) { + result: color(display-p3 0.86333 0 0.47139); +} +} + +@function --gamut-mapping-var() { + --local: rgb(230, 0, 122); + + result: var(--local); + +@supports (color: color(display-p3 0 0 0%)) { + --local: rgb(230, 0, 122); +} + +@media (color-gamut: p3) { +@supports (color: color(display-p3 0 0 0%)) { + --local: color(display-p3 0.86333 0 0.47139); +} +} +} + +@function --system-ui-font-family() { + result: -apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif; + result: system-ui; +} + +@function --system-ui-font-family-var() { + --local: -apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif; + + result: var(--local); +} + +@function --custom-properties() { + result: var(--color-fallback); +} + +@function --custom-properties-var() { + --local: var(--color-fallback); + + result: var(--local); +} diff --git a/plugin-packs/postcss-preset-env/test/postcss-functions.preserve-true.expect.css b/plugin-packs/postcss-preset-env/test/postcss-functions.preserve-true.expect.css new file mode 100644 index 0000000000..0d6f526715 --- /dev/null +++ b/plugin-packs/postcss-preset-env/test/postcss-functions.preserve-true.expect.css @@ -0,0 +1,275 @@ +/* + * `@function` interaction coverage. + * + * A `@function` body accepts conditional group rules such as `@supports` and `@media`. + * Transpilers must nest those rules inside the existing `@function` and never clone the + * `@function` rule into a conditional group rule, as a cloned `@function` with the same + * name overrides the original definition. + * + * Each pair covers a direct assignment to the `result` descriptor and indirection + * through a local custom property. + */ + +@function --color-function() { + result: rgb(26, 26, 26); + result: color(display-p3 0.1 0.1 0.1); +} + +@function --color-function-var() { + --local: rgb(26, 26, 26); + + result: var(--local); + +@supports (color: color(display-p3 0 0 0%)) { + --local: color(display-p3 0.1 0.1 0.1); +} +} + +@function --lab-function() { + result: rgb(179, 35, 35); + result: lab(40% 56.6 39); +} + +@function --lab-function-var() { + --local: rgb(179, 35, 35); + + result: var(--local); + +@supports (color: lab(0% 0 0%)) { + --local: lab(40% 56.6 39); +} +} + +@function --oklab-function() { + result: rgb(197, 84, 124); + result: oklch(60% 0.150 0); +} + +@function --oklab-function-var() { + --local: rgb(197, 84, 124); + + result: var(--local); + +@supports (color: oklab(0% 0 0%)) { + --local: oklch(60% 0.150 0); +} +} + +@function --hwb-function() { + result: rgba(153, 153, 153, var(--alpha)); + +@supports (color: hwb(0 0% 0%)) { + result: hwb(0 60% 40% / var(--alpha)); +} +} + +@function --hwb-function-var() { + --local: rgba(153, 153, 153, var(--alpha)); + + result: var(--local); + +@supports (color: hwb(0 0% 0%)) { + --local: hwb(0 60% 40% / var(--alpha)); +} +} + +@function --color-functional-notation() { + result: rgba(255, 0, 0, var(--alpha-50)); + +@supports (color: rgb(0 0 0 / 0)) { + result: rgb(255 0 0 / var(--alpha-50)); +} +} + +@function --color-functional-notation-var() { + --local: rgba(255, 0, 0, var(--alpha-50)); + + result: var(--local); + +@supports (color: rgb(0 0 0 / 0)) { + --local: rgb(255 0 0 / var(--alpha-50)); +} +} + +@function --color-mix-function() { + result: rgb(175, 92, 174); + result: color-mix(in lch, purple 50%, plum 50%); +} + +@function --color-mix-function-var() { + --local: rgb(175, 92, 174); + + result: var(--local); + +@supports (color: color-mix(in lch, red, blue)) { + --local: color-mix(in lch, purple 50%, plum 50%); +} +} + +@function --relative-color-syntax() { + result: rgb(0, 0, 255); + result: rgb(from blue r g b); +} + +@function --relative-color-syntax-var() { + --local: rgb(0, 0, 255); + + result: var(--local); + +@supports (color: lab(from red l 1 1% / calc(alpha + 0.1))) { + --local: rgb(from blue r g b); +} +} + +@function --double-position-gradients() { + result: linear-gradient(90deg, black 25%,black 50%, blue 50%, blue 75%); + result: linear-gradient(90deg, black 25% 50%, blue 50% 75%); +} + +@function --double-position-gradients-var() { + --local: linear-gradient(90deg, black 25%,black 50%, blue 50%, blue 75%); + + result: var(--local); + +@supports (background: linear-gradient(red 0%, red 0% 1%, red 2%)) { + --local: linear-gradient(90deg, black 25% 50%, blue 50% 75%); +} +} + +@function --gradients-interpolation-method() { + result: linear-gradient(90deg, rgb(0, 0, 0) 25%, rgb(0, 0, 0) 50%, rgb(0, 0, 255) 50%, rgb(0, 0, 255) 75%); + result: linear-gradient(in oklch 90deg, black 25% 50%, blue 50% 75%); +} + +@function --gradients-interpolation-method-var() { + --local: linear-gradient(90deg, rgb(0, 0, 0) 25%, rgb(0, 0, 0) 50%, rgb(0, 0, 255) 50%, rgb(0, 0, 255) 75%); + + result: var(--local); + +@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) { + --local: linear-gradient(in oklch 90deg, black 25% 50%, blue 50% 75%); +} +} + +@function --image-function() { + result: linear-gradient(red,red); + result: image(red); +} + +@function --image-function-var() { + --local: linear-gradient(red,red); + + result: var(--local); + +@supports (background-image: image(red)) { + --local: image(red); +} +} + +@function --image-set-function() { + result: url(img/test.png); + result: image-set(url(img/test.png) 1x, url(img/test-2x.png) 2x); + @media (-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 2), (min-resolution: 192dpi) { + result: url(img/test-2x.png); + } +} + +@function --image-set-function-var() { + --local: url(img/test.png); + --local: image-set(url(img/test.png) 1x, url(img/test-2x.png) 2x); + + result: var(--local); + + @media (-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 2), (min-resolution: 192dpi) { + --local: url(img/test-2x.png); + } +} + +@function --ic-unit() { + result: 2em; + result: 2ic; +} + +@function --ic-unit-var() { + --local: 2em; + + result: var(--local); + +@supports (font-size: 1ic) { + --local: 2ic; +} +} + +@function --logical-viewport-units() { + result: 2vw; + result: 2vi; +} + +@function --logical-viewport-units-var() { + --local: 2vw; + + result: var(--local); + +@supports (width: 1vi) { + --local: 2vi; +} +} + +@function --gamut-mapping() { + result: rgb(230, 0, 122); + +@media (color-gamut: p3) { + result: color(display-p3 0.86333 0 0.47139); +} + +@media (color-gamut: rec2020) { + result: oklch(60% 0.4 0); +} +} + +@function --gamut-mapping-var() { + --local: rgb(230, 0, 122); + + result: var(--local); + +@supports (color: color(display-p3 0 0 0%)) { + --local: rgb(230, 0, 122); +} + +@media (color-gamut: p3) { +@supports (color: color(display-p3 0 0 0%)) { + --local: color(display-p3 0.86333 0 0.47139); +} +} + +@supports (color: oklab(0% 0 0%)) { + --local: rgb(230, 0, 122); +} + +@media (color-gamut: rec2020) { +@supports (color: oklab(0% 0 0%)) { + --local: oklch(60% 0.4 0); +} +} +} + +@function --system-ui-font-family() { + result: system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif; + result: system-ui; +} + +@function --system-ui-font-family-var() { + --local: system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif; + + result: var(--local); +} + +@function --custom-properties() { + result: var(--color-fallback); +} + +@function --custom-properties-var() { + --local: var(--color-fallback); + + result: var(--local); +} diff --git a/plugins/postcss-gamut-mapping/test/basic.css b/plugins/postcss-gamut-mapping/test/basic.css index 9cfec8de95..8d1833843f 100644 --- a/plugins/postcss-gamut-mapping/test/basic.css +++ b/plugins/postcss-gamut-mapping/test/basic.css @@ -165,3 +165,25 @@ result: var(--a); } + +:root { + --firebrick: rgba(255, 155, 186, 0.5); + --firebrick: color(display-p3 1 0.58119 0.72367 / 0.5); + --firebrick: oklch(80% 0.4 0.039 / 50%); +} + +:root { + --firebrick-2: rgba(255, 155, 186, 0.5); +} + +@supports (color: color(display-p3 0 0 0%)) { + :root { + --firebrick-2: color(display-p3 1 0.58119 0.72367 / 0.5); + } +} + +@supports (color: oklab(0% 0 0%)) { + :root { + --firebrick-2: oklch(80% 0.4 0.039 / 50%); + } +} diff --git a/plugins/postcss-gamut-mapping/test/basic.expect.css b/plugins/postcss-gamut-mapping/test/basic.expect.css index 617c392f18..ad696fd38a 100644 --- a/plugins/postcss-gamut-mapping/test/basic.expect.css +++ b/plugins/postcss-gamut-mapping/test/basic.expect.css @@ -244,3 +244,47 @@ --a: oklch(60% 0.4 0); } } + +:root { + --firebrick: rgba(255, 155, 186, 0.5); +} + +@media (color-gamut: p3) { +:root { + --firebrick: color(display-p3 1 0.58119 0.72367 / 0.5); +} +} + +@media (color-gamut: rec2020) { +:root { + --firebrick: oklch(80% 0.4 0.039 / 50%); +} +} + +:root { + --firebrick-2: rgba(255, 155, 186, 0.5); +} + +@supports (color: color(display-p3 0 0 0%)) { + :root { + --firebrick-2: rgba(255, 155, 186, 0.5); + } + +@media (color-gamut: p3) { +:root { + --firebrick-2: color(display-p3 1 0.58119 0.72367 / 0.5); + } +} +} + +@supports (color: oklab(0% 0 0%)) { + :root { + --firebrick-2: rgba(255, 155, 186, 0.5); + } + +@media (color-gamut: rec2020) { +:root { + --firebrick-2: oklch(80% 0.4 0.039 / 50%); + } +} +} diff --git a/plugins/postcss-oklab-function/test/variables.css b/plugins/postcss-oklab-function/test/variables.css index f0d4196d06..f986a501ae 100644 --- a/plugins/postcss-oklab-function/test/variables.css +++ b/plugins/postcss-oklab-function/test/variables.css @@ -8,3 +8,8 @@ --point-five: 0.5; --firebrick-var: oklch(40% var(--point-five) 0.1324 / var(--opacity-50)); } + + +:root { + --firebrick: oklch(80% 0.4 0.039 / 50%); +} diff --git a/plugins/postcss-oklab-function/test/variables.expect.css b/plugins/postcss-oklab-function/test/variables.expect.css index 417c6f0d7e..af41f1895d 100644 --- a/plugins/postcss-oklab-function/test/variables.expect.css +++ b/plugins/postcss-oklab-function/test/variables.expect.css @@ -16,3 +16,14 @@ --firebrick-a50-var: color(display-p3 0.49825 0 0.26185 / var(--opacity-50)); } } + + +:root { + --firebrick: rgba(255, 155, 186, 0.5); +} + +@supports (color: color(display-p3 0 0 0%)) { +:root { + --firebrick: color(display-p3 1 0.58119 0.72367 / 0.5); +} +} diff --git a/plugins/postcss-oklab-function/test/variables.preserve-true.display-p3-false.expect.css b/plugins/postcss-oklab-function/test/variables.preserve-true.display-p3-false.expect.css index ea3e4a24b3..5d37152023 100644 --- a/plugins/postcss-oklab-function/test/variables.preserve-true.display-p3-false.expect.css +++ b/plugins/postcss-oklab-function/test/variables.preserve-true.display-p3-false.expect.css @@ -16,3 +16,14 @@ --firebrick-a50-var: oklch(40% 0.4 0.039 / var(--opacity-50)); } } + + +:root { + --firebrick: rgba(255, 155, 186, 0.5); +} + +@supports (color: oklab(0% 0 0%)) { +:root { + --firebrick: oklch(80% 0.4 0.039 / 50%); +} +} diff --git a/plugins/postcss-oklab-function/test/variables.preserve-true.expect.css b/plugins/postcss-oklab-function/test/variables.preserve-true.expect.css index 8d985937af..c6260e58be 100644 --- a/plugins/postcss-oklab-function/test/variables.preserve-true.expect.css +++ b/plugins/postcss-oklab-function/test/variables.preserve-true.expect.css @@ -44,3 +44,20 @@ --firebrick-a50-var: oklch(40% 0.4 0.039 / var(--opacity-50)); } } + + +:root { + --firebrick: rgba(255, 155, 186, 0.5); +} + +@supports (color: color(display-p3 0 0 0%)) { +:root { + --firebrick: color(display-p3 1 0.58119 0.72367 / 0.5); +} +} + +@supports (color: oklab(0% 0 0%)) { +:root { + --firebrick: oklch(80% 0.4 0.039 / 50%); +} +} From e3be5b426921c50552b19931300e66994b2b85c7 Mon Sep 17 00:00:00 2001 From: Romain Menke Date: Fri, 2 Oct 2026 07:31:25 +0200 Subject: [PATCH 4/5] wip --- .../src/lib/ids-by-execution-order.mjs | 2 +- .../test/basic.autoprefixer.expect.css | 1 - .../test/basic.autoprefixer.false.expect.css | 1 - .../test/basic.autoprefixer.remove.false.expect.css | 1 - .../postcss-preset-env/test/basic.ch38.expect.css | 1 - .../postcss-preset-env/test/basic.edge16.expect.css | 1 - plugin-packs/postcss-preset-env/test/basic.expect.css | 1 - .../postcss-preset-env/test/basic.ff49.expect.css | 1 - .../postcss-preset-env/test/basic.ff66.expect.css | 1 - .../postcss-preset-env/test/basic.hebrew.expect.css | 1 - .../postcss-preset-env/test/basic.ie10.expect.css | 1 - .../test/basic.nesting.false.expect.css | 1 - .../postcss-preset-env/test/basic.op_mini.expect.css | 1 - .../test/basic.preserve.false.expect.css | 1 - .../test/basic.preserve.true.expect.css | 2 -- .../postcss-preset-env/test/basic.safari15.expect.css | 1 - .../postcss-preset-env/test/basic.stage0-ff49.expect.css | 1 - .../postcss-preset-env/test/basic.stage0-ff66.expect.css | 1 - .../postcss-preset-env/test/basic.stage0.expect.css | 1 - .../test/basic.supports-query.expect.css | 1 - .../postcss-preset-env/test/postcss-functions.expect.css | 1 - .../test/postcss-functions.preserve-false.expect.css | 1 - .../test/postcss-functions.preserve-true.expect.css | 2 -- plugins/postcss-gamut-mapping/test/basic.expect.css | 9 --------- 24 files changed, 1 insertion(+), 34 deletions(-) diff --git a/plugin-packs/postcss-preset-env/src/lib/ids-by-execution-order.mjs b/plugin-packs/postcss-preset-env/src/lib/ids-by-execution-order.mjs index 8717bc131b..f7ad409a7f 100644 --- a/plugin-packs/postcss-preset-env/src/lib/ids-by-execution-order.mjs +++ b/plugin-packs/postcss-preset-env/src/lib/ids-by-execution-order.mjs @@ -82,6 +82,6 @@ export default [ 'cascade-layers', - 'progressive-custom-properties', 'gamut-mapping', + 'progressive-custom-properties', ]; 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 45a3e8e9ee..bda5cb6016 100644 --- a/plugin-packs/postcss-preset-env/test/basic.autoprefixer.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.autoprefixer.expect.css @@ -597,7 +597,6 @@ @supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(189, 182, 255), rgb(173, 195, 255), rgb(159, 205, 255), rgb(140, 215, 255), rgb(100, 228, 255), rgb(94, 237, 237) 100%); } @media (color-gamut: rec2020) { 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 9225f6f9b7..7be7f48572 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 @@ -597,7 +597,6 @@ @supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(189, 182, 255), rgb(173, 195, 255), rgb(159, 205, 255), rgb(140, 215, 255), rgb(100, 228, 255), rgb(94, 237, 237) 100%); } @media (color-gamut: rec2020) { diff --git a/plugin-packs/postcss-preset-env/test/basic.autoprefixer.remove.false.expect.css b/plugin-packs/postcss-preset-env/test/basic.autoprefixer.remove.false.expect.css index 26bb013149..fde6f091be 100644 --- a/plugin-packs/postcss-preset-env/test/basic.autoprefixer.remove.false.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.autoprefixer.remove.false.expect.css @@ -615,7 +615,6 @@ @supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(189, 182, 255), rgb(173, 195, 255), rgb(159, 205, 255), rgb(140, 215, 255), rgb(100, 228, 255), rgb(94, 237, 237) 100%); } @media (color-gamut: rec2020) { 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 26caacfb16..06e837d8a0 100644 --- a/plugin-packs/postcss-preset-env/test/basic.ch38.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.ch38.expect.css @@ -509,7 +509,6 @@ @supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(189, 182, 255), rgb(173, 195, 255), rgb(159, 205, 255), rgb(140, 215, 255), rgb(100, 228, 255), rgb(94, 237, 237) 100%); } @media (color-gamut: rec2020) { diff --git a/plugin-packs/postcss-preset-env/test/basic.edge16.expect.css b/plugin-packs/postcss-preset-env/test/basic.edge16.expect.css index b7c614ba06..d7b659cd9a 100644 --- a/plugin-packs/postcss-preset-env/test/basic.edge16.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.edge16.expect.css @@ -591,7 +591,6 @@ @supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(189, 182, 255), rgb(173, 195, 255), rgb(159, 205, 255), rgb(140, 215, 255), rgb(100, 228, 255), rgb(94, 237, 237) 100%); } @media (color-gamut: rec2020) { diff --git a/plugin-packs/postcss-preset-env/test/basic.expect.css b/plugin-packs/postcss-preset-env/test/basic.expect.css index 5d852d8260..17aeaeba9a 100644 --- a/plugin-packs/postcss-preset-env/test/basic.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.expect.css @@ -615,7 +615,6 @@ @supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(189, 182, 255), rgb(173, 195, 255), rgb(159, 205, 255), rgb(140, 215, 255), rgb(100, 228, 255), rgb(94, 237, 237) 100%); } @media (color-gamut: rec2020) { 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 fe94dce353..6b7507d379 100644 --- a/plugin-packs/postcss-preset-env/test/basic.ff49.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.ff49.expect.css @@ -508,7 +508,6 @@ @supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(189, 182, 255), rgb(173, 195, 255), rgb(159, 205, 255), rgb(140, 215, 255), rgb(100, 228, 255), rgb(94, 237, 237) 100%); } @media (color-gamut: rec2020) { 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 c7c20bffbb..f620d88197 100644 --- a/plugin-packs/postcss-preset-env/test/basic.ff66.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.ff66.expect.css @@ -503,7 +503,6 @@ @supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(189, 182, 255), rgb(173, 195, 255), rgb(159, 205, 255), rgb(140, 215, 255), rgb(100, 228, 255), rgb(94, 237, 237) 100%); } @media (color-gamut: rec2020) { diff --git a/plugin-packs/postcss-preset-env/test/basic.hebrew.expect.css b/plugin-packs/postcss-preset-env/test/basic.hebrew.expect.css index 84ff9d7619..1f27ef885b 100644 --- a/plugin-packs/postcss-preset-env/test/basic.hebrew.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.hebrew.expect.css @@ -611,7 +611,6 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe @supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(189, 182, 255), rgb(173, 195, 255), rgb(159, 205, 255), rgb(140, 215, 255), rgb(100, 228, 255), rgb(94, 237, 237) 100%); } @media (color-gamut: rec2020) { 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 6022813d6a..8da02108e7 100644 --- a/plugin-packs/postcss-preset-env/test/basic.ie10.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.ie10.expect.css @@ -633,7 +633,6 @@ @supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(189, 182, 255), rgb(173, 195, 255), rgb(159, 205, 255), rgb(140, 215, 255), rgb(100, 228, 255), rgb(94, 237, 237) 100%); } @media (color-gamut: rec2020) { 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 166ca3bb6c..61712b0776 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 @@ -606,7 +606,6 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe @supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(189, 182, 255), rgb(173, 195, 255), rgb(159, 205, 255), rgb(140, 215, 255), rgb(100, 228, 255), rgb(94, 237, 237) 100%); } @media (color-gamut: rec2020) { 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 d990850940..f8b56b3972 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 @@ -594,7 +594,6 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe @supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(189, 182, 255), rgb(173, 195, 255), rgb(159, 205, 255), rgb(140, 215, 255), rgb(100, 228, 255), rgb(94, 237, 237) 100%); } @media (color-gamut: rec2020) { diff --git a/plugin-packs/postcss-preset-env/test/basic.preserve.false.expect.css b/plugin-packs/postcss-preset-env/test/basic.preserve.false.expect.css index b7813b1068..788d8f3d70 100644 --- a/plugin-packs/postcss-preset-env/test/basic.preserve.false.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.preserve.false.expect.css @@ -732,7 +732,6 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe @supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(189, 182, 255), rgb(173, 195, 255), rgb(159, 205, 255), rgb(140, 215, 255), rgb(100, 228, 255), rgb(94, 237, 237) 100%); } @media (color-gamut: rec2020) { 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 d601fab434..acacfd0e5b 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 @@ -1016,7 +1016,6 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe @supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(189, 182, 255), rgb(173, 195, 255), rgb(159, 205, 255), rgb(140, 215, 255), rgb(100, 228, 255), rgb(94, 237, 237) 100%); } @media (color-gamut: rec2020) { @@ -1101,7 +1100,6 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe @supports (color: color(display-p3 0 0 0%)) { .out-of-gamut { - --color: rgb(0, 247, 79); } @media (color-gamut: p3) { 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 ec67e0eac5..7c9fb77f0a 100644 --- a/plugin-packs/postcss-preset-env/test/basic.safari15.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.safari15.expect.css @@ -488,7 +488,6 @@ @supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(189, 182, 255), rgb(173, 195, 255), rgb(159, 205, 255), rgb(140, 215, 255), rgb(100, 228, 255), rgb(94, 237, 237) 100%); } @media (color-gamut: rec2020) { 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 c8aeb3dfe2..519c73cd90 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 @@ -504,7 +504,6 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe @supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(189, 182, 255), rgb(173, 195, 255), rgb(159, 205, 255), rgb(140, 215, 255), rgb(100, 228, 255), rgb(94, 237, 237) 100%); } @media (color-gamut: rec2020) { 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 cc1108214a..5587606a85 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 @@ -499,7 +499,6 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe @supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(189, 182, 255), rgb(173, 195, 255), rgb(159, 205, 255), rgb(140, 215, 255), rgb(100, 228, 255), rgb(94, 237, 237) 100%); } @media (color-gamut: rec2020) { 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 e38a63e824..db5be4d9ee 100644 --- a/plugin-packs/postcss-preset-env/test/basic.stage0.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.stage0.expect.css @@ -611,7 +611,6 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe @supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(189, 182, 255), rgb(173, 195, 255), rgb(159, 205, 255), rgb(140, 215, 255), rgb(100, 228, 255), rgb(94, 237, 237) 100%); } @media (color-gamut: rec2020) { diff --git a/plugin-packs/postcss-preset-env/test/basic.supports-query.expect.css b/plugin-packs/postcss-preset-env/test/basic.supports-query.expect.css index 26e60075f7..7480939cb6 100644 --- a/plugin-packs/postcss-preset-env/test/basic.supports-query.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.supports-query.expect.css @@ -501,7 +501,6 @@ @supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(189, 182, 255), rgb(173, 195, 255), rgb(159, 205, 255), rgb(140, 215, 255), rgb(100, 228, 255), rgb(94, 237, 237) 100%); } @media (color-gamut: rec2020) { diff --git a/plugin-packs/postcss-preset-env/test/postcss-functions.expect.css b/plugin-packs/postcss-preset-env/test/postcss-functions.expect.css index 71e2cc2f45..e3540f976f 100644 --- a/plugin-packs/postcss-preset-env/test/postcss-functions.expect.css +++ b/plugin-packs/postcss-preset-env/test/postcss-functions.expect.css @@ -178,7 +178,6 @@ result: var(--local); @supports (color: color(display-p3 0 0 0%)) { - --local: rgb(230, 0, 122); } @media (color-gamut: p3) { diff --git a/plugin-packs/postcss-preset-env/test/postcss-functions.preserve-false.expect.css b/plugin-packs/postcss-preset-env/test/postcss-functions.preserve-false.expect.css index e75f3424bc..bd759edb37 100644 --- a/plugin-packs/postcss-preset-env/test/postcss-functions.preserve-false.expect.css +++ b/plugin-packs/postcss-preset-env/test/postcss-functions.preserve-false.expect.css @@ -161,7 +161,6 @@ result: var(--local); @supports (color: color(display-p3 0 0 0%)) { - --local: rgb(230, 0, 122); } @media (color-gamut: p3) { diff --git a/plugin-packs/postcss-preset-env/test/postcss-functions.preserve-true.expect.css b/plugin-packs/postcss-preset-env/test/postcss-functions.preserve-true.expect.css index 0d6f526715..045e3ed8c4 100644 --- a/plugin-packs/postcss-preset-env/test/postcss-functions.preserve-true.expect.css +++ b/plugin-packs/postcss-preset-env/test/postcss-functions.preserve-true.expect.css @@ -233,7 +233,6 @@ result: var(--local); @supports (color: color(display-p3 0 0 0%)) { - --local: rgb(230, 0, 122); } @media (color-gamut: p3) { @@ -243,7 +242,6 @@ } @supports (color: oklab(0% 0 0%)) { - --local: rgb(230, 0, 122); } @media (color-gamut: rec2020) { diff --git a/plugins/postcss-gamut-mapping/test/basic.expect.css b/plugins/postcss-gamut-mapping/test/basic.expect.css index ad696fd38a..47bb085f38 100644 --- a/plugins/postcss-gamut-mapping/test/basic.expect.css +++ b/plugins/postcss-gamut-mapping/test/basic.expect.css @@ -194,9 +194,6 @@ } @supports (color: color(display-p3 0 1 0)) { - .guarded-by-supports { - color: rgb(0, 247, 79); - } @media (color-gamut: p3) { .guarded-by-supports { @@ -266,9 +263,6 @@ } @supports (color: color(display-p3 0 0 0%)) { - :root { - --firebrick-2: rgba(255, 155, 186, 0.5); - } @media (color-gamut: p3) { :root { @@ -278,9 +272,6 @@ } @supports (color: oklab(0% 0 0%)) { - :root { - --firebrick-2: rgba(255, 155, 186, 0.5); - } @media (color-gamut: rec2020) { :root { From da9c8c268ae05fca567d2f6663c1ded7bf8f8536 Mon Sep 17 00:00:00 2001 From: Romain Menke Date: Fri, 2 Oct 2026 08:23:31 +0200 Subject: [PATCH 5/5] fix plugin interactions --- plugin-packs/postcss-preset-env/CHANGELOG.md | 1 - .../postcss-preset-env/dist/index.mjs | 2 +- .../test/basic.autoprefixer.expect.css | 39 +++-- .../test/basic.autoprefixer.false.expect.css | 39 +++-- ...basic.autoprefixer.remove.false.expect.css | 39 +++-- .../test/basic.ch126.expect.css | 21 +++ .../test/basic.ch130.expect.css | 21 +++ .../test/basic.ch38.expect.css | 39 +++-- .../test/basic.edge16.expect.css | 39 +++-- .../postcss-preset-env/test/basic.expect.css | 39 +++-- .../test/basic.ff49.expect.css | 39 +++-- .../test/basic.ff66.expect.css | 39 +++-- ...ebrew.all-browsers-have-support.expect.css | 21 +++ .../test/basic.hebrew.expect.css | 39 +++-- .../test/basic.ie10.expect.css | 39 +++-- .../test/basic.nesting.false.expect.css | 39 +++-- .../test/basic.op_mini.expect.css | 39 +++-- .../test/basic.preserve.false.expect.css | 28 ++-- .../test/basic.preserve.true.expect.css | 140 +++++++++++++++--- .../test/basic.safari15.expect.css | 45 ++++-- .../test/basic.stage0-ff49.expect.css | 39 +++-- .../test/basic.stage0-ff66.expect.css | 39 +++-- .../test/basic.stage0.expect.css | 39 +++-- .../test/basic.supports-query.expect.css | 39 +++-- .../test/layers-basic.expect.css | 3 + .../layers-basic.preserve.true.expect.css | 78 ++++++++++ .../test/postcss-functions.expect.css | 7 +- ...ostcss-functions.preserve-false.expect.css | 7 +- ...postcss-functions.preserve-true.expect.css | 14 +- plugins/postcss-gamut-mapping/CHANGELOG.md | 1 + plugins/postcss-gamut-mapping/README.md | 6 + plugins/postcss-gamut-mapping/dist/index.mjs | 2 +- plugins/postcss-gamut-mapping/src/index.ts | 47 +++++- .../src/supports-condition.ts | 103 +++++++++++++ .../test/basic.expect.css | 61 +++++++- .../test/examples/example.expect.css | 6 + .../postcss-light-dark-function/CHANGELOG.md | 4 + .../dist/index.mjs | 2 +- .../postcss-light-dark-function/src/index.ts | 14 +- .../test/basic.expect.css | 8 - .../test/basic.preserve-false.expect.css | 5 - 41 files changed, 1052 insertions(+), 219 deletions(-) create mode 100644 plugins/postcss-gamut-mapping/src/supports-condition.ts diff --git a/plugin-packs/postcss-preset-env/CHANGELOG.md b/plugin-packs/postcss-preset-env/CHANGELOG.md index e17f571f0e..8473badfd8 100644 --- a/plugin-packs/postcss-preset-env/CHANGELOG.md +++ b/plugin-packs/postcss-preset-env/CHANGELOG.md @@ -3,7 +3,6 @@ ### Unreleased (minor) - Added `@csstools/postcss-custom-functions` [Check the plugin README](https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-custom-functions#readme) for usage details. -- Correctly nest conditional rules inside `@function` instead of cloning the `@function` rule. ### 11.5.5 diff --git a/plugin-packs/postcss-preset-env/dist/index.mjs b/plugin-packs/postcss-preset-env/dist/index.mjs index 17f66737ec..ad509432ed 100644 --- a/plugin-packs/postcss-preset-env/dist/index.mjs +++ b/plugin-packs/postcss-preset-env/dist/index.mjs @@ -1 +1 @@ -import s from"autoprefixer";import o from"cssdb";import e from"browserslist";import t from"@csstools/postcss-initial";import r from"@csstools/postcss-alpha-function";import i from"postcss-pseudo-class-any-link";import a from"css-blank-pseudo";import c from"postcss-page-break";import p from"@csstools/postcss-cascade-layers";import n from"postcss-attribute-case-insensitive";import l from"postcss-clamp";import m from"@csstools/postcss-color-function";import u from"@csstools/postcss-color-function-display-p3-linear";import d from"postcss-color-functional-notation";import f from"@csstools/postcss-color-mix-function";import g from"@csstools/postcss-color-mix-variadic-function-arguments";import h from"@csstools/postcss-container-rule-prelude-list";import N from"@csstools/postcss-content-alt-text";import b from"@csstools/postcss-contrast-color-function";import y from"@csstools/postcss-custom-functions";import v from"postcss-custom-media";import k from"postcss-custom-properties";import w from"postcss-custom-selectors";import x from"postcss-dir-pseudo-class";import F from"@csstools/postcss-normalize-display-values";import O from"postcss-double-position-gradients";import P from"@csstools/postcss-exponential-functions";import C from"@csstools/postcss-fit-tolerance-property";import $ from"@csstools/postcss-logical-float-and-clear";import S from"postcss-focus-visible";import A from"postcss-focus-within";import L from"@csstools/postcss-font-format-keywords";import _ from"postcss-font-variant";import I from"@csstools/postcss-font-width-property";import E from"@csstools/postcss-gamut-mapping";import B from"postcss-gap-properties";import q from"@csstools/postcss-gradients-interpolation-method";import M from"css-has-pseudo";import D from"postcss-color-hex-alpha";import j from"@csstools/postcss-hwb-function";import z from"@csstools/postcss-ic-unit";import R from"@csstools/postcss-image-function";import U from"postcss-image-set-function";import T from"@csstools/postcss-is-pseudo-class";import V from"postcss-lab-function";import H from"@csstools/postcss-light-dark-function";import W from"@csstools/postcss-logical-overflow";import G from"@csstools/postcss-logical-overscroll-behavior";import K from"postcss-logical";import Z from"@csstools/postcss-logical-resize";import Q from"@csstools/postcss-logical-viewport-units";import J from"@csstools/postcss-media-queries-aspect-ratio-number-values";import X from"@csstools/postcss-media-minmax";import Y from"@csstools/postcss-mixins";import ss from"@csstools/postcss-nested-calc";import os from"postcss-nesting";import es from"postcss-selector-not";import ts from"@csstools/postcss-oklab-function";import rs from"postcss-opacity-percentage";import is from"postcss-overflow-shorthand";import as from"postcss-replace-overflow-wrap";import cs from"postcss-place";import ps from"@csstools/postcss-position-area-property";import ns from"css-prefers-color-scheme";import ls from"@csstools/postcss-progressive-custom-properties";import ms from"@csstools/postcss-property-rule-optional-descriptors";import us from"@csstools/postcss-property-rule-prelude-list";import ds from"@csstools/postcss-random-function";import fs from"postcss-color-rebeccapurple";import gs from"@csstools/postcss-relative-color-syntax";import hs from"@csstools/postcss-scope-pseudo-class";import Ns from"@csstools/postcss-sign-functions";import bs from"@csstools/postcss-stepped-value-functions";import ys from"@csstools/postcss-syntax-descriptor-syntax-production";import vs from"@csstools/postcss-system-ui-font-family";import ks from"@csstools/postcss-text-decoration-shorthand";import ws from"@csstools/postcss-trigonometric-functions";import xs from"@csstools/postcss-unset-value";const Fs={"blank-pseudo-class":"https://github.com/csstools/postcss-plugins/blob/main/plugins/css-blank-pseudo/README.md#browser","focus-visible-pseudo-class":"https://github.com/WICG/focus-visible","focus-within-pseudo-class":"https://github.com/csstools/postcss-plugins/blob/main/plugins/postcss-focus-within/README.md#browser","has-pseudo-class":"https://github.com/csstools/postcss-plugins/blob/main/plugins/css-has-pseudo/README.md#browser","prefers-color-scheme-query":"https://github.com/csstools/postcss-plugins/blob/main/plugins/css-prefers-color-scheme/README.md#browser"},Os=["blank-pseudo-class","focus-visible-pseudo-class","focus-within-pseudo-class","has-pseudo-class","prefers-color-scheme-query"];function logFeaturesList(s,o,e){if(o.debug){e.log("Enabling the following feature(s):");const t=[],r=[];!1!==o.autoprefixer&&r.push(" autoprefixer"),s.forEach(s=>{s.id.startsWith("before")||s.id.startsWith("after")?r.push(` ${s.id} (injected via options)`):r.push(` ${s.id}`),void 0!==Fs[s.id]&&t.push(s.id)}),r.sort((s,o)=>s.localeCompare(o)),t.sort((s,o)=>s.localeCompare(o)),r.forEach(s=>e.log(s)),t.length&&(e.log("These feature(s) need a browser library to work:"),t.forEach(s=>e.log(` ${s}: ${Fs[s]}`)))}}function initializeSharedOptions(s){if("preserve"in s){const o={};return o.preserve=s.preserve,o}return!1}function clamp(s,o,e){return Math.max(s,Math.min(o,e))}function stageFromOptions(s,o){let e=2;if(void 0===s.stage)return o.log("Using features from Stage 2 (default)."),e;if(!1===s.stage)e=5;else{let o=parseInt(s.stage,10);Number.isNaN(o)&&(o=0),e=clamp(0,o,5)}return 5===e?o.log('Stage has been disabled, features will be handled via the "features" option.'):o.log(`Using features from Stage ${e}.`),e}const Ps=Symbol("insertBefore"),Cs=Symbol("insertAfter"),$s=Symbol("insertOrder"),Ss=Symbol("plugin");function getTransformedInsertions(s,o,e){if("insertBefore"!==e&&"insertAfter"!==e)return[];const t="insertBefore"===e?Ps:Cs,r=[];for(const e in o){if(!Object.hasOwnProperty.call(o,e))continue;if(!s.find(s=>s.id===e))continue;let i=o[e];Array.isArray(i)||(i=[i]);for(let s=0;sfeatureIsInsertedOrHasAPlugin(s)).sort((s,o)=>featureIsLess(s,o))}function getOptionsForBrowsersByFeature(s,o,e,t){switch(o.id){case"is-pseudo-class":return{onComplexSelector:"warning"};case"any-link-pseudo-class":if(s.find(s=>s.startsWith("ie ")||"edge 12"===s||"edge 13"===s||"edge 14"===s||"edge 15"===s||"edge 16"===s||"edge 17"===s||"edge 18"===s))return t.log("- 'any-link-pseudo-class' setting 'subFeatures: { areaHrefNeedsFixing: true }' due to lack of browser support for area[href] in Edge and IE."),{subFeatures:{areaHrefNeedsFixing:!0}};return{};case"logical-properties-and-values":case"float-clear-logical-values":case"logical-resize":case"logical-viewport-units":case"logical-overflow":case"logical-overscroll-behavior":return"logical"in e?e.logical:{};default:return{}}}const _s=["and_chr","and_ff","android","chrome","edge","firefox","ie","ios_saf","op_mini","op_mob","opera","safari","samsung"];function getUnsupportedBrowsersByFeature(s){if(!s)return[];if("position-area-property"===s.id)return["chrome 125","chrome 126","chrome 127","chrome 128","edge 125","edge 126","edge 127","edge 128","and_chr 125","and_chr 126","and_chr 127","and_chr 128","android 125","android 126","android 127","android 128","samsung 27","opera 111","opera 112","opera 113","opera 114","op_mob 83","op_mob 84","op_mob 85"];if(!("browser_support"in s))return["> 0%"];const o=[];return _s.forEach(e=>{if("op_mini"===e&&void 0===s.browser_support[e])return void o.push("op_mini all");const t=s.browser_support[e];"string"==typeof t&&Is.test(t)?o.push(`${e} < ${s.browser_support[e]}`):o.push(`${e} >= 1`)}),o}const Is=/^[0-9|.]+$/;function formatPolyfillableFeature(s){const o=getUnsupportedBrowsersByFeature(s);if(s[Ps]||s[Cs]){let e=s.id;return e=s.insertBefore?`before-${e}`:`after-${e}`,{browsers:o,vendors_implementations:s.vendors_implementations,plugin:s[Ss],id:e,stage:6}}return{browsers:o,vendors_implementations:s.vendors_implementations,plugin:Ls.get(s.id),id:s.id,stage:s.stage}}function formatStagedFeature(s,o,e,t,r,i){let a,c;return a=getOptionsForBrowsersByFeature(s,e,r,i),a=t?Object.assign({},a,t,featureOptions(o,e.id)):Object.assign({},a,featureOptions(o,e.id)),"progressive-custom-properties"!==e.id&&(a.enableProgressiveCustomProperties=!1),"overflow-wrap-property"===e.id&&"preserve"in a&&(a.method=a.preserve?"copy":"replace"),c=e.plugin.postcss&&"function"==typeof e.plugin?e.plugin(a):e.plugin&&e.plugin.default&&"function"==typeof e.plugin.default&&e.plugin.default.postcss?e.plugin.default(a):e.plugin,{browsers:e.browsers,vendors_implementations:e.vendors_implementations,plugin:c,pluginOptions:a,id:e.id}}function featureOptions(s,o){if(!(o in s))return;const e=s[o];return Array.isArray(e)?e[1]:e}function intOrZero(s){const o=parseInt(s,10);return Number.isNaN(o)?0:o}const Es=new Set(["progressive-custom-properties"]);function listFeatures(s,o,t,r){const i=Object(o.features),a="enableClientSidePolyfills"in o&&o.enableClientSidePolyfills,c=Object(o.insertBefore),p=Object(o.insertAfter),n=o.browsers?void 0:o.env,l=o.browsers,m=clamp(0,intOrZero(o.minimumVendorImplementations),3);m>0&&r.log(`Using features with ${m} or more vendor implementations.`);const u=stageFromOptions(o,r),d=prepareFeaturesList([...s,{id:"progressive-custom-properties"}],c,p).map(s=>formatPolyfillableFeature(s)).filter(s=>!!Es.has(s.id)||(0===m||(!(!s[Ps]&&!s[Cs])||(m<=s.vendors_implementations||(!0===featureEnabledByOptions(i,s.id)?(r.log(`- '${s.id}' enabled manually even when it lacks the required interop (${s.vendors_implementations} out of ${m}).`),!0):(r.log(`- '${s.id}' disabled because it lacks the required interop (${s.vendors_implementations} out of ${m}).`),!1)))))),f=e(l,{env:n,ignoreUnknownVersions:!0}).filter(s=>_s.includes(s.split(" ")[0]));return d.filter(s=>{if(Es.has(s.id))return!0;const o=s.stage>=u,e=a||!Os.includes(s.id),t=featureEnabledByOptions(i,s.id),c=!1===t,p=!0===t||o&&e;return c?r.log(`- '${s.id}' disabled manually`):o?e||r.log(`- '${s.id}' disabled because 'enableClientSidePolyfills' is 'false'.`):p?r.log(`- '${s.id}' enabled manually even when it lacks the required stage (${s.stage} out of ${u}).`):r.log(`- '${s.id}' disabled because it lacks the required stage (${s.stage} out of ${u}).`),!c&&p}).map(s=>formatStagedFeature(f,i,s,t,o,r)).filter(s=>{if(Es.has(s.id))return!0;const o=featureEnabledByOptions(i,s.id);if(!0===o||!1===o)return o;const t=e(s.browsers,{ignoreUnknownVersions:!0}),a=f.filter(s=>t.some(o=>o===s));return a.length>0?r.log(`- '${s.id}' enabled for:\n ${a.join("\n ")}`):r.log(`- '${s.id}' disabled because all targeted browsers support it.`),a.length>0})}function featureEnabledByOptions(s,o){if(!(o in s))return"auto";const e=s[o];return Array.isArray(e)?!0===e[0]||!1!==e[0]&&"auto":Boolean(e)}class Logger{constructor(){this.logs=[]}log(s){this.logs.push(s)}resetLogger(){this.logs.length=0}emitLogs(s){s&&s.warn(this.logs.join("\n")),this.resetLogger()}}var Bs=[{packageName:"css-blank-pseudo",id:"blank-pseudo-class",importName:"postcssBlankPseudo"},{packageName:"css-has-pseudo",id:"has-pseudo-class",importName:"postcssHasPseudo"},{packageName:"css-prefers-color-scheme",id:"prefers-color-scheme-query",importName:"postcssPrefersColorScheme"},{packageName:"postcss-attribute-case-insensitive",id:"case-insensitive-attributes",importName:"postcssAttributeCaseInsensitive"},{packageName:"postcss-clamp",id:"clamp",importName:"postcssClamp"},{packageName:"@csstools/postcss-alpha-function",id:"alpha-function",importName:"postcssAlphaFunction"},{packageName:"@csstools/postcss-color-mix-variadic-function-arguments",id:"color-mix-variadic-function-arguments",importName:"postcssColorMixVariadicFunctionArguments"},{packageName:"@csstools/postcss-color-mix-function",id:"color-mix",importName:"postcssColorMixFunction"},{packageName:"@csstools/postcss-color-function",id:"color-function",importName:"postcssColorFunction"},{packageName:"@csstools/postcss-color-function-display-p3-linear",id:"color-function-display-p3-linear",importName:"postcssColorFunctionDisplayP3Linear"},{packageName:"postcss-color-functional-notation",id:"color-functional-notation",importName:"postcssColorFunctionalNotation"},{packageName:"postcss-color-hex-alpha",id:"hexadecimal-alpha-notation",importName:"postcssColorHexAlpha"},{packageName:"@csstools/postcss-content-alt-text",id:"content-alt-text",importName:"postcssContentAltText"},{packageName:"postcss-color-rebeccapurple",id:"rebeccapurple-color",importName:"postcssColorRebeccapurple"},{packageName:"@csstools/postcss-contrast-color-function",id:"contrast-color-function",importName:"postcssContrastColorFunction"},{packageName:"postcss-custom-media",id:"custom-media-queries",importName:"postcssCustomMedia"},{packageName:"postcss-custom-properties",id:"custom-properties",importName:"postcssCustomProperties"},{packageName:"postcss-custom-selectors",id:"custom-selectors",importName:"postcssCustomSelectors"},{packageName:"postcss-dir-pseudo-class",id:"dir-pseudo-class",importName:"postcssDirPseudoClass"},{packageName:"postcss-double-position-gradients",id:"double-position-gradients",importName:"postcssDoublePositionGradients"},{packageName:"@csstools/postcss-exponential-functions",id:"exponential-functions",importName:"postcssExponentialFunctions"},{packageName:"postcss-focus-visible",id:"focus-visible-pseudo-class",importName:"postcssFocusVisible"},{packageName:"postcss-focus-within",id:"focus-within-pseudo-class",importName:"postcssFocusWithin"},{packageName:"@csstools/postcss-font-format-keywords",id:"font-format-keywords",importName:"postcssFontFormatKeywords"},{packageName:"postcss-font-variant",id:"font-variant-property",importName:"postcssFontVariant"},{packageName:"@csstools/postcss-font-width-property",id:"font-width-property",importName:"postcssFontWidthProperty"},{packageName:"@csstools/postcss-gamut-mapping",id:"gamut-mapping",importName:"postcssGamutMapping"},{packageName:"postcss-gap-properties",id:"gap-properties",importName:"postcssGapProperties"},{packageName:"@csstools/postcss-gradients-interpolation-method",id:"gradients-interpolation-method",importName:"postcssGradientsInterpolationMethod"},{packageName:"@csstools/postcss-hwb-function",id:"hwb-function",importName:"postcssHWBFunction"},{packageName:"@csstools/postcss-ic-unit",id:"ic-unit",importName:"postcssICUnit"},{packageName:"postcss-image-set-function",id:"image-set-function",importName:"postcssImageSetFunction"},{packageName:"@csstools/postcss-initial",id:"all-property",importName:"postcssInitial"},{packageName:"@csstools/postcss-is-pseudo-class",id:"is-pseudo-class",importName:"postcssIsPseudoClass"},{packageName:"@csstools/postcss-scope-pseudo-class",id:"scope-pseudo-class",importName:"postcssScopePseudoClass"},{packageName:"postcss-lab-function",id:"lab-function",importName:"postcssLabFunction"},{packageName:"@csstools/postcss-light-dark-function",id:"light-dark-function",importName:"postcssLightDarkFunction"},{packageName:"postcss-logical",id:"logical-properties-and-values",importName:"postcssLogical"},{packageName:"@csstools/postcss-logical-float-and-clear",id:"float-clear-logical-values",importName:"postcssLogicalFloatAndClear"},{packageName:"@csstools/postcss-logical-overflow",id:"logical-overflow",importName:"postcssLogicalOverflow"},{packageName:"@csstools/postcss-logical-overscroll-behavior",id:"logical-overscroll-behavior",importName:"postcssLogicalOverscrollBehavor"},{packageName:"@csstools/postcss-logical-resize",id:"logical-resize",importName:"postcssLogicalResize"},{packageName:"@csstools/postcss-logical-viewport-units",id:"logical-viewport-units",importName:"postcssLogicalViewportUnits"},{packageName:"@csstools/postcss-media-minmax",id:"media-query-ranges",importName:"postcssMediaMinmax"},{packageName:"@csstools/postcss-media-queries-aspect-ratio-number-values",id:"media-queries-aspect-ratio-number-values",importName:"postcssMediaQueriesAspectRatioNumberValues"},{packageName:"@csstools/postcss-mixins",id:"mixins",importName:"postcssMixins"},{packageName:"postcss-nesting",id:"nesting-rules",importName:"postcssNesting"},{packageName:"@csstools/postcss-normalize-display-values",id:"display-two-values",importName:"postcssNormalizeDisplayValues"},{packageName:"@csstools/postcss-oklab-function",id:"oklab-function",importName:"postcssOKLabFunction"},{packageName:"@csstools/postcss-relative-color-syntax",id:"relative-color-syntax",importName:"postcssRelativeColorSyntax"},{packageName:"postcss-opacity-percentage",id:"opacity-percentage",importName:"postcssOpacityPercentage"},{packageName:"postcss-overflow-shorthand",id:"overflow-property",importName:"postcssOverflowShorthand"},{packageName:"postcss-page-break",id:"break-properties",importName:"postcssPageBreak"},{packageName:"@csstools/postcss-position-area-property",id:"position-area-property",importName:"postcssPositionAreaProperty"},{packageName:"postcss-place",id:"place-properties",importName:"postcssPlace"},{packageName:"postcss-pseudo-class-any-link",id:"any-link-pseudo-class",importName:"postcssPseudoClassAnyLink"},{packageName:"postcss-replace-overflow-wrap",id:"overflow-wrap-property",importName:"postcssReplaceOverflowWrap"},{packageName:"postcss-selector-not",id:"not-pseudo-class",importName:"postcssSelectorNot"},{packageName:"@csstools/postcss-stepped-value-functions",id:"stepped-value-functions",importName:"postcssSteppedValueFunctions"},{packageName:"@csstools/postcss-system-ui-font-family",id:"system-ui-font-family",importName:"postcssSystemUIFontFamily"},{packageName:"@csstools/postcss-unset-value",id:"unset-value",importName:"postcssUnsetValue"},{packageName:"@csstools/postcss-cascade-layers",id:"cascade-layers",importName:"postcssCascadeLayers"},{packageName:"@csstools/postcss-trigonometric-functions",id:"trigonometric-functions",importName:"postcssTrigonometricFunctions"},{packageName:"@csstools/postcss-nested-calc",id:"nested-calc",importName:"postcssNestedCalc"},{packageName:"@csstools/postcss-text-decoration-shorthand",id:"text-decoration-shorthand",importName:"postcssTextDecorationShorthand"},{packageName:"@csstools/postcss-sign-functions",id:"sign-functions",importName:"postcssSignFunctions"},{packageName:"@csstools/postcss-random-function",id:"random-function",importName:"postcssRandomFunction"},{packageName:"@csstools/postcss-property-rule-prelude-list",id:"property-rule-prelude-list",importName:"postcssPropertyRulePreludeList"},{packageName:"@csstools/postcss-syntax-descriptor-syntax-production",id:"syntax-descriptor-syntax-production",importName:"postcssSyntaxDescriptorSyntaxProduction"},{packageName:"@csstools/postcss-image-function",id:"image-function",importName:"postcssImageFunction"},{packageName:"@csstools/postcss-container-rule-prelude-list",id:"container-rule-prelude-list",importName:"postcssContainerRulePreludeList"},{packageName:"@csstools/postcss-fit-tolerance-property",id:"fit-tolerance-property",importName:"postcssFitToleranceProperty"},{packageName:"@csstools/postcss-property-rule-optional-descriptors",id:"property-rule-optional-descriptors",importName:"postcssPropertyRuleOptionalDescriptors"},{packageName:"@csstools/postcss-custom-functions",id:"custom-functions",importName:"postcssCustomFunctions"},{packageName:"@csstools/postcss-progressive-custom-properties",id:"progressive-custom-properties",importName:"postcssProgressiveCustomProperties",omitTypedOptions:!0,omitDocs:!0}];function getPackageNamesToIds(){const s={};return Bs.forEach(o=>{s[o.packageName]=o.id}),s}function pluginIdHelp(s,o,e){const t=Bs.map(s=>s.id),r=Bs.map(s=>s.packageName),i=getPackageNamesToIds();s.forEach(s=>{if(t.includes(s))return;const a=[...t.map(o=>[o,levenshteinDistance(s,o)]),...r.map(o=>[i[o],levenshteinDistance(s,o)])].sort((s,o)=>s[1]-o[1]).filter(s=>s[1]<10),c=new Set;for(let s=0;s=3));s++);if(!c.size)return void o.warn(e,`Unknown feature: "${s}", see the list of features https://github.com/csstools/postcss-plugins/blob/main/plugin-packs/postcss-preset-env/FEATURES.md`);let p='"';p+=Array.from(c).join('", "'),p+='"',o.warn(e,`Unknown feature: "${s}", did you mean one of: ${p}`)})}function levenshteinDistance(s,o){if(!s.length)return o.length;if(!o.length)return s.length;const e=[];for(let t=0;t<=o.length;t++){e[t]=[t];for(let r=1;r<=s.length;r++)e[t][r]=0===t?r:Math.min(e[t-1][r]+1,e[t][r-1]+1,e[t-1][r-1]+(s[r-1]===o[t-1]?0:1))}return e[o.length][s.length]}const creator=e=>{const t=new Logger,r=Object(e),i=Object.keys(Object(r.features)),a=r.browsers?void 0:r.env,c=r.browsers,p=initializeSharedOptions(r),n=listFeatures(o,r,p,t),l=n.map(s=>s.plugin);!1!==r.autoprefixer&&l.push(s(Object.assign({env:a,overrideBrowserslist:c},r.autoprefixer))),logFeaturesList(n,r,t);const internalPlugin=()=>({postcssPlugin:"postcss-preset-env",OnceExit(s,{result:o}){pluginIdHelp(i,s,o),r.debug&&t.emitLogs(o),t.resetLogger()}});return internalPlugin.postcss=!0,{postcssPlugin:"postcss-preset-env",plugins:[...l,internalPlugin()]}};creator.postcss=!0;export{creator as default,creator as"module.exports"}; +import s from"autoprefixer";import o from"cssdb";import e from"browserslist";import t from"@csstools/postcss-initial";import r from"@csstools/postcss-alpha-function";import i from"postcss-pseudo-class-any-link";import a from"css-blank-pseudo";import c from"postcss-page-break";import p from"@csstools/postcss-cascade-layers";import n from"postcss-attribute-case-insensitive";import l from"postcss-clamp";import m from"@csstools/postcss-color-function";import u from"@csstools/postcss-color-function-display-p3-linear";import d from"postcss-color-functional-notation";import f from"@csstools/postcss-color-mix-function";import g from"@csstools/postcss-color-mix-variadic-function-arguments";import h from"@csstools/postcss-container-rule-prelude-list";import N from"@csstools/postcss-content-alt-text";import b from"@csstools/postcss-contrast-color-function";import y from"@csstools/postcss-custom-functions";import v from"postcss-custom-media";import k from"postcss-custom-properties";import w from"postcss-custom-selectors";import x from"postcss-dir-pseudo-class";import F from"@csstools/postcss-normalize-display-values";import O from"postcss-double-position-gradients";import P from"@csstools/postcss-exponential-functions";import C from"@csstools/postcss-fit-tolerance-property";import $ from"@csstools/postcss-logical-float-and-clear";import S from"postcss-focus-visible";import A from"postcss-focus-within";import L from"@csstools/postcss-font-format-keywords";import _ from"postcss-font-variant";import I from"@csstools/postcss-font-width-property";import E from"@csstools/postcss-gamut-mapping";import B from"postcss-gap-properties";import q from"@csstools/postcss-gradients-interpolation-method";import M from"css-has-pseudo";import D from"postcss-color-hex-alpha";import j from"@csstools/postcss-hwb-function";import z from"@csstools/postcss-ic-unit";import R from"@csstools/postcss-image-function";import U from"postcss-image-set-function";import T from"@csstools/postcss-is-pseudo-class";import V from"postcss-lab-function";import H from"@csstools/postcss-light-dark-function";import W from"@csstools/postcss-logical-overflow";import G from"@csstools/postcss-logical-overscroll-behavior";import K from"postcss-logical";import Z from"@csstools/postcss-logical-resize";import Q from"@csstools/postcss-logical-viewport-units";import J from"@csstools/postcss-media-queries-aspect-ratio-number-values";import X from"@csstools/postcss-media-minmax";import Y from"@csstools/postcss-mixins";import ss from"@csstools/postcss-nested-calc";import os from"postcss-nesting";import es from"postcss-selector-not";import ts from"@csstools/postcss-oklab-function";import rs from"postcss-opacity-percentage";import is from"postcss-overflow-shorthand";import as from"postcss-replace-overflow-wrap";import cs from"postcss-place";import ps from"@csstools/postcss-position-area-property";import ns from"css-prefers-color-scheme";import ls from"@csstools/postcss-progressive-custom-properties";import ms from"@csstools/postcss-property-rule-optional-descriptors";import us from"@csstools/postcss-property-rule-prelude-list";import ds from"@csstools/postcss-random-function";import fs from"postcss-color-rebeccapurple";import gs from"@csstools/postcss-relative-color-syntax";import hs from"@csstools/postcss-scope-pseudo-class";import Ns from"@csstools/postcss-sign-functions";import bs from"@csstools/postcss-stepped-value-functions";import ys from"@csstools/postcss-syntax-descriptor-syntax-production";import vs from"@csstools/postcss-system-ui-font-family";import ks from"@csstools/postcss-text-decoration-shorthand";import ws from"@csstools/postcss-trigonometric-functions";import xs from"@csstools/postcss-unset-value";const Fs={"blank-pseudo-class":"https://github.com/csstools/postcss-plugins/blob/main/plugins/css-blank-pseudo/README.md#browser","focus-visible-pseudo-class":"https://github.com/WICG/focus-visible","focus-within-pseudo-class":"https://github.com/csstools/postcss-plugins/blob/main/plugins/postcss-focus-within/README.md#browser","has-pseudo-class":"https://github.com/csstools/postcss-plugins/blob/main/plugins/css-has-pseudo/README.md#browser","prefers-color-scheme-query":"https://github.com/csstools/postcss-plugins/blob/main/plugins/css-prefers-color-scheme/README.md#browser"},Os=["blank-pseudo-class","focus-visible-pseudo-class","focus-within-pseudo-class","has-pseudo-class","prefers-color-scheme-query"];function logFeaturesList(s,o,e){if(o.debug){e.log("Enabling the following feature(s):");const t=[],r=[];!1!==o.autoprefixer&&r.push(" autoprefixer"),s.forEach(s=>{s.id.startsWith("before")||s.id.startsWith("after")?r.push(` ${s.id} (injected via options)`):r.push(` ${s.id}`),void 0!==Fs[s.id]&&t.push(s.id)}),r.sort((s,o)=>s.localeCompare(o)),t.sort((s,o)=>s.localeCompare(o)),r.forEach(s=>e.log(s)),t.length&&(e.log("These feature(s) need a browser library to work:"),t.forEach(s=>e.log(` ${s}: ${Fs[s]}`)))}}function initializeSharedOptions(s){if("preserve"in s){const o={};return o.preserve=s.preserve,o}return!1}function clamp(s,o,e){return Math.max(s,Math.min(o,e))}function stageFromOptions(s,o){let e=2;if(void 0===s.stage)return o.log("Using features from Stage 2 (default)."),e;if(!1===s.stage)e=5;else{let o=parseInt(s.stage,10);Number.isNaN(o)&&(o=0),e=clamp(0,o,5)}return 5===e?o.log('Stage has been disabled, features will be handled via the "features" option.'):o.log(`Using features from Stage ${e}.`),e}const Ps=Symbol("insertBefore"),Cs=Symbol("insertAfter"),$s=Symbol("insertOrder"),Ss=Symbol("plugin");function getTransformedInsertions(s,o,e){if("insertBefore"!==e&&"insertAfter"!==e)return[];const t="insertBefore"===e?Ps:Cs,r=[];for(const e in o){if(!Object.hasOwnProperty.call(o,e))continue;if(!s.find(s=>s.id===e))continue;let i=o[e];Array.isArray(i)||(i=[i]);for(let s=0;sfeatureIsInsertedOrHasAPlugin(s)).sort((s,o)=>featureIsLess(s,o))}function getOptionsForBrowsersByFeature(s,o,e,t){switch(o.id){case"is-pseudo-class":return{onComplexSelector:"warning"};case"any-link-pseudo-class":if(s.find(s=>s.startsWith("ie ")||"edge 12"===s||"edge 13"===s||"edge 14"===s||"edge 15"===s||"edge 16"===s||"edge 17"===s||"edge 18"===s))return t.log("- 'any-link-pseudo-class' setting 'subFeatures: { areaHrefNeedsFixing: true }' due to lack of browser support for area[href] in Edge and IE."),{subFeatures:{areaHrefNeedsFixing:!0}};return{};case"logical-properties-and-values":case"float-clear-logical-values":case"logical-resize":case"logical-viewport-units":case"logical-overflow":case"logical-overscroll-behavior":return"logical"in e?e.logical:{};default:return{}}}const _s=["and_chr","and_ff","android","chrome","edge","firefox","ie","ios_saf","op_mini","op_mob","opera","safari","samsung"];function getUnsupportedBrowsersByFeature(s){if(!s)return[];if("position-area-property"===s.id)return["chrome 125","chrome 126","chrome 127","chrome 128","edge 125","edge 126","edge 127","edge 128","and_chr 125","and_chr 126","and_chr 127","and_chr 128","android 125","android 126","android 127","android 128","samsung 27","opera 111","opera 112","opera 113","opera 114","op_mob 83","op_mob 84","op_mob 85"];if(!("browser_support"in s))return["> 0%"];const o=[];return _s.forEach(e=>{if("op_mini"===e&&void 0===s.browser_support[e])return void o.push("op_mini all");const t=s.browser_support[e];"string"==typeof t&&Is.test(t)?o.push(`${e} < ${s.browser_support[e]}`):o.push(`${e} >= 1`)}),o}const Is=/^[0-9|.]+$/;function formatPolyfillableFeature(s){const o=getUnsupportedBrowsersByFeature(s);if(s[Ps]||s[Cs]){let e=s.id;return e=s.insertBefore?`before-${e}`:`after-${e}`,{browsers:o,vendors_implementations:s.vendors_implementations,plugin:s[Ss],id:e,stage:6}}return{browsers:o,vendors_implementations:s.vendors_implementations,plugin:Ls.get(s.id),id:s.id,stage:s.stage}}function formatStagedFeature(s,o,e,t,r,i){let a,c;return a=getOptionsForBrowsersByFeature(s,e,r,i),a=t?Object.assign({},a,t,featureOptions(o,e.id)):Object.assign({},a,featureOptions(o,e.id)),"progressive-custom-properties"!==e.id&&(a.enableProgressiveCustomProperties=!1),"overflow-wrap-property"===e.id&&"preserve"in a&&(a.method=a.preserve?"copy":"replace"),c=e.plugin.postcss&&"function"==typeof e.plugin?e.plugin(a):e.plugin&&e.plugin.default&&"function"==typeof e.plugin.default&&e.plugin.default.postcss?e.plugin.default(a):e.plugin,{browsers:e.browsers,vendors_implementations:e.vendors_implementations,plugin:c,pluginOptions:a,id:e.id}}function featureOptions(s,o){if(!(o in s))return;const e=s[o];return Array.isArray(e)?e[1]:e}function intOrZero(s){const o=parseInt(s,10);return Number.isNaN(o)?0:o}const Es=new Set(["progressive-custom-properties"]);function listFeatures(s,o,t,r){const i=Object(o.features),a="enableClientSidePolyfills"in o&&o.enableClientSidePolyfills,c=Object(o.insertBefore),p=Object(o.insertAfter),n=o.browsers?void 0:o.env,l=o.browsers,m=clamp(0,intOrZero(o.minimumVendorImplementations),3);m>0&&r.log(`Using features with ${m} or more vendor implementations.`);const u=stageFromOptions(o,r),d=prepareFeaturesList([...s,{id:"progressive-custom-properties"}],c,p).map(s=>formatPolyfillableFeature(s)).filter(s=>!!Es.has(s.id)||(0===m||(!(!s[Ps]&&!s[Cs])||(m<=s.vendors_implementations||(!0===featureEnabledByOptions(i,s.id)?(r.log(`- '${s.id}' enabled manually even when it lacks the required interop (${s.vendors_implementations} out of ${m}).`),!0):(r.log(`- '${s.id}' disabled because it lacks the required interop (${s.vendors_implementations} out of ${m}).`),!1)))))),f=e(l,{env:n,ignoreUnknownVersions:!0}).filter(s=>_s.includes(s.split(" ")[0]));return d.filter(s=>{if(Es.has(s.id))return!0;const o=s.stage>=u,e=a||!Os.includes(s.id),t=featureEnabledByOptions(i,s.id),c=!1===t,p=!0===t||o&&e;return c?r.log(`- '${s.id}' disabled manually`):o?e||r.log(`- '${s.id}' disabled because 'enableClientSidePolyfills' is 'false'.`):p?r.log(`- '${s.id}' enabled manually even when it lacks the required stage (${s.stage} out of ${u}).`):r.log(`- '${s.id}' disabled because it lacks the required stage (${s.stage} out of ${u}).`),!c&&p}).map(s=>formatStagedFeature(f,i,s,t,o,r)).filter(s=>{if(Es.has(s.id))return!0;const o=featureEnabledByOptions(i,s.id);if(!0===o||!1===o)return o;const t=e(s.browsers,{ignoreUnknownVersions:!0}),a=f.filter(s=>t.some(o=>o===s));return a.length>0?r.log(`- '${s.id}' enabled for:\n ${a.join("\n ")}`):r.log(`- '${s.id}' disabled because all targeted browsers support it.`),a.length>0})}function featureEnabledByOptions(s,o){if(!(o in s))return"auto";const e=s[o];return Array.isArray(e)?!0===e[0]||!1!==e[0]&&"auto":Boolean(e)}class Logger{constructor(){this.logs=[]}log(s){this.logs.push(s)}resetLogger(){this.logs.length=0}emitLogs(s){s&&s.warn(this.logs.join("\n")),this.resetLogger()}}var Bs=[{packageName:"css-blank-pseudo",id:"blank-pseudo-class",importName:"postcssBlankPseudo"},{packageName:"css-has-pseudo",id:"has-pseudo-class",importName:"postcssHasPseudo"},{packageName:"css-prefers-color-scheme",id:"prefers-color-scheme-query",importName:"postcssPrefersColorScheme"},{packageName:"postcss-attribute-case-insensitive",id:"case-insensitive-attributes",importName:"postcssAttributeCaseInsensitive"},{packageName:"postcss-clamp",id:"clamp",importName:"postcssClamp"},{packageName:"@csstools/postcss-alpha-function",id:"alpha-function",importName:"postcssAlphaFunction"},{packageName:"@csstools/postcss-color-mix-variadic-function-arguments",id:"color-mix-variadic-function-arguments",importName:"postcssColorMixVariadicFunctionArguments"},{packageName:"@csstools/postcss-color-mix-function",id:"color-mix",importName:"postcssColorMixFunction"},{packageName:"@csstools/postcss-color-function",id:"color-function",importName:"postcssColorFunction"},{packageName:"@csstools/postcss-color-function-display-p3-linear",id:"color-function-display-p3-linear",importName:"postcssColorFunctionDisplayP3Linear"},{packageName:"postcss-color-functional-notation",id:"color-functional-notation",importName:"postcssColorFunctionalNotation"},{packageName:"postcss-color-hex-alpha",id:"hexadecimal-alpha-notation",importName:"postcssColorHexAlpha"},{packageName:"@csstools/postcss-content-alt-text",id:"content-alt-text",importName:"postcssContentAltText"},{packageName:"postcss-color-rebeccapurple",id:"rebeccapurple-color",importName:"postcssColorRebeccapurple"},{packageName:"@csstools/postcss-contrast-color-function",id:"contrast-color-function",importName:"postcssContrastColorFunction"},{packageName:"postcss-custom-media",id:"custom-media-queries",importName:"postcssCustomMedia"},{packageName:"postcss-custom-properties",id:"custom-properties",importName:"postcssCustomProperties"},{packageName:"postcss-custom-selectors",id:"custom-selectors",importName:"postcssCustomSelectors"},{packageName:"postcss-dir-pseudo-class",id:"dir-pseudo-class",importName:"postcssDirPseudoClass"},{packageName:"postcss-double-position-gradients",id:"double-position-gradients",importName:"postcssDoublePositionGradients"},{packageName:"@csstools/postcss-exponential-functions",id:"exponential-functions",importName:"postcssExponentialFunctions"},{packageName:"postcss-focus-visible",id:"focus-visible-pseudo-class",importName:"postcssFocusVisible"},{packageName:"postcss-focus-within",id:"focus-within-pseudo-class",importName:"postcssFocusWithin"},{packageName:"@csstools/postcss-font-format-keywords",id:"font-format-keywords",importName:"postcssFontFormatKeywords"},{packageName:"postcss-font-variant",id:"font-variant-property",importName:"postcssFontVariant"},{packageName:"@csstools/postcss-font-width-property",id:"font-width-property",importName:"postcssFontWidthProperty"},{packageName:"@csstools/postcss-gamut-mapping",id:"gamut-mapping",importName:"postcssGamutMapping"},{packageName:"postcss-gap-properties",id:"gap-properties",importName:"postcssGapProperties"},{packageName:"@csstools/postcss-gradients-interpolation-method",id:"gradients-interpolation-method",importName:"postcssGradientsInterpolationMethod"},{packageName:"@csstools/postcss-hwb-function",id:"hwb-function",importName:"postcssHWBFunction"},{packageName:"@csstools/postcss-ic-unit",id:"ic-unit",importName:"postcssICUnit"},{packageName:"postcss-image-set-function",id:"image-set-function",importName:"postcssImageSetFunction"},{packageName:"@csstools/postcss-initial",id:"all-property",importName:"postcssInitial"},{packageName:"@csstools/postcss-is-pseudo-class",id:"is-pseudo-class",importName:"postcssIsPseudoClass"},{packageName:"@csstools/postcss-scope-pseudo-class",id:"scope-pseudo-class",importName:"postcssScopePseudoClass"},{packageName:"postcss-lab-function",id:"lab-function",importName:"postcssLabFunction"},{packageName:"@csstools/postcss-light-dark-function",id:"light-dark-function",importName:"postcssLightDarkFunction"},{packageName:"postcss-logical",id:"logical-properties-and-values",importName:"postcssLogical"},{packageName:"@csstools/postcss-logical-float-and-clear",id:"float-clear-logical-values",importName:"postcssLogicalFloatAndClear"},{packageName:"@csstools/postcss-logical-overflow",id:"logical-overflow",importName:"postcssLogicalOverflow"},{packageName:"@csstools/postcss-logical-overscroll-behavior",id:"logical-overscroll-behavior",importName:"postcssLogicalOverscrollBehavor"},{packageName:"@csstools/postcss-logical-resize",id:"logical-resize",importName:"postcssLogicalResize"},{packageName:"@csstools/postcss-logical-viewport-units",id:"logical-viewport-units",importName:"postcssLogicalViewportUnits"},{packageName:"@csstools/postcss-media-minmax",id:"media-query-ranges",importName:"postcssMediaMinmax"},{packageName:"@csstools/postcss-media-queries-aspect-ratio-number-values",id:"media-queries-aspect-ratio-number-values",importName:"postcssMediaQueriesAspectRatioNumberValues"},{packageName:"@csstools/postcss-mixins",id:"mixins",importName:"postcssMixins"},{packageName:"postcss-nesting",id:"nesting-rules",importName:"postcssNesting"},{packageName:"@csstools/postcss-normalize-display-values",id:"display-two-values",importName:"postcssNormalizeDisplayValues"},{packageName:"@csstools/postcss-oklab-function",id:"oklab-function",importName:"postcssOKLabFunction"},{packageName:"@csstools/postcss-relative-color-syntax",id:"relative-color-syntax",importName:"postcssRelativeColorSyntax"},{packageName:"postcss-opacity-percentage",id:"opacity-percentage",importName:"postcssOpacityPercentage"},{packageName:"postcss-overflow-shorthand",id:"overflow-property",importName:"postcssOverflowShorthand"},{packageName:"postcss-page-break",id:"break-properties",importName:"postcssPageBreak"},{packageName:"@csstools/postcss-position-area-property",id:"position-area-property",importName:"postcssPositionAreaProperty"},{packageName:"postcss-place",id:"place-properties",importName:"postcssPlace"},{packageName:"postcss-pseudo-class-any-link",id:"any-link-pseudo-class",importName:"postcssPseudoClassAnyLink"},{packageName:"postcss-replace-overflow-wrap",id:"overflow-wrap-property",importName:"postcssReplaceOverflowWrap"},{packageName:"postcss-selector-not",id:"not-pseudo-class",importName:"postcssSelectorNot"},{packageName:"@csstools/postcss-stepped-value-functions",id:"stepped-value-functions",importName:"postcssSteppedValueFunctions"},{packageName:"@csstools/postcss-system-ui-font-family",id:"system-ui-font-family",importName:"postcssSystemUIFontFamily"},{packageName:"@csstools/postcss-unset-value",id:"unset-value",importName:"postcssUnsetValue"},{packageName:"@csstools/postcss-cascade-layers",id:"cascade-layers",importName:"postcssCascadeLayers"},{packageName:"@csstools/postcss-trigonometric-functions",id:"trigonometric-functions",importName:"postcssTrigonometricFunctions"},{packageName:"@csstools/postcss-nested-calc",id:"nested-calc",importName:"postcssNestedCalc"},{packageName:"@csstools/postcss-text-decoration-shorthand",id:"text-decoration-shorthand",importName:"postcssTextDecorationShorthand"},{packageName:"@csstools/postcss-sign-functions",id:"sign-functions",importName:"postcssSignFunctions"},{packageName:"@csstools/postcss-random-function",id:"random-function",importName:"postcssRandomFunction"},{packageName:"@csstools/postcss-property-rule-prelude-list",id:"property-rule-prelude-list",importName:"postcssPropertyRulePreludeList"},{packageName:"@csstools/postcss-syntax-descriptor-syntax-production",id:"syntax-descriptor-syntax-production",importName:"postcssSyntaxDescriptorSyntaxProduction"},{packageName:"@csstools/postcss-image-function",id:"image-function",importName:"postcssImageFunction"},{packageName:"@csstools/postcss-container-rule-prelude-list",id:"container-rule-prelude-list",importName:"postcssContainerRulePreludeList"},{packageName:"@csstools/postcss-fit-tolerance-property",id:"fit-tolerance-property",importName:"postcssFitToleranceProperty"},{packageName:"@csstools/postcss-property-rule-optional-descriptors",id:"property-rule-optional-descriptors",importName:"postcssPropertyRuleOptionalDescriptors"},{packageName:"@csstools/postcss-custom-functions",id:"custom-functions",importName:"postcssCustomFunctions"},{packageName:"@csstools/postcss-progressive-custom-properties",id:"progressive-custom-properties",importName:"postcssProgressiveCustomProperties",omitTypedOptions:!0,omitDocs:!0}];function getPackageNamesToIds(){const s={};return Bs.forEach(o=>{s[o.packageName]=o.id}),s}function pluginIdHelp(s,o,e){const t=Bs.map(s=>s.id),r=Bs.map(s=>s.packageName),i=getPackageNamesToIds();s.forEach(s=>{if(t.includes(s))return;const a=[...t.map(o=>[o,levenshteinDistance(s,o)]),...r.map(o=>[i[o],levenshteinDistance(s,o)])].sort((s,o)=>s[1]-o[1]).filter(s=>s[1]<10),c=new Set;for(let s=0;s=3));s++);if(!c.size)return void o.warn(e,`Unknown feature: "${s}", see the list of features https://github.com/csstools/postcss-plugins/blob/main/plugin-packs/postcss-preset-env/FEATURES.md`);let p='"';p+=Array.from(c).join('", "'),p+='"',o.warn(e,`Unknown feature: "${s}", did you mean one of: ${p}`)})}function levenshteinDistance(s,o){if(!s.length)return o.length;if(!o.length)return s.length;const e=[];for(let t=0;t<=o.length;t++){e[t]=[t];for(let r=1;r<=s.length;r++)e[t][r]=0===t?r:Math.min(e[t-1][r]+1,e[t][r-1]+1,e[t-1][r-1]+(s[r-1]===o[t-1]?0:1))}return e[o.length][s.length]}const creator=e=>{const t=new Logger,r=Object(e),i=Object.keys(Object(r.features)),a=r.browsers?void 0:r.env,c=r.browsers,p=initializeSharedOptions(r),n=listFeatures(o,r,p,t),l=n.map(s=>s.plugin);!1!==r.autoprefixer&&l.push(s(Object.assign({env:a,overrideBrowserslist:c},r.autoprefixer))),logFeaturesList(n,r,t);const internalPlugin=()=>({postcssPlugin:"postcss-preset-env",OnceExit(s,{result:o}){pluginIdHelp(i,s,o),r.debug&&t.emitLogs(o),t.resetLogger()}});return internalPlugin.postcss=!0,{postcssPlugin:"postcss-preset-env",plugins:[...l,internalPlugin()]}};creator.postcss=!0;export{creator as default,creator as"module.exports"}; 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 bda5cb6016..41e81b72bd 100644 --- a/plugin-packs/postcss-preset-env/test/basic.autoprefixer.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.autoprefixer.expect.css @@ -433,6 +433,8 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .oklch { color-7: color(display-p3 0.19244 0.58461 0.51559); @@ -442,6 +444,7 @@ color-11: color(display-p3 0.19244 0.58461 0.51559); } } +} .alpha { color-1: rgba(188, 101, 59, 0.3); @@ -574,11 +577,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .color-mix { color-4: color(display-p3 0.44 0 0.70096 / 0.65); color-5: color(display-p3 0.54692 0 0.47541 / 0.65); } } +} .gradients-interpolation-method { --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(188, 179, 255), rgb(164, 192, 255), rgb(137, 206, 255), rgb(111, 218, 255), rgb(93, 229, 255), rgb(94, 237, 237) 100%); @@ -586,29 +592,35 @@ background-image: radial-gradient(farthest-corner circle at 50% 115%, rgb(255, 71, 0) 0%, rgb(255, 103, 0), rgb(255, 137, 0), rgb(255, 169, 0), rgb(250, 199, 0), rgb(197, 225, 0), rgb(116, 246, 0), rgb(0, 255, 86), rgb(0, 255, 171), rgb(0, 255, 239), rgb(0, 255, 255) 100%); } -@media (color-gamut: rec2020) { +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - - background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); - - background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); + --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); } } -@supports (color: color(display-p3 0 0 0%)) { +@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { .gradients-interpolation-method { + --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); +} } @media (color-gamut: rec2020) { + +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); } } } -@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { +@media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); +} } } @@ -625,11 +637,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .test-css-color-5-interop { color-8: color(display-p3 0.4939 0.10676 0); color-9: color(display-p3 0.47553 0.14324 0); } } +} .test-property-with-var { --opacity: 1; @@ -675,10 +690,13 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .schemed-colors { color: light-dark(color(display-p3 0.4939 0.10676 0), magenta); } } +} .schemed-prop { --csstools-light-dark-toggle--0: var(--csstools-color-scheme--light) deepskyblue; @@ -735,11 +753,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .random { border-color: color(display-p3 0.08293 0.41734 0); } } +} .contrast-color { color: rgb(255, 255, 255); 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 7be7f48572..ab0e833e42 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 @@ -433,6 +433,8 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .oklch { color-7: color(display-p3 0.19244 0.58461 0.51559); @@ -442,6 +444,7 @@ color-11: color(display-p3 0.19244 0.58461 0.51559); } } +} .alpha { color-1: rgba(188, 101, 59, 0.3); @@ -574,11 +577,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .color-mix { color-4: color(display-p3 0.44 0 0.70096 / 0.65); color-5: color(display-p3 0.54692 0 0.47541 / 0.65); } } +} .gradients-interpolation-method { --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(188, 179, 255), rgb(164, 192, 255), rgb(137, 206, 255), rgb(111, 218, 255), rgb(93, 229, 255), rgb(94, 237, 237) 100%); @@ -586,29 +592,35 @@ background-image: radial-gradient(farthest-corner circle at 50% 115%, rgb(255, 71, 0) 0%, rgb(255, 103, 0), rgb(255, 137, 0), rgb(255, 169, 0), rgb(250, 199, 0), rgb(197, 225, 0), rgb(116, 246, 0), rgb(0, 255, 86), rgb(0, 255, 171), rgb(0, 255, 239), rgb(0, 255, 255) 100%); } -@media (color-gamut: rec2020) { +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - - background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); - - background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); + --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); } } -@supports (color: color(display-p3 0 0 0%)) { +@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { .gradients-interpolation-method { + --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); +} } @media (color-gamut: rec2020) { + +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); } } } -@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { +@media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); +} } } @@ -625,11 +637,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .test-css-color-5-interop { color-8: color(display-p3 0.4939 0.10676 0); color-9: color(display-p3 0.47553 0.14324 0); } } +} .test-property-with-var { --opacity: 1; @@ -680,10 +695,13 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .schemed-colors { color: light-dark(color(display-p3 0.4939 0.10676 0), magenta); } } +} .schemed-prop { --csstools-light-dark-toggle--0: var(--csstools-color-scheme--light) deepskyblue; @@ -740,11 +758,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .random { border-color: color(display-p3 0.08293 0.41734 0); } } +} .contrast-color { color: rgb(255, 255, 255); diff --git a/plugin-packs/postcss-preset-env/test/basic.autoprefixer.remove.false.expect.css b/plugin-packs/postcss-preset-env/test/basic.autoprefixer.remove.false.expect.css index fde6f091be..e2e72381d7 100644 --- a/plugin-packs/postcss-preset-env/test/basic.autoprefixer.remove.false.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.autoprefixer.remove.false.expect.css @@ -449,6 +449,8 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .oklch { color-7: color(display-p3 0.19244 0.58461 0.51559); @@ -458,6 +460,7 @@ color-11: color(display-p3 0.19244 0.58461 0.51559); } } +} .alpha { color-1: rgba(188, 101, 59, 0.3); @@ -592,11 +595,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .color-mix { color-4: color(display-p3 0.44 0 0.70096 / 0.65); color-5: color(display-p3 0.54692 0 0.47541 / 0.65); } } +} .gradients-interpolation-method { --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(188, 179, 255), rgb(164, 192, 255), rgb(137, 206, 255), rgb(111, 218, 255), rgb(93, 229, 255), rgb(94, 237, 237) 100%); @@ -604,29 +610,35 @@ background-image: radial-gradient(farthest-corner circle at 50% 115%, rgb(255, 71, 0) 0%, rgb(255, 103, 0), rgb(255, 137, 0), rgb(255, 169, 0), rgb(250, 199, 0), rgb(197, 225, 0), rgb(116, 246, 0), rgb(0, 255, 86), rgb(0, 255, 171), rgb(0, 255, 239), rgb(0, 255, 255) 100%); } -@media (color-gamut: rec2020) { +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - - background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); - - background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); + --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); } } -@supports (color: color(display-p3 0 0 0%)) { +@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { .gradients-interpolation-method { + --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); +} } @media (color-gamut: rec2020) { + +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); } } } -@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { +@media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); +} } } @@ -643,11 +655,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .test-css-color-5-interop { color-8: color(display-p3 0.4939 0.10676 0); color-9: color(display-p3 0.47553 0.14324 0); } } +} .test-property-with-var { --opacity: 1; @@ -698,10 +713,13 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .schemed-colors { color: light-dark(color(display-p3 0.4939 0.10676 0), magenta); } } +} .schemed-prop { --csstools-light-dark-toggle--0: var(--csstools-color-scheme--light) deepskyblue; @@ -758,11 +776,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .random { border-color: color(display-p3 0.08293 0.41734 0); } } +} .contrast-color { color: rgb(255, 255, 255); diff --git a/plugin-packs/postcss-preset-env/test/basic.ch126.expect.css b/plugin-packs/postcss-preset-env/test/basic.ch126.expect.css index 4ef20b4bc7..297e6e94ee 100644 --- a/plugin-packs/postcss-preset-env/test/basic.ch126.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.ch126.expect.css @@ -277,10 +277,13 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .color-function { prop-1: color(display-p3 0.00000 0.51872 0.36985); } } +} .oklab { color-1: oklab(40% 0.001236 0.0039); @@ -320,6 +323,8 @@ } @media (color-gamut: p3) { + +@supports (color: oklab(0% 0 0%)) { .oklch { color-7: oklch(60% 0.1250 180); @@ -329,6 +334,7 @@ color-11: oklch(60% 0.1250 3.14159rad); } } +} .alpha { color-1: oklch(from oklch(60% 0.1250 45deg / 0.2) l c h / calc(alpha + 0.1)); @@ -460,11 +466,14 @@ } @media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { .gradients-interpolation-method { background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); } } +} .test-css-color-5-interop { color-1: color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / alpha); @@ -479,11 +488,14 @@ } @media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { .test-css-color-5-interop { color-8: oklab(from oklab(40% 0.566 0.39) l a b); color-9: oklch(from oklch(40% 0.566 39deg) l c h); } } +} .test-property-with-var { --opacity: 1; @@ -499,10 +511,13 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .out-of-gamut { --color: color(display-p3 0 1 0); } } +} .issue-1244--a { background-image: -ms-linear-gradient(180deg, red 0%, blue 100%); @@ -529,10 +544,13 @@ } @media (color-gamut: rec2020) { + +@supports (color: lab(0% 0 0%)) and (color: oklab(0% 0 0%)) { .schemed-colors { color: light-dark(lch(from oklab(40% 0.566 0.39) l c h), magenta); } } +} .schemed-prop { --theme-color: light-dark(cyan, deepskyblue); @@ -567,6 +585,8 @@ } @media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { .random { border-color: oklch( @@ -576,6 +596,7 @@ ); } } +} .contrast-color { color: rgb(255, 255, 255); diff --git a/plugin-packs/postcss-preset-env/test/basic.ch130.expect.css b/plugin-packs/postcss-preset-env/test/basic.ch130.expect.css index ed27b45096..218515b760 100644 --- a/plugin-packs/postcss-preset-env/test/basic.ch130.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.ch130.expect.css @@ -277,10 +277,13 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .color-function { prop-1: color(display-p3 0.00000 0.51872 0.36985); } } +} .oklab { color-1: oklab(40% 0.001236 0.0039); @@ -320,6 +323,8 @@ } @media (color-gamut: p3) { + +@supports (color: oklab(0% 0 0%)) { .oklch { color-7: oklch(60% 0.1250 180); @@ -329,6 +334,7 @@ color-11: oklch(60% 0.1250 3.14159rad); } } +} .alpha { color-1: oklch(from oklch(60% 0.1250 45deg / 0.2) l c h / calc(alpha + 0.1)); @@ -460,11 +466,14 @@ } @media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { .gradients-interpolation-method { background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); } } +} .test-css-color-5-interop { color-1: color(from color(a98-rgb 0.7 0.5 0.3) a98-rgb r g b / alpha); @@ -479,11 +488,14 @@ } @media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { .test-css-color-5-interop { color-8: oklab(from oklab(40% 0.566 0.39) l a b); color-9: oklch(from oklch(40% 0.566 39deg) l c h); } } +} .test-property-with-var { --opacity: 1; @@ -499,10 +511,13 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .out-of-gamut { --color: color(display-p3 0 1 0); } } +} .issue-1244--a { background-image: -ms-linear-gradient(180deg, red 0%, blue 100%); @@ -529,10 +544,13 @@ } @media (color-gamut: rec2020) { + +@supports (color: lab(0% 0 0%)) and (color: oklab(0% 0 0%)) { .schemed-colors { color: light-dark(lch(from oklab(40% 0.566 0.39) l c h), magenta); } } +} .schemed-prop { --theme-color: light-dark(cyan, deepskyblue); @@ -567,6 +585,8 @@ } @media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { .random { border-color: oklch( @@ -576,6 +596,7 @@ ); } } +} .contrast-color { color: rgb(255, 255, 255); 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 06e837d8a0..927f12b3e4 100644 --- a/plugin-packs/postcss-preset-env/test/basic.ch38.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.ch38.expect.css @@ -346,6 +346,8 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .oklch { color-7: color(display-p3 0.19244 0.58461 0.51559); @@ -355,6 +357,7 @@ color-11: color(display-p3 0.19244 0.58461 0.51559); } } +} .alpha { color-1: rgba(188, 101, 59, 0.3); @@ -486,11 +489,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .color-mix { color-4: color(display-p3 0.44 0 0.70096 / 0.65); color-5: color(display-p3 0.54692 0 0.47541 / 0.65); } } +} .gradients-interpolation-method { --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(188, 179, 255), rgb(164, 192, 255), rgb(137, 206, 255), rgb(111, 218, 255), rgb(93, 229, 255), rgb(94, 237, 237) 100%); @@ -498,29 +504,35 @@ background-image: radial-gradient(farthest-corner circle at 50% 115%, rgb(255, 71, 0) 0%, rgb(255, 103, 0), rgb(255, 137, 0), rgb(255, 169, 0), rgb(250, 199, 0), rgb(197, 225, 0), rgb(116, 246, 0), rgb(0, 255, 86), rgb(0, 255, 171), rgb(0, 255, 239), rgb(0, 255, 255) 100%); } -@media (color-gamut: rec2020) { +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - - background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); - - background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); + --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); } } -@supports (color: color(display-p3 0 0 0%)) { +@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { .gradients-interpolation-method { + --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); +} } @media (color-gamut: rec2020) { + +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); } } } -@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { +@media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); +} } } @@ -537,11 +549,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .test-css-color-5-interop { color-8: color(display-p3 0.4939 0.10676 0); color-9: color(display-p3 0.47553 0.14324 0); } } +} .test-property-with-var { --opacity: 1; @@ -587,10 +602,13 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .schemed-colors { color: light-dark(color(display-p3 0.4939 0.10676 0), magenta); } } +} .schemed-prop { --csstools-light-dark-toggle--0: var(--csstools-color-scheme--light) deepskyblue; @@ -647,11 +665,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .random { border-color: color(display-p3 0.08293 0.41734 0); } } +} .contrast-color { color: rgb(255, 255, 255); diff --git a/plugin-packs/postcss-preset-env/test/basic.edge16.expect.css b/plugin-packs/postcss-preset-env/test/basic.edge16.expect.css index d7b659cd9a..2da05edc77 100644 --- a/plugin-packs/postcss-preset-env/test/basic.edge16.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.edge16.expect.css @@ -433,6 +433,8 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .oklch { color-7: color(display-p3 0.19244 0.58461 0.51559); @@ -442,6 +444,7 @@ color-11: color(display-p3 0.19244 0.58461 0.51559); } } +} .alpha { color-1: rgba(188, 101, 59, 0.3); @@ -568,11 +571,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .color-mix { color-4: color(display-p3 0.44 0 0.70096 / 0.65); color-5: color(display-p3 0.54692 0 0.47541 / 0.65); } } +} .gradients-interpolation-method { --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(188, 179, 255), rgb(164, 192, 255), rgb(137, 206, 255), rgb(111, 218, 255), rgb(93, 229, 255), rgb(94, 237, 237) 100%); @@ -580,29 +586,35 @@ background-image: radial-gradient(farthest-corner circle at 50% 115%, rgb(255, 71, 0) 0%, rgb(255, 103, 0), rgb(255, 137, 0), rgb(255, 169, 0), rgb(250, 199, 0), rgb(197, 225, 0), rgb(116, 246, 0), rgb(0, 255, 86), rgb(0, 255, 171), rgb(0, 255, 239), rgb(0, 255, 255) 100%); } -@media (color-gamut: rec2020) { +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - - background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); - - background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); + --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); } } -@supports (color: color(display-p3 0 0 0%)) { +@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { .gradients-interpolation-method { + --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); +} } @media (color-gamut: rec2020) { + +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); } } } -@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { +@media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); +} } } @@ -619,11 +631,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .test-css-color-5-interop { color-8: color(display-p3 0.4939 0.10676 0); color-9: color(display-p3 0.47553 0.14324 0); } } +} .test-property-with-var { --opacity: 1; @@ -667,10 +682,13 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .schemed-colors { color: light-dark(color(display-p3 0.4939 0.10676 0), magenta); } } +} .schemed-prop { --csstools-light-dark-toggle--0: var(--csstools-color-scheme--light) deepskyblue; @@ -727,11 +745,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .random { border-color: color(display-p3 0.08293 0.41734 0); } } +} .contrast-color { color: rgb(255, 255, 255); diff --git a/plugin-packs/postcss-preset-env/test/basic.expect.css b/plugin-packs/postcss-preset-env/test/basic.expect.css index 17aeaeba9a..5e4109f102 100644 --- a/plugin-packs/postcss-preset-env/test/basic.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.expect.css @@ -449,6 +449,8 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .oklch { color-7: color(display-p3 0.19244 0.58461 0.51559); @@ -458,6 +460,7 @@ color-11: color(display-p3 0.19244 0.58461 0.51559); } } +} .alpha { color-1: rgba(188, 101, 59, 0.3); @@ -592,11 +595,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .color-mix { color-4: color(display-p3 0.44 0 0.70096 / 0.65); color-5: color(display-p3 0.54692 0 0.47541 / 0.65); } } +} .gradients-interpolation-method { --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(188, 179, 255), rgb(164, 192, 255), rgb(137, 206, 255), rgb(111, 218, 255), rgb(93, 229, 255), rgb(94, 237, 237) 100%); @@ -604,29 +610,35 @@ background-image: radial-gradient(farthest-corner circle at 50% 115%, rgb(255, 71, 0) 0%, rgb(255, 103, 0), rgb(255, 137, 0), rgb(255, 169, 0), rgb(250, 199, 0), rgb(197, 225, 0), rgb(116, 246, 0), rgb(0, 255, 86), rgb(0, 255, 171), rgb(0, 255, 239), rgb(0, 255, 255) 100%); } -@media (color-gamut: rec2020) { +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - - background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); - - background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); + --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); } } -@supports (color: color(display-p3 0 0 0%)) { +@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { .gradients-interpolation-method { + --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); +} } @media (color-gamut: rec2020) { + +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); } } } -@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { +@media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); +} } } @@ -643,11 +655,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .test-css-color-5-interop { color-8: color(display-p3 0.4939 0.10676 0); color-9: color(display-p3 0.47553 0.14324 0); } } +} .test-property-with-var { --opacity: 1; @@ -693,10 +708,13 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .schemed-colors { color: light-dark(color(display-p3 0.4939 0.10676 0), magenta); } } +} .schemed-prop { --csstools-light-dark-toggle--0: var(--csstools-color-scheme--light) deepskyblue; @@ -753,11 +771,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .random { border-color: color(display-p3 0.08293 0.41734 0); } } +} .contrast-color { color: rgb(255, 255, 255); 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 6b7507d379..8399b8c5d3 100644 --- a/plugin-packs/postcss-preset-env/test/basic.ff49.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.ff49.expect.css @@ -350,6 +350,8 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .oklch { color-7: color(display-p3 0.19244 0.58461 0.51559); @@ -359,6 +361,7 @@ color-11: color(display-p3 0.19244 0.58461 0.51559); } } +} .alpha { color-1: rgba(188, 101, 59, 0.3); @@ -485,11 +488,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .color-mix { color-4: color(display-p3 0.44 0 0.70096 / 0.65); color-5: color(display-p3 0.54692 0 0.47541 / 0.65); } } +} .gradients-interpolation-method { --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(188, 179, 255), rgb(164, 192, 255), rgb(137, 206, 255), rgb(111, 218, 255), rgb(93, 229, 255), rgb(94, 237, 237) 100%); @@ -497,29 +503,35 @@ background-image: radial-gradient(farthest-corner circle at 50% 115%, rgb(255, 71, 0) 0%, rgb(255, 103, 0), rgb(255, 137, 0), rgb(255, 169, 0), rgb(250, 199, 0), rgb(197, 225, 0), rgb(116, 246, 0), rgb(0, 255, 86), rgb(0, 255, 171), rgb(0, 255, 239), rgb(0, 255, 255) 100%); } -@media (color-gamut: rec2020) { +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - - background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); - - background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); + --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); } } -@supports (color: color(display-p3 0 0 0%)) { +@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { .gradients-interpolation-method { + --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); +} } @media (color-gamut: rec2020) { + +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); } } } -@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { +@media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); +} } } @@ -536,11 +548,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .test-css-color-5-interop { color-8: color(display-p3 0.4939 0.10676 0); color-9: color(display-p3 0.47553 0.14324 0); } } +} .test-property-with-var { --opacity: 1; @@ -584,10 +599,13 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .schemed-colors { color: light-dark(color(display-p3 0.4939 0.10676 0), magenta); } } +} .schemed-prop { --csstools-light-dark-toggle--0: var(--csstools-color-scheme--light) deepskyblue; @@ -644,11 +662,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .random { border-color: color(display-p3 0.08293 0.41734 0); } } +} .contrast-color { color: rgb(255, 255, 255); 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 f620d88197..8474312b14 100644 --- a/plugin-packs/postcss-preset-env/test/basic.ff66.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.ff66.expect.css @@ -345,6 +345,8 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .oklch { color-7: color(display-p3 0.19244 0.58461 0.51559); @@ -354,6 +356,7 @@ color-11: color(display-p3 0.19244 0.58461 0.51559); } } +} .alpha { color-1: rgba(188, 101, 59, 0.3); @@ -480,11 +483,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .color-mix { color-4: color(display-p3 0.44 0 0.70096 / 0.65); color-5: color(display-p3 0.54692 0 0.47541 / 0.65); } } +} .gradients-interpolation-method { --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(188, 179, 255), rgb(164, 192, 255), rgb(137, 206, 255), rgb(111, 218, 255), rgb(93, 229, 255), rgb(94, 237, 237) 100%); @@ -492,29 +498,35 @@ background-image: radial-gradient(farthest-corner circle at 50% 115%, rgb(255, 71, 0) 0%, rgb(255, 103, 0), rgb(255, 137, 0), rgb(255, 169, 0), rgb(250, 199, 0), rgb(197, 225, 0), rgb(116, 246, 0), rgb(0, 255, 86), rgb(0, 255, 171), rgb(0, 255, 239), rgb(0, 255, 255) 100%); } -@media (color-gamut: rec2020) { +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - - background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); - - background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); + --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); } } -@supports (color: color(display-p3 0 0 0%)) { +@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { .gradients-interpolation-method { + --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); +} } @media (color-gamut: rec2020) { + +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); } } } -@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { +@media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); +} } } @@ -531,11 +543,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .test-css-color-5-interop { color-8: color(display-p3 0.4939 0.10676 0); color-9: color(display-p3 0.47553 0.14324 0); } } +} .test-property-with-var { --opacity: 1; @@ -579,10 +594,13 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .schemed-colors { color: light-dark(color(display-p3 0.4939 0.10676 0), magenta); } } +} .schemed-prop { --csstools-light-dark-toggle--0: var(--csstools-color-scheme--light) deepskyblue; @@ -639,11 +657,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .random { border-color: color(display-p3 0.08293 0.41734 0); } } +} .contrast-color { color: rgb(255, 255, 255); diff --git a/plugin-packs/postcss-preset-env/test/basic.hebrew.all-browsers-have-support.expect.css b/plugin-packs/postcss-preset-env/test/basic.hebrew.all-browsers-have-support.expect.css index 9e31c7171f..8524bea689 100644 --- a/plugin-packs/postcss-preset-env/test/basic.hebrew.all-browsers-have-support.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.hebrew.all-browsers-have-support.expect.css @@ -297,10 +297,13 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .color-function { prop-1: color(display-p3 0.00000 0.51872 0.36985); } } +} .oklab { color-1: rgb(73, 71, 69); @@ -340,6 +343,8 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .oklch { color-7: color(display-p3 0.19244 0.58461 0.51559); @@ -349,6 +354,7 @@ color-11: color(display-p3 0.19244 0.58461 0.51559); } } +} .alpha { color-1: rgba(188, 101, 59, 0.3); @@ -476,11 +482,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, color(display-p3 1 0.61806 0.51282) 0%, color(display-p3 0.51747 0.96259 1) 100%); } } +} .test-css-color-5-interop { color-1: rgb(196, 129, 72); @@ -495,11 +504,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .test-css-color-5-interop { color-8: color(display-p3 0.4939 0.10676 0); color-9: color(display-p3 0.47553 0.14324 0); } } +} .test-property-with-var { --opacity: 1; @@ -515,10 +527,13 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .out-of-gamut { --color: color(display-p3 0 1 0); } } +} .issue-1244--a { background-image: -ms-linear-gradient(180deg, red 0%, blue 100%); @@ -549,10 +564,13 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .schemed-colors { color: light-dark(color(display-p3 0.4939 0.10676 0), magenta); } } +} .schemed-prop { --csstools-light-dark-toggle--0: var(--csstools-color-scheme--light) deepskyblue; @@ -602,11 +620,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .random { border-color: color(display-p3 0.08293 0.41734 0); } } +} .contrast-color { color: rgb(255, 255, 255); diff --git a/plugin-packs/postcss-preset-env/test/basic.hebrew.expect.css b/plugin-packs/postcss-preset-env/test/basic.hebrew.expect.css index 1f27ef885b..0817a14cac 100644 --- a/plugin-packs/postcss-preset-env/test/basic.hebrew.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.hebrew.expect.css @@ -447,6 +447,8 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .oklch { color-7: color(display-p3 0.19244 0.58461 0.51559); @@ -456,6 +458,7 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe color-11: color(display-p3 0.19244 0.58461 0.51559); } } +} .alpha { color-1: rgba(188, 101, 59, 0.3); @@ -588,11 +591,14 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .color-mix { color-4: color(display-p3 0.44 0 0.70096 / 0.65); color-5: color(display-p3 0.54692 0 0.47541 / 0.65); } } +} .gradients-interpolation-method { --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(188, 179, 255), rgb(164, 192, 255), rgb(137, 206, 255), rgb(111, 218, 255), rgb(93, 229, 255), rgb(94, 237, 237) 100%); @@ -600,29 +606,35 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe background-image: radial-gradient(farthest-corner circle at 50% 115%, rgb(255, 71, 0) 0%, rgb(255, 103, 0), rgb(255, 137, 0), rgb(255, 169, 0), rgb(250, 199, 0), rgb(197, 225, 0), rgb(116, 246, 0), rgb(0, 255, 86), rgb(0, 255, 171), rgb(0, 255, 239), rgb(0, 255, 255) 100%); } -@media (color-gamut: rec2020) { +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - - background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); - - background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); + --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); } } -@supports (color: color(display-p3 0 0 0%)) { +@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { .gradients-interpolation-method { + --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); +} } @media (color-gamut: rec2020) { + +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); } } } -@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { +@media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); +} } } @@ -639,11 +651,14 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .test-css-color-5-interop { color-8: color(display-p3 0.4939 0.10676 0); color-9: color(display-p3 0.47553 0.14324 0); } } +} .test-property-with-var { --opacity: 1; @@ -689,10 +704,13 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .schemed-colors { color: light-dark(color(display-p3 0.4939 0.10676 0), magenta); } } +} .schemed-prop { --csstools-light-dark-toggle--0: var(--csstools-color-scheme--light) deepskyblue; @@ -749,11 +767,14 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .random { border-color: color(display-p3 0.08293 0.41734 0); } } +} .contrast-color { color: rgb(255, 255, 255); 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 8da02108e7..ab164d75b5 100644 --- a/plugin-packs/postcss-preset-env/test/basic.ie10.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.ie10.expect.css @@ -467,6 +467,8 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .oklch { color-7: color(display-p3 0.19244 0.58461 0.51559); @@ -476,6 +478,7 @@ color-11: color(display-p3 0.19244 0.58461 0.51559); } } +} .alpha { color-1: rgba(188, 101, 59, 0.3); @@ -610,11 +613,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .color-mix { color-4: color(display-p3 0.44 0 0.70096 / 0.65); color-5: color(display-p3 0.54692 0 0.47541 / 0.65); } } +} .gradients-interpolation-method { --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(188, 179, 255), rgb(164, 192, 255), rgb(137, 206, 255), rgb(111, 218, 255), rgb(93, 229, 255), rgb(94, 237, 237) 100%); @@ -622,29 +628,35 @@ background-image: radial-gradient(farthest-corner circle at 50% 115%, rgb(255, 71, 0) 0%, rgb(255, 103, 0), rgb(255, 137, 0), rgb(255, 169, 0), rgb(250, 199, 0), rgb(197, 225, 0), rgb(116, 246, 0), rgb(0, 255, 86), rgb(0, 255, 171), rgb(0, 255, 239), rgb(0, 255, 255) 100%); } -@media (color-gamut: rec2020) { +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - - background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); - - background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); + --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); } } -@supports (color: color(display-p3 0 0 0%)) { +@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { .gradients-interpolation-method { + --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); +} } @media (color-gamut: rec2020) { + +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); } } } -@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { +@media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); +} } } @@ -661,11 +673,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .test-css-color-5-interop { color-8: color(display-p3 0.4939 0.10676 0); color-9: color(display-p3 0.47553 0.14324 0); } } +} .test-property-with-var { --opacity: 1; @@ -711,10 +726,13 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .schemed-colors { color: light-dark(color(display-p3 0.4939 0.10676 0), magenta); } } +} .schemed-prop { --csstools-light-dark-toggle--0: var(--csstools-color-scheme--light) deepskyblue; @@ -773,11 +791,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .random { border-color: color(display-p3 0.08293 0.41734 0); } } +} .contrast-color { color: rgb(255, 255, 255); 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 61712b0776..c68debbe14 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 @@ -440,6 +440,8 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .oklch { color-7: color(display-p3 0.19244 0.58461 0.51559); @@ -449,6 +451,7 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe color-11: color(display-p3 0.19244 0.58461 0.51559); } } +} .alpha { color-1: rgba(188, 101, 59, 0.3); @@ -583,11 +586,14 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .color-mix { color-4: color(display-p3 0.44 0 0.70096 / 0.65); color-5: color(display-p3 0.54692 0 0.47541 / 0.65); } } +} .gradients-interpolation-method { --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(188, 179, 255), rgb(164, 192, 255), rgb(137, 206, 255), rgb(111, 218, 255), rgb(93, 229, 255), rgb(94, 237, 237) 100%); @@ -595,29 +601,35 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe background-image: radial-gradient(farthest-corner circle at 50% 115%, rgb(255, 71, 0) 0%, rgb(255, 103, 0), rgb(255, 137, 0), rgb(255, 169, 0), rgb(250, 199, 0), rgb(197, 225, 0), rgb(116, 246, 0), rgb(0, 255, 86), rgb(0, 255, 171), rgb(0, 255, 239), rgb(0, 255, 255) 100%); } -@media (color-gamut: rec2020) { +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - - background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); - - background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); + --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); } } -@supports (color: color(display-p3 0 0 0%)) { +@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { .gradients-interpolation-method { + --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); +} } @media (color-gamut: rec2020) { + +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); } } } -@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { +@media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); +} } } @@ -634,11 +646,14 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .test-css-color-5-interop { color-8: color(display-p3 0.4939 0.10676 0); color-9: color(display-p3 0.47553 0.14324 0); } } +} .test-property-with-var { --opacity: 1; @@ -684,10 +699,13 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .schemed-colors { color: light-dark(color(display-p3 0.4939 0.10676 0), magenta); } } +} .schemed-prop { --csstools-light-dark-toggle--0: var(--csstools-color-scheme--light) deepskyblue; @@ -743,11 +761,14 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .random { border-color: color(display-p3 0.08293 0.41734 0); } } +} .contrast-color { color: rgb(255, 255, 255); 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 f8b56b3972..622711217a 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 @@ -432,6 +432,8 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .oklch { color-7: color(display-p3 0.19244 0.58461 0.51559); @@ -441,6 +443,7 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe color-11: color(display-p3 0.19244 0.58461 0.51559); } } +} .alpha { color-1: rgba(188, 101, 59, 0.3); @@ -571,11 +574,14 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .color-mix { color-4: color(display-p3 0.44 0 0.70096 / 0.65); color-5: color(display-p3 0.54692 0 0.47541 / 0.65); } } +} .gradients-interpolation-method { --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(188, 179, 255), rgb(164, 192, 255), rgb(137, 206, 255), rgb(111, 218, 255), rgb(93, 229, 255), rgb(94, 237, 237) 100%); @@ -583,29 +589,35 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe background-image: radial-gradient(farthest-corner circle at 50% 115%, rgb(255, 71, 0) 0%, rgb(255, 103, 0), rgb(255, 137, 0), rgb(255, 169, 0), rgb(250, 199, 0), rgb(197, 225, 0), rgb(116, 246, 0), rgb(0, 255, 86), rgb(0, 255, 171), rgb(0, 255, 239), rgb(0, 255, 255) 100%); } -@media (color-gamut: rec2020) { +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - - background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); - - background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); + --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); } } -@supports (color: color(display-p3 0 0 0%)) { +@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { .gradients-interpolation-method { + --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); +} } @media (color-gamut: rec2020) { + +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); } } } -@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { +@media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); +} } } @@ -622,11 +634,14 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .test-css-color-5-interop { color-8: color(display-p3 0.4939 0.10676 0); color-9: color(display-p3 0.47553 0.14324 0); } } +} .test-property-with-var { --opacity: 1; @@ -672,10 +687,13 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .schemed-colors { color: light-dark(color(display-p3 0.4939 0.10676 0), magenta); } } +} .schemed-prop { --csstools-light-dark-toggle--0: var(--csstools-color-scheme--light) deepskyblue; @@ -732,11 +750,14 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .random { border-color: color(display-p3 0.08293 0.41734 0); } } +} .contrast-color { color: rgb(255, 255, 255); diff --git a/plugin-packs/postcss-preset-env/test/basic.preserve.false.expect.css b/plugin-packs/postcss-preset-env/test/basic.preserve.false.expect.css index 788d8f3d70..7c02ac065f 100644 --- a/plugin-packs/postcss-preset-env/test/basic.preserve.false.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.preserve.false.expect.css @@ -545,6 +545,8 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .oklch { color-7: color(display-p3 0.19244 0.58461 0.51559); @@ -554,6 +556,7 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe color-11: color(display-p3 0.19244 0.58461 0.51559); } } +} .alpha { color-1: rgba(188, 101, 59, 0.3); @@ -703,11 +706,14 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .color-mix { color-4: color(display-p3 0.44 0 0.70096 / 0.65); color-5: color(display-p3 0.54692 0 0.47541 / 0.65); } } +} .gradients-interpolation-method { --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(188, 179, 255), rgb(164, 192, 255), rgb(137, 206, 255), rgb(111, 218, 255), rgb(93, 229, 255), rgb(94, 237, 237) 100%); @@ -720,7 +726,10 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: rec2020) { + +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { + --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); background-image: -webkit-radial-gradient(50% 115%, farthest-corner circle, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); @@ -729,16 +738,6 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); } } - -@supports (color: color(display-p3 0 0 0%)) { -.gradients-interpolation-method { -} - -@media (color-gamut: rec2020) { -.gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); -} -} } .test-css-color-5-interop { @@ -754,11 +753,14 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .test-css-color-5-interop { color-8: color(display-p3 0.4939 0.10676 0); color-9: color(display-p3 0.47553 0.14324 0); } } +} .test-property-with-var { --opacity: 1; @@ -812,10 +814,13 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .schemed-colors { color: light-dark(color(display-p3 0.4939 0.10676 0), magenta); } } +} .schemed-prop { --csstools-light-dark-toggle--0: var(--csstools-color-scheme--light) deepskyblue; @@ -869,11 +874,14 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .random { border-color: color(display-p3 0.08293 0.41734 0); } } +} .contrast-color { color: rgb(255, 255, 255); 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 acacfd0e5b..fa3158fdd3 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 @@ -661,10 +661,13 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .color-function { prop-1: color(display-p3 0.00000 0.51872 0.36985); } } +} .oklab { color-1: rgb(73, 71, 69); @@ -727,21 +730,96 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .oklch { color-7: color(display-p3 0.19244 0.58461 0.51559); +} +} +} + +@media (color-gamut: p3) { + +@supports (color: oklab(0% 0 0%)) { +.oklch { color-7: oklch(60% 0.1250 180); +} +} +} + +@media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { +.oklch { color-8: color(display-p3 0.19244 0.58461 0.51559); +} +} +} + +@media (color-gamut: p3) { + +@supports (color: oklab(0% 0 0%)) { +.oklch { color-8: oklch(60% 0.1250 180deg); +} +} +} + +@media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { +.oklch { color-9: color(display-p3 0.19244 0.58461 0.51559); +} +} +} + +@media (color-gamut: p3) { + +@supports (color: oklab(0% 0 0%)) { +.oklch { color-9: oklch(60% 0.1250 0.5turn); +} +} +} + +@media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { +.oklch { color-10: color(display-p3 0.19244 0.58461 0.51559); +} +} +} + +@media (color-gamut: p3) { + +@supports (color: oklab(0% 0 0%)) { +.oklch { color-10: oklch(60% 0.1250 200grad); +} +} +} + +@media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { +.oklch { color-11: color(display-p3 0.19244 0.58461 0.51559); +} +} +} + +@media (color-gamut: p3) { + +@supports (color: oklab(0% 0 0%)) { +.oklch { color-11: oklch(60% 0.1250 3.14159rad); } } +} .alpha { color-1: rgba(188, 101, 59, 0.3); @@ -997,7 +1075,21 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe background-image: radial-gradient(farthest-corner circle at 50% 115%, rgb(255, 71, 0) 0%, rgb(255, 103, 0), rgb(255, 137, 0), rgb(255, 169, 0), rgb(250, 199, 0), rgb(197, 225, 0), rgb(116, 246, 0), rgb(0, 255, 86), rgb(0, 255, 171), rgb(0, 255, 239), rgb(0, 255, 255) 100%); } +@supports (color: color(display-p3 0 0 0%)) { +.gradients-interpolation-method { + --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); +} +} + +@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { +.gradients-interpolation-method { + --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); +} +} + @media (color-gamut: rec2020) { + +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { background-image: -webkit-radial-gradient(50% 115%, farthest-corner circle, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); @@ -1005,29 +1097,21 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe background-image: -moz-radial-gradient(50% 115%, farthest-corner circle, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); - - background-image: -webkit-radial-gradient(50% 115% in oklch, farthest-corner circle, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); - - background-image: -moz-radial-gradient(50% 115% in oklch, farthest-corner circle, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); - - background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); } } - -@supports (color: color(display-p3 0 0 0%)) { -.gradients-interpolation-method { } @media (color-gamut: rec2020) { -.gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); -} -} -} -@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { +@supports (color: oklab(0% 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); + + background-image: -webkit-radial-gradient(50% 115% in oklch, farthest-corner circle, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); + + background-image: -moz-radial-gradient(50% 115% in oklch, farthest-corner circle, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); +} } } @@ -1051,28 +1135,40 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .test-css-color-5-interop { color-8: color(display-p3 0.4939 0.10676 0); } } +} @media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { .test-css-color-5-interop { color-8: oklab(from oklab(40% 0.566 0.39) l a b); } } +} @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .test-css-color-5-interop { color-9: color(display-p3 0.47553 0.14324 0); } } +} @media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { .test-css-color-5-interop { color-9: oklch(from oklch(40% 0.566 39deg) l c h); } } +} .test-property-with-var { --opacity: 1; @@ -1098,11 +1194,9 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe --color: rgb(0, 247, 79); } -@supports (color: color(display-p3 0 0 0%)) { -.out-of-gamut { -} - @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .out-of-gamut { --color: color(display-p3 0 1 0); } @@ -1149,16 +1243,22 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .schemed-colors { color: light-dark(color(display-p3 0.4939 0.10676 0), magenta); } } +} @media (color-gamut: rec2020) { + +@supports (color: lab(0% 0 0%)) and (color: oklab(0% 0 0%)) { .schemed-colors { color: light-dark(lch(from oklab(40% 0.566 0.39) l c h), magenta); } } +} .schemed-prop { --csstools-light-dark-toggle--0: var(--csstools-color-scheme--light) deepskyblue; 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 7c9fb77f0a..e460ae5269 100644 --- a/plugin-packs/postcss-preset-env/test/basic.safari15.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.safari15.expect.css @@ -285,10 +285,13 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .color-function { prop-1: color(display-p3 0.00000 0.51872 0.36985); } } +} .oklab { color-1: rgb(73, 71, 69); @@ -328,6 +331,8 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .oklch { color-7: color(display-p3 0.19244 0.58461 0.51559); @@ -337,6 +342,7 @@ color-11: color(display-p3 0.19244 0.58461 0.51559); } } +} .alpha { color-1: rgba(188, 101, 59, 0.3); @@ -465,11 +471,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .color-mix { color-4: color(display-p3 0.44 0 0.70096 / 0.65); color-5: color(display-p3 0.54692 0 0.47541 / 0.65); } } +} .gradients-interpolation-method { --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(188, 179, 255), rgb(164, 192, 255), rgb(137, 206, 255), rgb(111, 218, 255), rgb(93, 229, 255), rgb(94, 237, 237) 100%); @@ -477,29 +486,35 @@ background-image: radial-gradient(farthest-corner circle at 50% 115%, rgb(255, 71, 0) 0%, rgb(255, 103, 0), rgb(255, 137, 0), rgb(255, 169, 0), rgb(250, 199, 0), rgb(197, 225, 0), rgb(116, 246, 0), rgb(0, 255, 86), rgb(0, 255, 171), rgb(0, 255, 239), rgb(0, 255, 255) 100%); } -@media (color-gamut: rec2020) { +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - - background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); - - background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); + --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); } } -@supports (color: color(display-p3 0 0 0%)) { +@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { .gradients-interpolation-method { + --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); +} } @media (color-gamut: rec2020) { + +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); } } } -@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { +@media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); +} } } @@ -516,11 +531,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .test-css-color-5-interop { color-8: color(display-p3 0.4939 0.10676 0); color-9: color(display-p3 0.47553 0.14324 0); } } +} .test-property-with-var { --opacity: 1; @@ -536,10 +554,13 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .out-of-gamut { --color: color(display-p3 0 1 0); } } +} .issue-1244--a { background-image: -ms-linear-gradient(180deg, red 0%, blue 100%); @@ -570,10 +591,13 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .schemed-colors { color: light-dark(color(display-p3 0.4939 0.10676 0), magenta); } } +} .schemed-prop { --csstools-light-dark-toggle--0: var(--csstools-color-scheme--light) deepskyblue; @@ -630,11 +654,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .random { border-color: color(display-p3 0.08293 0.41734 0); } } +} .contrast-color { color: rgb(255, 255, 255); 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 519c73cd90..b029b2d0c9 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 @@ -348,6 +348,8 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .oklch { color-7: color(display-p3 0.19244 0.58461 0.51559); @@ -357,6 +359,7 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe color-11: color(display-p3 0.19244 0.58461 0.51559); } } +} .alpha { color-1: rgba(188, 101, 59, 0.3); @@ -481,11 +484,14 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .color-mix { color-4: color(display-p3 0.44 0 0.70096 / 0.65); color-5: color(display-p3 0.54692 0 0.47541 / 0.65); } } +} .gradients-interpolation-method { --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(188, 179, 255), rgb(164, 192, 255), rgb(137, 206, 255), rgb(111, 218, 255), rgb(93, 229, 255), rgb(94, 237, 237) 100%); @@ -493,29 +499,35 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe background-image: radial-gradient(farthest-corner circle at 50% 115%, rgb(255, 71, 0) 0%, rgb(255, 103, 0), rgb(255, 137, 0), rgb(255, 169, 0), rgb(250, 199, 0), rgb(197, 225, 0), rgb(116, 246, 0), rgb(0, 255, 86), rgb(0, 255, 171), rgb(0, 255, 239), rgb(0, 255, 255) 100%); } -@media (color-gamut: rec2020) { +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - - background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); - - background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); + --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); } } -@supports (color: color(display-p3 0 0 0%)) { +@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { .gradients-interpolation-method { + --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); +} } @media (color-gamut: rec2020) { + +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); } } } -@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { +@media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); +} } } @@ -532,11 +544,14 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .test-css-color-5-interop { color-8: color(display-p3 0.4939 0.10676 0); color-9: color(display-p3 0.47553 0.14324 0); } } +} .test-property-with-var { --opacity: 1; @@ -580,10 +595,13 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .schemed-colors { color: light-dark(color(display-p3 0.4939 0.10676 0), magenta); } } +} .schemed-prop { --csstools-light-dark-toggle--0: var(--csstools-color-scheme--light) deepskyblue; @@ -640,11 +658,14 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .random { border-color: color(display-p3 0.08293 0.41734 0); } } +} .contrast-color { color: rgb(255, 255, 255); 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 5587606a85..9f9151aa87 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 @@ -343,6 +343,8 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .oklch { color-7: color(display-p3 0.19244 0.58461 0.51559); @@ -352,6 +354,7 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe color-11: color(display-p3 0.19244 0.58461 0.51559); } } +} .alpha { color-1: rgba(188, 101, 59, 0.3); @@ -476,11 +479,14 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .color-mix { color-4: color(display-p3 0.44 0 0.70096 / 0.65); color-5: color(display-p3 0.54692 0 0.47541 / 0.65); } } +} .gradients-interpolation-method { --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(188, 179, 255), rgb(164, 192, 255), rgb(137, 206, 255), rgb(111, 218, 255), rgb(93, 229, 255), rgb(94, 237, 237) 100%); @@ -488,29 +494,35 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe background-image: radial-gradient(farthest-corner circle at 50% 115%, rgb(255, 71, 0) 0%, rgb(255, 103, 0), rgb(255, 137, 0), rgb(255, 169, 0), rgb(250, 199, 0), rgb(197, 225, 0), rgb(116, 246, 0), rgb(0, 255, 86), rgb(0, 255, 171), rgb(0, 255, 239), rgb(0, 255, 255) 100%); } -@media (color-gamut: rec2020) { +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - - background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); - - background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); + --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); } } -@supports (color: color(display-p3 0 0 0%)) { +@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { .gradients-interpolation-method { + --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); +} } @media (color-gamut: rec2020) { + +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); } } } -@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { +@media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); +} } } @@ -527,11 +539,14 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .test-css-color-5-interop { color-8: color(display-p3 0.4939 0.10676 0); color-9: color(display-p3 0.47553 0.14324 0); } } +} .test-property-with-var { --opacity: 1; @@ -575,10 +590,13 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .schemed-colors { color: light-dark(color(display-p3 0.4939 0.10676 0), magenta); } } +} .schemed-prop { --csstools-light-dark-toggle--0: var(--csstools-color-scheme--light) deepskyblue; @@ -635,11 +653,14 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .random { border-color: color(display-p3 0.08293 0.41734 0); } } +} .contrast-color { color: rgb(255, 255, 255); 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 db5be4d9ee..8b2374be25 100644 --- a/plugin-packs/postcss-preset-env/test/basic.stage0.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.stage0.expect.css @@ -447,6 +447,8 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .oklch { color-7: color(display-p3 0.19244 0.58461 0.51559); @@ -456,6 +458,7 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe color-11: color(display-p3 0.19244 0.58461 0.51559); } } +} .alpha { color-1: rgba(188, 101, 59, 0.3); @@ -588,11 +591,14 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .color-mix { color-4: color(display-p3 0.44 0 0.70096 / 0.65); color-5: color(display-p3 0.54692 0 0.47541 / 0.65); } } +} .gradients-interpolation-method { --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(188, 179, 255), rgb(164, 192, 255), rgb(137, 206, 255), rgb(111, 218, 255), rgb(93, 229, 255), rgb(94, 237, 237) 100%); @@ -600,29 +606,35 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe background-image: radial-gradient(farthest-corner circle at 50% 115%, rgb(255, 71, 0) 0%, rgb(255, 103, 0), rgb(255, 137, 0), rgb(255, 169, 0), rgb(250, 199, 0), rgb(197, 225, 0), rgb(116, 246, 0), rgb(0, 255, 86), rgb(0, 255, 171), rgb(0, 255, 239), rgb(0, 255, 255) 100%); } -@media (color-gamut: rec2020) { +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - - background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); - - background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); + --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); } } -@supports (color: color(display-p3 0 0 0%)) { +@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { .gradients-interpolation-method { + --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); +} } @media (color-gamut: rec2020) { + +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); } } } -@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { +@media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); +} } } @@ -639,11 +651,14 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .test-css-color-5-interop { color-8: color(display-p3 0.4939 0.10676 0); color-9: color(display-p3 0.47553 0.14324 0); } } +} .test-property-with-var { --opacity: 1; @@ -689,10 +704,13 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .schemed-colors { color: light-dark(color(display-p3 0.4939 0.10676 0), magenta); } } +} .schemed-prop { --csstools-light-dark-toggle--0: var(--csstools-color-scheme--light) deepskyblue; @@ -749,11 +767,14 @@ h1.test-custom-selectors:not(.does-not-exist), h2.test-custom-selectors:not(.doe } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .random { border-color: color(display-p3 0.08293 0.41734 0); } } +} .contrast-color { color: rgb(255, 255, 255); diff --git a/plugin-packs/postcss-preset-env/test/basic.supports-query.expect.css b/plugin-packs/postcss-preset-env/test/basic.supports-query.expect.css index 7480939cb6..749f1ca4c3 100644 --- a/plugin-packs/postcss-preset-env/test/basic.supports-query.expect.css +++ b/plugin-packs/postcss-preset-env/test/basic.supports-query.expect.css @@ -341,6 +341,8 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .oklch { color-7: color(display-p3 0.19244 0.58461 0.51559); @@ -350,6 +352,7 @@ color-11: color(display-p3 0.19244 0.58461 0.51559); } } +} .alpha { color-1: rgba(188, 101, 59, 0.3); @@ -478,11 +481,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .color-mix { color-4: color(display-p3 0.44 0 0.70096 / 0.65); color-5: color(display-p3 0.54692 0 0.47541 / 0.65); } } +} .gradients-interpolation-method { --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), rgb(188, 179, 255), rgb(164, 192, 255), rgb(137, 206, 255), rgb(111, 218, 255), rgb(93, 229, 255), rgb(94, 237, 237) 100%); @@ -490,29 +496,35 @@ background-image: radial-gradient(farthest-corner circle at 50% 115%, rgb(255, 71, 0) 0%, rgb(255, 103, 0), rgb(255, 137, 0), rgb(255, 169, 0), rgb(250, 199, 0), rgb(197, 225, 0), rgb(116, 246, 0), rgb(0, 255, 86), rgb(0, 255, 171), rgb(0, 255, 239), rgb(0, 255, 255) 100%); } -@media (color-gamut: rec2020) { +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - - background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); - - background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); + --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); } } -@supports (color: color(display-p3 0 0 0%)) { +@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { .gradients-interpolation-method { + --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); +} } @media (color-gamut: rec2020) { + +@supports (color: color(display-p3 0 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(rgb(245, 137, 137) 0%, rgb(245, 140, 170), rgb(238, 146, 202), rgb(227, 155, 230), rgb(210, 166, 253), color(display-p3 0.73255 0.7035 1.03328), color(display-p3 0.66377 0.75145 1.06652), color(display-p3 0.59643 0.80011 1.0696), color(display-p3 0.54198 0.8462 1.04382), color(display-p3 0.51578 0.88643 0.99318), rgb(94, 237, 237) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115%, color(display-p3 1.2198 0.38716 0.16814) 0%, color(display-p3 1.20289 0.47522 -0.30036), color(display-p3 1.15167 0.57912 -0.39461), color(display-p3 1.06645 0.68611 -0.42959), color(display-p3 0.94738 0.78766 -0.42632), color(display-p3 0.79233 0.87807 -0.37074), color(display-p3 0.59026 0.95319 -0.14671), color(display-p3 0.27082 1.00972 0.43521), color(display-p3 -0.3983 1.04501 0.69996), color(display-p3 -0.53921 1.05733 0.93686), color(display-p3 -0.57773 1.04644 1.15396) 100%); } } } -@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) and (color: hsl(0 0% 0% / 0)) { +@media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { .gradients-interpolation-method { - --background-image: linear-gradient(in oklch decreasing hue, hsl(0deg 85% 75%) 0%, hsl(180deg 80% 65%) 100%); + + background-image: radial-gradient(farthest-corner circle at 50% 115% in oklch, oklch(80% .3 34) 0%, oklch(90% .3 200) 100%); +} } } @@ -529,11 +541,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .test-css-color-5-interop { color-8: color(display-p3 0.4939 0.10676 0); color-9: color(display-p3 0.47553 0.14324 0); } } +} .test-property-with-var { --opacity: 1; @@ -577,10 +592,13 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .schemed-colors { color: light-dark(color(display-p3 0.4939 0.10676 0), magenta); } } +} .schemed-prop { --csstools-light-dark-toggle--0: var(--csstools-color-scheme--light) deepskyblue; @@ -630,11 +648,14 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .random { border-color: color(display-p3 0.08293 0.41734 0); } } +} .contrast-color { color: rgb(255, 255, 255); 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 6dac6703df..f89b007512 100644 --- a/plugin-packs/postcss-preset-env/test/layers-basic.expect.css +++ b/plugin-packs/postcss-preset-env/test/layers-basic.expect.css @@ -585,6 +585,8 @@ h1.test-custom-selectors:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):n } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .oklch:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { color-7: color(display-p3 0.19244 0.58461 0.51559); @@ -594,6 +596,7 @@ h1.test-custom-selectors:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):n color-11: color(display-p3 0.19244 0.58461 0.51559); } } +} .ic-unit:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { --value-2ic: 'something'; 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 c33c1e856b..b17328e997 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 @@ -658,10 +658,13 @@ h1.test-custom-selectors:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):n } @media (color-gamut: p3){ + +@supports (color: color(display-p3 0 0 0%)){ .color-function:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { prop-1: color(display-p3 0.00000 0.51872 0.36985); } } +} .oklab:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { color-1: rgb(73, 71, 69); @@ -724,21 +727,96 @@ h1.test-custom-selectors:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):n } @media (color-gamut: p3){ + +@supports (color: color(display-p3 0 0 0%)){ .oklch:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { color-7: color(display-p3 0.19244 0.58461 0.51559); +} +} +} + +@media (color-gamut: p3){ + +@supports (color: oklab(0% 0 0%)){ +.oklch:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { color-7: oklch(60% 0.1250 180); +} +} +} + +@media (color-gamut: p3){ + +@supports (color: color(display-p3 0 0 0%)){ +.oklch:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { color-8: color(display-p3 0.19244 0.58461 0.51559); +} +} +} + +@media (color-gamut: p3){ + +@supports (color: oklab(0% 0 0%)){ +.oklch:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { color-8: oklch(60% 0.1250 180deg); +} +} +} + +@media (color-gamut: p3){ + +@supports (color: color(display-p3 0 0 0%)){ +.oklch:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { color-9: color(display-p3 0.19244 0.58461 0.51559); +} +} +} + +@media (color-gamut: p3){ + +@supports (color: oklab(0% 0 0%)){ +.oklch:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { color-9: oklch(60% 0.1250 0.5turn); +} +} +} + +@media (color-gamut: p3){ + +@supports (color: color(display-p3 0 0 0%)){ +.oklch:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { color-10: color(display-p3 0.19244 0.58461 0.51559); +} +} +} + +@media (color-gamut: p3){ + +@supports (color: oklab(0% 0 0%)){ +.oklch:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { color-10: oklch(60% 0.1250 200grad); +} +} +} + +@media (color-gamut: p3){ + +@supports (color: color(display-p3 0 0 0%)){ +.oklch:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { color-11: color(display-p3 0.19244 0.58461 0.51559); +} +} +} + +@media (color-gamut: p3){ + +@supports (color: oklab(0% 0 0%)){ +.oklch:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { color-11: oklch(60% 0.1250 3.14159rad); } } +} .ic-unit:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#) { --value-2ic: 'something'; diff --git a/plugin-packs/postcss-preset-env/test/postcss-functions.expect.css b/plugin-packs/postcss-preset-env/test/postcss-functions.expect.css index e3540f976f..3f9f86225c 100644 --- a/plugin-packs/postcss-preset-env/test/postcss-functions.expect.css +++ b/plugin-packs/postcss-preset-env/test/postcss-functions.expect.css @@ -168,19 +168,20 @@ result: rgb(230, 0, 122); @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { result: color(display-p3 0.86333 0 0.47139); } } +} @function --gamut-mapping-var() { --local: rgb(230, 0, 122); result: var(--local); -@supports (color: color(display-p3 0 0 0%)) { -} - @media (color-gamut: p3) { + @supports (color: color(display-p3 0 0 0%)) { --local: color(display-p3 0.86333 0 0.47139); } diff --git a/plugin-packs/postcss-preset-env/test/postcss-functions.preserve-false.expect.css b/plugin-packs/postcss-preset-env/test/postcss-functions.preserve-false.expect.css index bd759edb37..3325ccf295 100644 --- a/plugin-packs/postcss-preset-env/test/postcss-functions.preserve-false.expect.css +++ b/plugin-packs/postcss-preset-env/test/postcss-functions.preserve-false.expect.css @@ -151,19 +151,20 @@ result: rgb(230, 0, 122); @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { result: color(display-p3 0.86333 0 0.47139); } } +} @function --gamut-mapping-var() { --local: rgb(230, 0, 122); result: var(--local); -@supports (color: color(display-p3 0 0 0%)) { -} - @media (color-gamut: p3) { + @supports (color: color(display-p3 0 0 0%)) { --local: color(display-p3 0.86333 0 0.47139); } diff --git a/plugin-packs/postcss-preset-env/test/postcss-functions.preserve-true.expect.css b/plugin-packs/postcss-preset-env/test/postcss-functions.preserve-true.expect.css index 045e3ed8c4..00f47e06c7 100644 --- a/plugin-packs/postcss-preset-env/test/postcss-functions.preserve-true.expect.css +++ b/plugin-packs/postcss-preset-env/test/postcss-functions.preserve-true.expect.css @@ -219,32 +219,34 @@ result: rgb(230, 0, 122); @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { result: color(display-p3 0.86333 0 0.47139); } +} @media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { result: oklch(60% 0.4 0); } } +} @function --gamut-mapping-var() { --local: rgb(230, 0, 122); result: var(--local); -@supports (color: color(display-p3 0 0 0%)) { -} - @media (color-gamut: p3) { + @supports (color: color(display-p3 0 0 0%)) { --local: color(display-p3 0.86333 0 0.47139); } } -@supports (color: oklab(0% 0 0%)) { -} - @media (color-gamut: rec2020) { + @supports (color: oklab(0% 0 0%)) { --local: oklch(60% 0.4 0); } diff --git a/plugins/postcss-gamut-mapping/CHANGELOG.md b/plugins/postcss-gamut-mapping/CHANGELOG.md index 64c529450a..22a1d7d01d 100644 --- a/plugins/postcss-gamut-mapping/CHANGELOG.md +++ b/plugins/postcss-gamut-mapping/CHANGELOG.md @@ -3,6 +3,7 @@ ### Unreleased (patch) - Correctly nest conditional rules inside `@function` instead of cloning the `@function` rule. +- Emit an `@supports (color: …)` condition for the color functions that are used, nested inside the generated `@media (color-gamut: …)` rule. ### 3.0.14 diff --git a/plugins/postcss-gamut-mapping/README.md b/plugins/postcss-gamut-mapping/README.md index 26b6b2fe97..e3e6a61c14 100644 --- a/plugins/postcss-gamut-mapping/README.md +++ b/plugins/postcss-gamut-mapping/README.md @@ -32,16 +32,22 @@ p { } @media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { p { color: oklch(20% 0.234 0.39 / 0.5); } } +} @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { p { border-color: color(display-p3 0 1 0); } } +} ``` ## Usage diff --git a/plugins/postcss-gamut-mapping/dist/index.mjs b/plugins/postcss-gamut-mapping/dist/index.mjs index ce39ca1857..216550cc18 100644 --- a/plugins/postcss-gamut-mapping/dist/index.mjs +++ b/plugins/postcss-gamut-mapping/dist/index.mjs @@ -1 +1 @@ -import{tokenize as e}from"@csstools/css-tokenizer";import{replaceComponentValues as t,parseCommaSeparatedListOfComponentValues as o,isFunctionNode as a,stringify as s}from"@csstools/css-parser-algorithms";import{color as n,SyntaxFlag as r,colorDataFitsRGB_Gamut as l,colorDataFitsDisplayP3_Gamut as i,serializeRGB as c}from"@csstools/css-color-parser";const p=/\bcolor-gamut\b/i;function hasConditionalAncestor(e){let t=e.parent;for(;t;)if("atrule"===t.type){if("media"===t.name.toLowerCase()&&p.test(t.params))return!0;t=t.parent}else t=t.parent;return!1}function sameProperty(e){const t=e.prop.toLowerCase(),o=[],a=e.parent?.nodes??[];for(let e=0;e({postcssPlugin:"postcss-gamut-mapping",prepare(){const p=new WeakMap,f=new WeakSet;return{postcssPlugin:"postcss-gamut-mapping",OnceExit(g,{postcss:v}){g.walkDecls(g=>{if(f.has(g))return;if(!u.test(g.value))return;if(!g.parent||hasConditionalAncestor(g))return;if(inKeyframes(g)||"atrule"===g.parent.type&&d.test(g.parent.name))return;const y=sameProperty(g).map((p,u)=>{f.add(p);let d=!1;const h=p.value,g=t(o(e({css:h})),e=>{if(!a(e)||!m.test(e.getName()))return;const t=n(e);return!t||t.syntaxFlags.has(r.HasNoneKeywords)||l(t)?void 0:(d||i(t)||(d=!0),c(t,!0))}),v=s(g);return{isRec2020:d,matchesOriginal:v===h,modifiedValue:v,hasFallback:u>0,item:p}}),k=[];y.reverse();for(const e of y){if(e.matchesOriginal)break;k.push(e)}k.reverse(),k.forEach(({isRec2020:e,modifiedValue:t,hasFallback:o,item:a})=>{const s=a.parent;if(!s)return;const n=p.get(s)||{conditionalRules:[],propNames:new Set,lastConditionParams:void 0,lastConditionalRule:void 0};p.set(s,n);const r=`(color-gamut: ${e?"rec2020":"p3"})`;if(n.lastConditionParams!==r&&(n.lastConditionalRule=void 0),!o){const e=a.cloneBefore({value:t});f.add(e)}if(n.lastConditionalRule){const e=a.clone();return n.lastConditionalRule.append(e),f.add(e),void a.remove()}const l=v.atRule({name:"media",params:r,source:s.source,raws:{before:"\n\n",after:"\n"}});let i;if("atrule"===s.type&&h.test(s.name))i=l;else{const e=s.clone();e.removeAll(),e.raws.before="\n",l.append(e),i=e}const c=a.clone();i.append(c),a.remove(),f.add(c),n.lastConditionParams=l.params,n.lastConditionalRule=i,n.conditionalRules.push(l)})}),g.walk(e=>{const t=p.get(e);t&&0!==t.conditionalRules.length&&("atrule"===e.type&&h.test(e.name)?e.append(t.conditionalRules):t.conditionalRules.reverse().forEach(t=>{e.after(t)}))})}}}});creator.postcss=!0;export{creator as default,creator as"module.exports"}; +import{walk as e,isFunctionNode as o,isTokenNode as t,parseCommaSeparatedListOfComponentValues as r,replaceComponentValues as n,stringify as s}from"@csstools/css-parser-algorithms";import{isTokenWhiteSpaceOrComment as a,isTokenIdent as l,tokenize as i}from"@csstools/css-tokenizer";import{color as c,SyntaxFlag as p,colorDataFitsRGB_Gamut as u,colorDataFitsDisplayP3_Gamut as d,serializeRGB as f}from"@csstools/css-color-parser";const m=/\bcolor-gamut\b/i;function hasConditionalAncestor(e){let o=e.parent;for(;o;)if("atrule"===o.type){if("media"===o.name.toLowerCase()&&m.test(o.params))return!0;o=o.parent}else o=o.parent;return!1}const h=new Map([["lab","(color: lab(0% 0 0%))"],["lch","(color: lab(0% 0 0%))"],["oklab","(color: oklab(0% 0 0%))"],["oklch","(color: oklab(0% 0 0%))"]]);function colorCondition(e){switch(e){case"display-p3":case"srgb":return"(color: color(display-p3 0 0 0%))";case"display-p3-linear":return"(color: color(display-p3-linear 0 0 0))";default:return"(color: color(xyz 0 0 0%))"}}function firstColorSpace(e){for(let o=0;o{if(!o(e))return;const t=e.getName().toLowerCase();if("color"===t)return void r.add(colorCondition(firstColorSpace(e)));const n=h.get(t);n&&r.add(n)}),Array.from(r).sort()}const C=/(?:^|[\s(])color\s*:/i;function hasSupportsConditionAncestor(e){let o=e.parent;for(;o;){if("atrule"===o.type&&"supports"===o.name.toLowerCase()&&C.test(o.params))return!0;o=o.parent}return!1}function sameProperty(e){const o=e.prop.toLowerCase(),t=[],r=e.parent?.nodes??[];for(let e=0;e({postcssPlugin:"postcss-gamut-mapping",prepare(){const e=new WeakMap,t=new WeakSet;return{postcssPlugin:"postcss-gamut-mapping",OnceExit(a,{postcss:l}){a.walkDecls(a=>{if(t.has(a))return;if(!v.test(a.value))return;if(!a.parent||hasConditionalAncestor(a))return;if(inKeyframes(a)||"atrule"===a.parent.type&&b.test(a.parent.name))return;const m=sameProperty(a).map((e,a)=>{t.add(e);let l=!1;const m=e.value,h=r(i({css:m})),C=supportsConditions(h.flat()),v=n(h,e=>{if(!o(e)||!y.test(e.getName()))return;const t=c(e);return!t||t.syntaxFlags.has(p.HasNoneKeywords)||u(t)?void 0:(l||d(t)||(l=!0),f(t,!0))}),b=s(v);return{conditions:C,isRec2020:l,matchesOriginal:b===m,modifiedValue:b,hasFallback:a>0,item:e}}),h=[];m.reverse();for(const e of m){if(e.matchesOriginal)break;h.push(e)}h.reverse(),h.forEach(({conditions:o,isRec2020:r,modifiedValue:n,hasFallback:s,item:a})=>{const i=a.parent;if(!i)return;const c=e.get(i)||{conditionalRules:[],propNames:new Set,lastConditionParams:void 0,lastConditionalRule:void 0};e.set(i,c);const p=`(color-gamut: ${r?"rec2020":"p3"})`,u=hasSupportsConditionAncestor(a)?"":o.join(" and "),d=`${p} && ${u}`;if(c.lastConditionParams!==d&&(c.lastConditionalRule=void 0),!s){const e=a.cloneBefore({value:n});t.add(e)}if(c.lastConditionalRule){const e=a.clone();return c.lastConditionalRule.append(e),t.add(e),void a.remove()}const f=l.atRule({name:"media",params:p,source:i.source,raws:{before:"\n\n",after:"\n"}});let m;if(u){const e=l.atRule({name:"supports",params:u,source:i.source,raws:{before:"\n\n",after:"\n"}});if(f.append(e),"atrule"===i.type&&w.test(i.name))m=e;else{const o=i.clone();o.removeAll(),o.raws.before="\n",e.append(o),m=o}}else if("atrule"===i.type&&w.test(i.name))m=f;else{const e=i.clone();e.removeAll(),e.raws.before="\n",f.append(e),m=e}const h=a.clone();m.append(h),a.remove(),t.add(h),c.lastConditionParams=d,c.lastConditionalRule=m,c.conditionalRules.push(f)})}),a.walk(o=>{const t=e.get(o);t&&0!==t.conditionalRules.length&&("atrule"===o.type&&w.test(o.name)?o.append(t.conditionalRules):t.conditionalRules.reverse().forEach(e=>{o.after(e)}))})}}}});creator.postcss=!0;export{creator as default,creator as"module.exports"}; diff --git a/plugins/postcss-gamut-mapping/src/index.ts b/plugins/postcss-gamut-mapping/src/index.ts index 7b0a1e2fdd..f83512daae 100644 --- a/plugins/postcss-gamut-mapping/src/index.ts +++ b/plugins/postcss-gamut-mapping/src/index.ts @@ -1,5 +1,6 @@ import type { AtRule, ChildNode, Container, Declaration, Document, Node, Plugin, PluginCreator } from 'postcss'; import { hasConditionalAncestor } from './has-conditional-ancestor'; +import { hasSupportsConditionAncestor, supportsConditions } from './supports-condition'; import { tokenize } from '@csstools/css-tokenizer'; import { isFunctionNode, parseCommaSeparatedListOfComponentValues, replaceComponentValues, stringify } from '@csstools/css-parser-algorithms'; import { SyntaxFlag, color, colorDataFitsDisplayP3_Gamut, colorDataFitsRGB_Gamut, serializeRGB } from '@csstools/css-color-parser'; @@ -22,6 +23,7 @@ type State = { }; type Modification = { + conditions: Array, isRec2020: boolean, matchesOriginal: boolean, modifiedValue: string, @@ -76,8 +78,10 @@ const creator: PluginCreator = () => { let isRec2020 = false; const originalValue = item.value; + const originalComponentValues = parseCommaSeparatedListOfComponentValues(tokenize({ css: originalValue })); + const conditions = supportsConditions(originalComponentValues.flat()); const modified = replaceComponentValues( - parseCommaSeparatedListOfComponentValues(tokenize({ css: originalValue })), + originalComponentValues, (componentValue) => { if (!isFunctionNode(componentValue) || !HAS_WIDE_GAMUT_COLOR_NAME_REGEX.test(componentValue.getName())) { return; @@ -107,6 +111,7 @@ const creator: PluginCreator = () => { const modifiedValue = stringify(modified); return { + conditions: conditions, isRec2020: isRec2020, matchesOriginal: modifiedValue === originalValue, modifiedValue: modifiedValue, @@ -131,7 +136,7 @@ const creator: PluginCreator = () => { modified.reverse(); } - modified.forEach(({ isRec2020, modifiedValue, hasFallback, item }) => { + modified.forEach(({ conditions, isRec2020, modifiedValue, hasFallback, item }) => { const parent = item.parent; if (!parent) { return; @@ -148,7 +153,13 @@ const creator: PluginCreator = () => { const condition = `(color-gamut: ${isRec2020 ? 'rec2020' : 'p3'})`; - if (state.lastConditionParams !== condition) { + const supportsParams = hasSupportsConditionAncestor(item) + ? '' + : conditions.join(' and '); + + const conditionParams = `${condition} && ${supportsParams}`; + + if (state.lastConditionParams !== conditionParams) { state.lastConditionalRule = undefined; } @@ -182,7 +193,33 @@ const creator: PluginCreator = () => { let conditionalRuleContainer: Container; - if (parent.type === 'atrule' && IS_FUNCTION_REGEX.test(parent.name)) { + if (supportsParams) { + const supportsRule = postcss.atRule({ + name: 'supports', + params: supportsParams, + source: parent.source, + raws: { + before: '\n\n', + after: '\n', + }, + }); + + atRule.append(supportsRule); + + if (parent.type === 'atrule' && IS_FUNCTION_REGEX.test(parent.name)) { + // `@function` accepts conditional group rules in its body, + // so the conditional rule is nested instead of cloning the `@function`. + conditionalRuleContainer = supportsRule; + } else { + const parentClone = parent.clone(); + parentClone.removeAll(); + + parentClone.raws.before = '\n'; + + supportsRule.append(parentClone); + conditionalRuleContainer = parentClone; + } + } else if (parent.type === 'atrule' && IS_FUNCTION_REGEX.test(parent.name)) { // `@function` accepts conditional group rules in its body, // so the conditional rule is nested instead of cloning the `@function`. conditionalRuleContainer = atRule; @@ -203,7 +240,7 @@ const creator: PluginCreator = () => { visited.add(clone); - state.lastConditionParams = atRule.params; + state.lastConditionParams = conditionParams; state.lastConditionalRule = conditionalRuleContainer; state.conditionalRules.push(atRule); diff --git a/plugins/postcss-gamut-mapping/src/supports-condition.ts b/plugins/postcss-gamut-mapping/src/supports-condition.ts new file mode 100644 index 0000000000..8932bbd586 --- /dev/null +++ b/plugins/postcss-gamut-mapping/src/supports-condition.ts @@ -0,0 +1,103 @@ +import type { AtRule, Declaration, Document } from 'postcss'; +import type { ComponentValue, FunctionNode } from '@csstools/css-parser-algorithms'; +import { isFunctionNode, isTokenNode, walk } from '@csstools/css-parser-algorithms'; +import { isTokenIdent, isTokenWhiteSpaceOrComment } from '@csstools/css-tokenizer'; + +/** + * Map of wide gamut color function names to the `@supports (color: …)` condition + * that is required to use the resulting color function. + * + * Values that are only known after inspecting the first argument of `color()` are + * handled separately. + */ +const CONDITION_BY_FUNCTION_NAME = new Map([ + ['lab', '(color: lab(0% 0 0%))'], + ['lch', '(color: lab(0% 0 0%))'], + ['oklab', '(color: oklab(0% 0 0%))'], + ['oklch', '(color: oklab(0% 0 0%))'], +]); + +function colorCondition(colorSpace: string | undefined): string { + switch (colorSpace) { + case 'display-p3': + case 'srgb': + return '(color: color(display-p3 0 0 0%))'; + case 'display-p3-linear': + return '(color: color(display-p3-linear 0 0 0))'; + default: + return '(color: color(xyz 0 0 0%))'; + } +} + +function firstColorSpace(functionNode: FunctionNode): string | undefined { + for (let i = 0; i < functionNode.value.length; i++) { + const child = functionNode.value[i]; + + if (isTokenNode(child) && isTokenWhiteSpaceOrComment(child.value)) { + continue; + } + + if (isTokenNode(child) && isTokenIdent(child.value)) { + return child.value[4].value.toLowerCase(); + } + + return; + } +} + +/** + * Derive the `@supports (color: …)` conditions for the wide gamut color functions + * that are used in a list of component values. + * + * @param {Array} componentValues - The component values to inspect. + * @returns {Array} The required `@supports` conditions. + */ +export function supportsConditions(componentValues: Array): Array { + const conditions = new Set(); + + walk(componentValues, ({ node }) => { + if (!isFunctionNode(node)) { + return; + } + + const name = node.getName().toLowerCase(); + + if (name === 'color') { + conditions.add(colorCondition(firstColorSpace(node))); + return; + } + + const condition = CONDITION_BY_FUNCTION_NAME.get(name); + if (condition) { + conditions.add(condition); + } + }); + + return Array.from(conditions).sort(); +} + +const HAS_COLOR_FEATURE_QUERY_REGEX = /(?:^|[\s(])color\s*:/i; + +/** + * Check if a declaration is already guarded by an `@supports` ancestor. + * + * Any `@supports` query that contains a `color:` feature query is considered + * to cover the color functions used by the declaration. + * + * @param {Declaration} decl - The declaration to check. + * @returns {boolean} `true` if a matching `@supports` ancestor exists. + */ +export function hasSupportsConditionAncestor(decl: Declaration): boolean { + let parent: typeof decl.parent | Document = decl.parent; + while (parent) { + if (parent.type === 'atrule' && (parent as AtRule).name.toLowerCase() === 'supports') { + if (HAS_COLOR_FEATURE_QUERY_REGEX.test((parent as AtRule).params)) { + return true; + } + } + + parent = parent.parent; + } + + return false; +} diff --git a/plugins/postcss-gamut-mapping/test/basic.expect.css b/plugins/postcss-gamut-mapping/test/basic.expect.css index 47bb085f38..88f356ab88 100644 --- a/plugins/postcss-gamut-mapping/test/basic.expect.css +++ b/plugins/postcss-gamut-mapping/test/basic.expect.css @@ -4,10 +4,13 @@ } @media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { :root { --b-color: oklch(40% 0.234 0.39 / var(--opacity-50)); } } +} .oklch { color-1: oklch(40% 0.1268735435 34.568626); @@ -56,10 +59,13 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .default-2 { color: color(srgb 0.99 1.0001 0.99); } } +} .default-3 { /* Out rgb of gamut */ @@ -67,10 +73,13 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .default-3 { color: color(display-p3 0.99 1 0.99); } } +} .default-4 { /* Out p3 of gamut */ @@ -78,10 +87,13 @@ } @media (color-gamut: rec2020) { + +@supports (color: color(display-p3 0 0 0%)) { .default-4 { color: color(srgb 0.99 1.001 0.99); } } +} .default-5 { /* Out p3 of gamut */ @@ -89,10 +101,13 @@ } @media (color-gamut: rec2020) { + +@supports (color: color(display-p3 0 0 0%)) { .default-5 { color: color(display-p3 0.99 1.0001 0.99); } } +} /* With fallbacks */ .with-fallback-1 { @@ -107,10 +122,13 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .with-fallback-2 { color: color(srgb 0.99 1.0001 0.99); } } +} .with-fallback-3 { /* Out rgb of gamut */ @@ -118,10 +136,13 @@ } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { .with-fallback-3 { color: color(display-p3 0.99 1 0.99); } } +} .with-fallback-4 { /* Out p3 of gamut */ @@ -129,10 +150,13 @@ } @media (color-gamut: rec2020) { + +@supports (color: color(display-p3 0 0 0%)) { .with-fallback-4 { color: color(srgb 0.99 1.001 0.99); } } +} .with-fallback-5 { /* Out p3 of gamut */ @@ -140,10 +164,13 @@ } @media (color-gamut: rec2020) { + +@supports (color: color(display-p3 0 0 0%)) { .with-fallback-5 { color: color(display-p3 0.99 1.0001 0.99); } } +} /* With overrides */ .with-override-1 { @@ -194,6 +221,9 @@ } @supports (color: color(display-p3 0 1 0)) { + .guarded-by-supports { + color: rgb(0, 247, 79); + } @media (color-gamut: p3) { .guarded-by-supports { @@ -207,11 +237,22 @@ } @media (color-gamut: rec2020) { + +@supports (color: color(display-p3 0 0 0%)) { +:root { + background: linear-gradient(to right, rgb(180, 6, 95) 0%, color(display-p3 0.66274 0.13281 0.2732), rgb(187, 5, 34), color(display-p3 0.66744 0.1674 -0.0377), color(display-p3 0.65449 0.20282 -0.1531), color(display-p3 0.63125 0.24386 -0.1941), color(display-p3 0.59786 0.28667 -0.2143), color(display-p3 0.55449 0.32865 -0.2232), color(display-p3 0.50119 0.3681 -0.2238), color(display-p3 0.43745 0.40384 -0.2152), color(display-p3 0.36142 0.435 -0.1928) 100%) +} +} +} + +@media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { :root { - background: linear-gradient(to right, rgb(180, 6, 95) 0%, color(display-p3 0.66274 0.13281 0.2732), rgb(187, 5, 34), color(display-p3 0.66744 0.1674 -0.0377), color(display-p3 0.65449 0.20282 -0.1531), color(display-p3 0.63125 0.24386 -0.1941), color(display-p3 0.59786 0.28667 -0.2143), color(display-p3 0.55449 0.32865 -0.2232), color(display-p3 0.50119 0.3681 -0.2238), color(display-p3 0.43745 0.40384 -0.2152), color(display-p3 0.36142 0.435 -0.1928) 100%); background: linear-gradient(to right in oklch, oklch(50% 50% 0deg) 0%, oklch(50% 50% 120deg) 100%) } } +} @property --foo { inherits: false; @@ -228,9 +269,12 @@ result: rgb(230, 0, 122); @media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { result: oklch(60% 0.4 0); } } +} @function --b() { --a: rgb(230, 0, 122); @@ -238,31 +282,43 @@ result: var(--a); @media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { --a: oklch(60% 0.4 0); } } +} :root { --firebrick: rgba(255, 155, 186, 0.5); } @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { :root { --firebrick: color(display-p3 1 0.58119 0.72367 / 0.5); } } +} @media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { :root { --firebrick: oklch(80% 0.4 0.039 / 50%); } } +} :root { --firebrick-2: rgba(255, 155, 186, 0.5); } @supports (color: color(display-p3 0 0 0%)) { + :root { + --firebrick-2: rgba(255, 155, 186, 0.5); + } @media (color-gamut: p3) { :root { @@ -272,6 +328,9 @@ } @supports (color: oklab(0% 0 0%)) { + :root { + --firebrick-2: rgba(255, 155, 186, 0.5); + } @media (color-gamut: rec2020) { :root { diff --git a/plugins/postcss-gamut-mapping/test/examples/example.expect.css b/plugins/postcss-gamut-mapping/test/examples/example.expect.css index df9791def8..00d082f521 100644 --- a/plugins/postcss-gamut-mapping/test/examples/example.expect.css +++ b/plugins/postcss-gamut-mapping/test/examples/example.expect.css @@ -5,13 +5,19 @@ p { } @media (color-gamut: rec2020) { + +@supports (color: oklab(0% 0 0%)) { p { color: oklch(20% 0.234 0.39 / 0.5); } } +} @media (color-gamut: p3) { + +@supports (color: color(display-p3 0 0 0%)) { p { border-color: color(display-p3 0 1 0); } } +} diff --git a/plugins/postcss-light-dark-function/CHANGELOG.md b/plugins/postcss-light-dark-function/CHANGELOG.md index bcf1b52826..9eac0395ea 100644 --- a/plugins/postcss-light-dark-function/CHANGELOG.md +++ b/plugins/postcss-light-dark-function/CHANGELOG.md @@ -1,5 +1,9 @@ # Changes to PostCSS Light Dark Function +### Unreleased (patch) + +- Do not generate a nested inheritance rule inside `@function` bodies, as `@function` does not accept nested style rules. + ### 3.0.6 _October 1, 2026_ diff --git a/plugins/postcss-light-dark-function/dist/index.mjs b/plugins/postcss-light-dark-function/dist/index.mjs index 84c80d1178..75050d0bfd 100644 --- a/plugins/postcss-light-dark-function/dist/index.mjs +++ b/plugins/postcss-light-dark-function/dist/index.mjs @@ -1 +1 @@ -import e from"@csstools/postcss-progressive-custom-properties";import{tokenize as r,isTokenIdent as t,isTokenComma as o,TokenType as s}from"@csstools/css-tokenizer";import{hasFallback as n,hasSupportsAtRuleAncestor as a}from"@csstools/utilities";import{isFunctionNode as i,isWhitespaceNode as c,isCommentNode as u,walk as l,isTokenNode as p,replaceComponentValues as f,parseCommaSeparatedListOfComponentValues as m,FunctionNode as g,TokenNode as v,WhitespaceNode as d,stringify as h}from"@csstools/css-parser-algorithms";const k="--csstools-color-scheme--light",D="initial";function toggleNameGenerator(e){return`--csstools-light-dark-toggle--${e}`}const L=/dark/i,w=/light/i;function colorSchemes(e){const o=r({css:e});let s=!1,n=!1;return o.forEach(e=>{t(e)&&(w.test(e[4].value)?s=!0:L.test(e[4].value)&&(n=!0))}),[s,n]}const y=/^light-dark$/i;function isComma(e){return p(e)&&o(e.value)}function parseLightDark(e){if(!i(e)||!y.test(e.getName()))return!1;const r=e.value.filter(e=>!c(e)&&!u(e));if(3!==r.length)return!1;let t=r[0];const o=r[1];let s=r[2];if(!t||!o||!s)return!1;if(!isComma(o))return!1;if(isComma(t)||isComma(s))return!1;if(i(t)){const e=[t];l(e,({node:e,parent:r},t)=>{recurseLightDark(e,r,t,!0)}),[t]=e}if(i(s)){const e=[s];l(e,({node:e,parent:r},t)=>{recurseLightDark(e,r,t,!1)}),[s]=e}return[t,s]}function recurseLightDark(e,r,t,o){if("number"!=typeof t)return;const s=parseLightDark(e);if(!s)return;let n=s[o?0:1];if(i(n)){const e=[n];l(e,({node:e,parent:r},t)=>{recurseLightDark(e,r,t,o)}),[n]=e}r.value[t]=n}function transformLightDark(e,t){const o=new Map,n=f(m(r({css:e})),e=>{const r=parseLightDark(e);if(!r)return;const[n,a]=r,i=t();return o.set(i,`var(${k}) ${a.toString()}`),new g([s.Function,"var(",-1,-1,{value:"var"}],[s.CloseParen,")",-1,-1,void 0],[new v([s.Ident,i,-1,-1,{value:i}]),new v([s.Comma,",",-1,-1,void 0]),new d([[s.Whitespace," ",-1,-1,void 0]]),n])});return{value:h(n),toggles:o}}function newNestedRuleWithSupportsNot(e,r,t,o){const s=r({selector:"& *",source:e.source});if(!o)return{inner:s,outer:s};const n=t({name:"supports",params:"not (color: light-dark(tan, tan))",source:e.source});return n.append(s),{inner:s,outer:n}}const C=/^color-scheme$/i,P=/\blight-dark\(/i,N=/^property$/i,$=/^keyframes$/i;function inKeyframes(e){let r=e.parent;for(;r;){if("atrule"===r.type&&$.test(r.name))return r;r=r.parent}}const basePlugin=e=>({postcssPlugin:"postcss-light-dark-function",prepare(){let r=0;const currentToggleNameGenerator=()=>toggleNameGenerator(r++),t=new Map;return{postcssPlugin:"postcss-light-dark-function",Declaration(r,{atRule:o,rule:s}){const i=r.parent;if(i&&!(inKeyframes(r)||"atrule"===r.parent?.type&&N.test(r.parent.name))){if(C.test(r.prop)){if(i.some(e=>"decl"===e.type&&e.prop===k))return;const[e,t]=colorSchemes(r.value);if(e&&t){r.cloneBefore({prop:k,value:D});const e=i.clone();e.removeAll(),e.append(r.clone({prop:k,value:" "}));const t=o({name:"media",params:"(prefers-color-scheme: dark)",source:i.source});return t.append(e),void i.after(t)}return t?void r.cloneBefore({prop:k,value:" "}):e?void r.cloneBefore({prop:k,value:D}):void 0}if(P.test(r.value)){if(n(r))return;if(a(r,P))return;const i=transformLightDark(r.value,currentToggleNameGenerator);if(i.value===r.value)return;for(const[e,t]of i.toggles)r.cloneBefore({prop:e,value:t});if(r.cloneBefore({value:i.value}),r.variable&&r.parent){const n=t.get(r.parent)??newNestedRuleWithSupportsNot(r,s,o,e?.preserve);for(const[e,t]of i.toggles)n.inner.append(r.clone({prop:e,value:t}));n.inner.append(r.clone({value:i.value})),t.has(r.parent)||(r.parent.append(n.outer),t.set(r.parent,n))}e?.preserve||r.remove()}}}}}});basePlugin.postcss=!0;const postcssPlugin=r=>{const t=Object.assign({enableProgressiveCustomProperties:!0,preserve:!0},r);return t.enableProgressiveCustomProperties&&t.preserve?{postcssPlugin:"postcss-light-dark-function",plugins:[e(),basePlugin(t)]}:basePlugin(t)};postcssPlugin.postcss=!0;export{postcssPlugin as default,postcssPlugin as"module.exports"}; +import e from"@csstools/postcss-progressive-custom-properties";import{tokenize as t,isTokenIdent as r,isTokenComma as o,TokenType as n}from"@csstools/css-tokenizer";import{hasFallback as s,hasSupportsAtRuleAncestor as a}from"@csstools/utilities";import{isFunctionNode as i,isWhitespaceNode as c,isCommentNode as u,walk as l,isTokenNode as p,replaceComponentValues as f,parseCommaSeparatedListOfComponentValues as m,FunctionNode as g,TokenNode as v,WhitespaceNode as d,stringify as h}from"@csstools/css-parser-algorithms";const k="--csstools-color-scheme--light",D="initial";function toggleNameGenerator(e){return`--csstools-light-dark-toggle--${e}`}const y=/dark/i,L=/light/i;function colorSchemes(e){const o=t({css:e});let n=!1,s=!1;return o.forEach(e=>{r(e)&&(L.test(e[4].value)?n=!0:y.test(e[4].value)&&(s=!0))}),[n,s]}const w=/^light-dark$/i;function isComma(e){return p(e)&&o(e.value)}function parseLightDark(e){if(!i(e)||!w.test(e.getName()))return!1;const t=e.value.filter(e=>!c(e)&&!u(e));if(3!==t.length)return!1;let r=t[0];const o=t[1];let n=t[2];if(!r||!o||!n)return!1;if(!isComma(o))return!1;if(isComma(r)||isComma(n))return!1;if(i(r)){const e=[r];l(e,({node:e,parent:t},r)=>{recurseLightDark(e,t,r,!0)}),[r]=e}if(i(n)){const e=[n];l(e,({node:e,parent:t},r)=>{recurseLightDark(e,t,r,!1)}),[n]=e}return[r,n]}function recurseLightDark(e,t,r,o){if("number"!=typeof r)return;const n=parseLightDark(e);if(!n)return;let s=n[o?0:1];if(i(s)){const e=[s];l(e,({node:e,parent:t},r)=>{recurseLightDark(e,t,r,o)}),[s]=e}t.value[r]=s}function transformLightDark(e,r){const o=new Map,s=f(m(t({css:e})),e=>{const t=parseLightDark(e);if(!t)return;const[s,a]=t,i=r();return o.set(i,`var(${k}) ${a.toString()}`),new g([n.Function,"var(",-1,-1,{value:"var"}],[n.CloseParen,")",-1,-1,void 0],[new v([n.Ident,i,-1,-1,{value:i}]),new v([n.Comma,",",-1,-1,void 0]),new d([[n.Whitespace," ",-1,-1,void 0]]),s])});return{value:h(s),toggles:o}}function newNestedRuleWithSupportsNot(e,t,r,o){const n=t({selector:"& *",source:e.source});if(!o)return{inner:n,outer:n};const s=r({name:"supports",params:"not (color: light-dark(tan, tan))",source:e.source});return s.append(n),{inner:n,outer:s}}const C=/^color-scheme$/i,P=/\blight-dark\(/i,$=/^property$/i,N=/^keyframes$/i,b=/^function$/i;function inKeyframes(e){let t=e.parent;for(;t;){if("atrule"===t.type&&N.test(t.name))return t;t=t.parent}}function inFunction(e){let t=e.parent;for(;t;){if("atrule"===t.type&&b.test(t.name))return t;t=t.parent}}const basePlugin=e=>({postcssPlugin:"postcss-light-dark-function",prepare(){let t=0;const currentToggleNameGenerator=()=>toggleNameGenerator(t++),r=new Map;return{postcssPlugin:"postcss-light-dark-function",Declaration(t,{atRule:o,rule:n}){const i=t.parent;if(i&&!(inKeyframes(t)||"atrule"===t.parent?.type&&$.test(t.parent.name))){if(C.test(t.prop)){if(i.some(e=>"decl"===e.type&&e.prop===k))return;const[e,r]=colorSchemes(t.value);if(e&&r){t.cloneBefore({prop:k,value:D});const e=i.clone();e.removeAll(),e.append(t.clone({prop:k,value:" "}));const r=o({name:"media",params:"(prefers-color-scheme: dark)",source:i.source});return r.append(e),void i.after(r)}return r?void t.cloneBefore({prop:k,value:" "}):e?void t.cloneBefore({prop:k,value:D}):void 0}if(P.test(t.value)){if(s(t))return;if(a(t,P))return;const i=transformLightDark(t.value,currentToggleNameGenerator);if(i.value===t.value)return;for(const[e,r]of i.toggles)t.cloneBefore({prop:e,value:r});if(t.cloneBefore({value:i.value}),t.variable&&t.parent&&!inFunction(t)){const s=r.get(t.parent)??newNestedRuleWithSupportsNot(t,n,o,e?.preserve);for(const[e,r]of i.toggles)s.inner.append(t.clone({prop:e,value:r}));s.inner.append(t.clone({value:i.value})),r.has(t.parent)||(t.parent.append(s.outer),r.set(t.parent,s))}e?.preserve||t.remove()}}}}}});basePlugin.postcss=!0;const postcssPlugin=t=>{const r=Object.assign({enableProgressiveCustomProperties:!0,preserve:!0},t);return r.enableProgressiveCustomProperties&&r.preserve?{postcssPlugin:"postcss-light-dark-function",plugins:[e(),basePlugin(r)]}:basePlugin(r)};postcssPlugin.postcss=!0;export{postcssPlugin as default,postcssPlugin as"module.exports"}; diff --git a/plugins/postcss-light-dark-function/src/index.ts b/plugins/postcss-light-dark-function/src/index.ts index 4735b57f39..646d70143f 100644 --- a/plugins/postcss-light-dark-function/src/index.ts +++ b/plugins/postcss-light-dark-function/src/index.ts @@ -10,6 +10,7 @@ const COLOR_SCHEME_REGEX = /^color-scheme$/i; const LIGHT_DARK_FUNCTION_REGEX = /\blight-dark\(/i; const IS_PROPERTY_REGEX = /^property$/i; const IS_KEYFRAMES_REGEX = /^keyframes$/i; +const IS_FUNCTION_REGEX = /^function$/i; function inKeyframes(decl: Declaration): AtRule | void { let parent: typeof decl.parent | Document = decl.parent; @@ -22,6 +23,17 @@ function inKeyframes(decl: Declaration): AtRule | void { } } +function inFunction(decl: Declaration): AtRule | void { + let parent: typeof decl.parent | Document = decl.parent; + while (parent) { + if (parent.type === 'atrule' && IS_FUNCTION_REGEX.test(parent.name)) { + return parent; + } + + parent = parent.parent; + } +} + const basePlugin: PluginCreator = (opts) => { return { postcssPlugin: 'postcss-light-dark-function', @@ -107,7 +119,7 @@ const basePlugin: PluginCreator = (opts) => { decl.cloneBefore({ value: modified.value }); - if (decl.variable && decl.parent) { + if (decl.variable && decl.parent && !inFunction(decl)) { const variableInheritanceRule = variableInheritanceRules.get(decl.parent) ?? newNestedRuleWithSupportsNot( decl, rule, diff --git a/plugins/postcss-light-dark-function/test/basic.expect.css b/plugins/postcss-light-dark-function/test/basic.expect.css index 93e5fbc5ae..ace0323749 100644 --- a/plugins/postcss-light-dark-function/test/basic.expect.css +++ b/plugins/postcss-light-dark-function/test/basic.expect.css @@ -166,14 +166,6 @@ result: var(--a); - @supports not (color: light-dark(tan, tan)) { - - & * { - --csstools-light-dark-toggle--15: var(--csstools-color-scheme--light) blue; - --a: var(--csstools-light-dark-toggle--15, green); - } - } - @supports (color: light-dark(red, red)) { --a: light-dark(green, blue); } diff --git a/plugins/postcss-light-dark-function/test/basic.preserve-false.expect.css b/plugins/postcss-light-dark-function/test/basic.preserve-false.expect.css index 8b4be3a718..357c72850e 100644 --- a/plugins/postcss-light-dark-function/test/basic.preserve-false.expect.css +++ b/plugins/postcss-light-dark-function/test/basic.preserve-false.expect.css @@ -143,9 +143,4 @@ --a: var(--csstools-light-dark-toggle--15, green); result: var(--a); - - & * { - --csstools-light-dark-toggle--15: var(--csstools-color-scheme--light) blue; - --a: var(--csstools-light-dark-toggle--15, green); - } }