From ba68e10529c312b358aeec5be6f6c648e83a5e47 Mon Sep 17 00:00:00 2001
From: romainmenke
Date: Thu, 3 Mar 2022 23:15:19 +0100
Subject: [PATCH 1/8] postcss-double-position-gradients : typescript
---
.../CHANGELOG.md | 4 ++
.../package.json | 1 +
...or.js => has-supports-at-rule-ancestor.ts} | 5 ++-
.../src/{index.js => index.ts} | 38 ++++++++++---------
.../src/{is-gradient.js => is-gradient.ts} | 4 +-
.../test/basic.css | 8 ++++
.../test/basic.expect.css | 10 +++++
.../test/basic.preserve.expect.css | 8 ++++
.../tsconfig.json | 9 +++++
9 files changed, 65 insertions(+), 22 deletions(-)
rename plugins/postcss-double-position-gradients/src/{has-supports-at-rule-ancestor.js => has-supports-at-rule-ancestor.ts} (54%)
rename plugins/postcss-double-position-gradients/src/{index.js => index.ts} (80%)
rename plugins/postcss-double-position-gradients/src/{is-gradient.js => is-gradient.ts} (79%)
create mode 100644 plugins/postcss-double-position-gradients/tsconfig.json
diff --git a/plugins/postcss-double-position-gradients/CHANGELOG.md b/plugins/postcss-double-position-gradients/CHANGELOG.md
index 531f53560..66a631bef 100644
--- a/plugins/postcss-double-position-gradients/CHANGELOG.md
+++ b/plugins/postcss-double-position-gradients/CHANGELOG.md
@@ -1,5 +1,9 @@
# Changes to PostCSS Double Position Gradients
+### Unreleased (patch)
+
+- Add typescript support
+
### 3.1.0 (February 15, 2022)
- Ignore values in relevant `@supports` rules.
diff --git a/plugins/postcss-double-position-gradients/package.json b/plugins/postcss-double-position-gradients/package.json
index c3cc48fce..2573e865c 100644
--- a/plugins/postcss-double-position-gradients/package.json
+++ b/plugins/postcss-double-position-gradients/package.json
@@ -9,6 +9,7 @@
},
"main": "dist/index.cjs",
"module": "dist/index.mjs",
+ "types": "dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.mjs",
diff --git a/plugins/postcss-double-position-gradients/src/has-supports-at-rule-ancestor.js b/plugins/postcss-double-position-gradients/src/has-supports-at-rule-ancestor.ts
similarity index 54%
rename from plugins/postcss-double-position-gradients/src/has-supports-at-rule-ancestor.js
rename to plugins/postcss-double-position-gradients/src/has-supports-at-rule-ancestor.ts
index edfbb9e8d..36b3bad8d 100644
--- a/plugins/postcss-double-position-gradients/src/has-supports-at-rule-ancestor.js
+++ b/plugins/postcss-double-position-gradients/src/has-supports-at-rule-ancestor.ts
@@ -1,6 +1,7 @@
import { includesGradientsFunction } from './is-gradient';
+import type { AtRule, Node } from 'postcss';
-export function hasSupportsAtRuleAncestor(node) {
+export function hasSupportsAtRuleAncestor(node: Node): boolean {
let parent = node.parent;
while (parent) {
if (parent.type !== 'atrule') {
@@ -8,7 +9,7 @@ export function hasSupportsAtRuleAncestor(node) {
continue;
}
- if (parent.name === 'supports' && includesGradientsFunction(parent.params)) {
+ if ((parent as AtRule).name === 'supports' && includesGradientsFunction((parent as AtRule).params)) {
return true;
}
diff --git a/plugins/postcss-double-position-gradients/src/index.js b/plugins/postcss-double-position-gradients/src/index.ts
similarity index 80%
rename from plugins/postcss-double-position-gradients/src/index.js
rename to plugins/postcss-double-position-gradients/src/index.ts
index d754bacd2..5048e4da3 100644
--- a/plugins/postcss-double-position-gradients/src/index.js
+++ b/plugins/postcss-double-position-gradients/src/index.ts
@@ -1,17 +1,11 @@
import postcssProgressiveCustomProperties from '@csstools/postcss-progressive-custom-properties';
+import type { PluginCreator } from 'postcss';
import valueParser from 'postcss-value-parser';
import { hasSupportsAtRuleAncestor } from './has-supports-at-rule-ancestor';
import { includesGradientsFunction, isGradientsFunctions } from './is-gradient';
const isPunctuationCommaNode = node => node.type === 'div' && node.value === ',';
-function insertBefore(nodes, node, ...values) {
- const index = nodes.findIndex(n => n === node);
- nodes.splice.apply(nodes, [index - 1, 0].concat(
- Array.prototype.slice.call(...values, 0)),
- );
-}
-
function isNumericNode(node) {
try {
return valueParser.unit(node?.value) !== false;
@@ -63,10 +57,10 @@ const basePlugin = (opts) => {
return x.type !== 'comment' && x.type !== 'space';
});
- nodes.forEach((node, index, nodes) => {
- const oneValueBack = Object(nodes[index - 1]);
- const twoValuesBack = Object(nodes[index - 2]);
- const nextNode = Object(nodes[index + 1]);
+ nodes.forEach((node, index, currentNodes) => {
+ const oneValueBack = Object(currentNodes[index - 1]);
+ const twoValuesBack = Object(currentNodes[index - 2]);
+ const nextNode = Object(currentNodes[index + 1]);
const isDoublePositionLength = twoValuesBack.type && isNumericNode(oneValueBack) && isNumericNode(node);
// if the argument concludes a double-position gradient
@@ -80,7 +74,14 @@ const basePlugin = (opts) => {
after: isPunctuationCommaNode(nextNode) ? '' : ' ',
};
- insertBefore(func.nodes, node, [comma, color]);
+ func.nodes.splice(
+ // 1 before the current node
+ func.nodes.indexOf(node) - 1,
+ // remove none
+ 0,
+ // insert these :
+ comma, color,
+ );
}
});
@@ -103,12 +104,13 @@ const basePlugin = (opts) => {
basePlugin.postcss = true;
-/**
- * Transform double-position gradients in CSS.
- * @param {{preserve?: boolean}} opts
- * @returns {import('postcss').Plugin}
- */
-const postcssPlugin = (opts) => {
+type pluginOptions = {
+ preserve?: boolean;
+ enableProgressiveCustomProperties?: boolean;
+};
+
+// Transform double-position gradients in CSS.
+const postcssPlugin: PluginCreator = (opts?: pluginOptions) => {
const options = Object.assign({
enableProgressiveCustomProperties: true,
preserve: true,
diff --git a/plugins/postcss-double-position-gradients/src/is-gradient.js b/plugins/postcss-double-position-gradients/src/is-gradient.ts
similarity index 79%
rename from plugins/postcss-double-position-gradients/src/is-gradient.js
rename to plugins/postcss-double-position-gradients/src/is-gradient.ts
index b42515d1c..6bc438727 100644
--- a/plugins/postcss-double-position-gradients/src/is-gradient.js
+++ b/plugins/postcss-double-position-gradients/src/is-gradient.ts
@@ -1,4 +1,4 @@
-export function includesGradientsFunction(str) {
+export function includesGradientsFunction(str: string): boolean {
return (
str.includes('conic-gradient(') ||
str.includes('linear-gradient(') ||
@@ -9,7 +9,7 @@ export function includesGradientsFunction(str) {
);
}
-export function isGradientsFunctions(str) {
+export function isGradientsFunctions(str: string): boolean {
return (
str ==='conic-gradient' ||
str ==='linear-gradient' ||
diff --git a/plugins/postcss-double-position-gradients/test/basic.css b/plugins/postcss-double-position-gradients/test/basic.css
index 42d9deb61..f775685c1 100644
--- a/plugins/postcss-double-position-gradients/test/basic.css
+++ b/plugins/postcss-double-position-gradients/test/basic.css
@@ -2,6 +2,10 @@
background-image: linear-gradient(90deg, black 25% 50%, blue 50% 75%);
}
+.test-linear-gradient-no-spaces {
+ background-image: linear-gradient(90deg,black 25% 50%,blue 50% 75%);
+}
+
.test-conic-gradient {
background-image: conic-gradient(yellowgreen 40%, gold 0deg 75% , #f06 0deg);
}
@@ -43,3 +47,7 @@
--gradient-prop-5: repeating-linear-gradient(90deg, black 25% 50%, blue 50% 75%);
--gradient-prop-6: repeating-radial-gradient(red 0 8%, yellow 8% 16%, blue 16% 24%);
}
+
+.test-color-space-interop {
+ background: linear-gradient(in lab to right, #44C 0% 10%, #795)
+}
diff --git a/plugins/postcss-double-position-gradients/test/basic.expect.css b/plugins/postcss-double-position-gradients/test/basic.expect.css
index 7fecef813..c8525ccb5 100644
--- a/plugins/postcss-double-position-gradients/test/basic.expect.css
+++ b/plugins/postcss-double-position-gradients/test/basic.expect.css
@@ -3,6 +3,11 @@
background-image: linear-gradient(90deg, black 25% 50%, blue 50% 75%);
}
+.test-linear-gradient-no-spaces {
+ background-image: linear-gradient(90deg,black 25%,black 50%,blue 50%, blue 75%);
+ background-image: linear-gradient(90deg,black 25% 50%,blue 50% 75%);
+}
+
.test-conic-gradient {
background-image: conic-gradient(yellowgreen 40%, gold 0deg ,gold 75% , #f06 0deg);
background-image: conic-gradient(yellowgreen 40%, gold 0deg 75% , #f06 0deg);
@@ -75,3 +80,8 @@
--gradient-prop-6: repeating-radial-gradient(red 0 8%, yellow 8% 16%, blue 16% 24%);
}
}
+
+.test-color-space-interop {
+ background: linear-gradient(in lab to right, #44C 0%,#44C 10%, #795);
+ background: linear-gradient(in lab to right, #44C 0% 10%, #795)
+}
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 13b003719..690e44a17 100644
--- a/plugins/postcss-double-position-gradients/test/basic.preserve.expect.css
+++ b/plugins/postcss-double-position-gradients/test/basic.preserve.expect.css
@@ -2,6 +2,10 @@
background-image: linear-gradient(90deg, black 25%,black 50%, blue 50%, blue 75%);
}
+.test-linear-gradient-no-spaces {
+ background-image: linear-gradient(90deg,black 25%,black 50%,blue 50%, blue 75%);
+}
+
.test-conic-gradient {
background-image: conic-gradient(yellowgreen 40%, gold 0deg ,gold 75% , #f06 0deg);
}
@@ -43,3 +47,7 @@
--gradient-prop-5: repeating-linear-gradient(90deg, black 25%,black 50%, blue 50%, blue 75%);
--gradient-prop-6: repeating-radial-gradient(red 0,red 8%, yellow 8%,yellow 16%, blue 16%, blue 24%);
}
+
+.test-color-space-interop {
+ background: linear-gradient(in lab to right, #44C 0%,#44C 10%, #795)
+}
diff --git a/plugins/postcss-double-position-gradients/tsconfig.json b/plugins/postcss-double-position-gradients/tsconfig.json
new file mode 100644
index 000000000..e0d06239c
--- /dev/null
+++ b/plugins/postcss-double-position-gradients/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "dist",
+ "declarationDir": "."
+ },
+ "include": ["./src/**/*"],
+ "exclude": ["dist"],
+}
From 15f32eead9a05f34c34bdff7edb1e84c6e44ca88 Mon Sep 17 00:00:00 2001
From: romainmenke
Date: Fri, 4 Mar 2022 17:26:01 +0100
Subject: [PATCH 2/8] postcss-gradients-interpolation-method
---
.github/bin/new-plugin.mjs | 2 +-
package-lock.json | 26 ++
.../CHANGELOG.md | 1 +
.../src/index.ts | 34 ++-
.../test/basic.css | 5 +
.../test/basic.expect.css | 6 +
.../test/basic.preserve.expect.css | 5 +
.../.gitignore | 6 +
.../.nvmrc | 1 +
.../.tape.mjs | 25 ++
.../CHANGELOG.md | 5 +
.../INSTALL.md | 176 +++++++++++++
.../LICENSE.md | 108 ++++++++
.../README.md | 145 +++++++++++
.../docs/README.md | 72 ++++++
.../package.json | 75 ++++++
.../src/color-stop-list.ts | 93 +++++++
.../src/has-supports-at-rule-ancestor.ts | 20 ++
.../src/index.ts | 235 ++++++++++++++++++
.../src/is-gradient.ts | 23 ++
.../test/_import.mjs | 6 +
.../test/_require.cjs | 6 +
.../test/basic.css | 21 ++
.../test/basic.expect.css | 60 +++++
.../test/examples/example.css | 7 +
.../test/examples/example.expect.css | 14 ++
.../examples/example.preserve-true.expect.css | 14 ++
...preserve-true.progressive-false.expect.css | 9 +
.../tsconfig.json | 9 +
.../src/custom/double-position-gradients.ts | 64 ++++-
.../test/basic.css | 14 ++
.../test/basic.expect.css | 47 +++-
32 files changed, 1322 insertions(+), 12 deletions(-)
create mode 100644 plugins/postcss-gradients-interpolation-method/.gitignore
create mode 100644 plugins/postcss-gradients-interpolation-method/.nvmrc
create mode 100644 plugins/postcss-gradients-interpolation-method/.tape.mjs
create mode 100644 plugins/postcss-gradients-interpolation-method/CHANGELOG.md
create mode 100644 plugins/postcss-gradients-interpolation-method/INSTALL.md
create mode 100644 plugins/postcss-gradients-interpolation-method/LICENSE.md
create mode 100644 plugins/postcss-gradients-interpolation-method/README.md
create mode 100644 plugins/postcss-gradients-interpolation-method/docs/README.md
create mode 100644 plugins/postcss-gradients-interpolation-method/package.json
create mode 100644 plugins/postcss-gradients-interpolation-method/src/color-stop-list.ts
create mode 100644 plugins/postcss-gradients-interpolation-method/src/has-supports-at-rule-ancestor.ts
create mode 100644 plugins/postcss-gradients-interpolation-method/src/index.ts
create mode 100644 plugins/postcss-gradients-interpolation-method/src/is-gradient.ts
create mode 100644 plugins/postcss-gradients-interpolation-method/test/_import.mjs
create mode 100644 plugins/postcss-gradients-interpolation-method/test/_require.cjs
create mode 100644 plugins/postcss-gradients-interpolation-method/test/basic.css
create mode 100644 plugins/postcss-gradients-interpolation-method/test/basic.expect.css
create mode 100644 plugins/postcss-gradients-interpolation-method/test/examples/example.css
create mode 100644 plugins/postcss-gradients-interpolation-method/test/examples/example.expect.css
create mode 100644 plugins/postcss-gradients-interpolation-method/test/examples/example.preserve-true.expect.css
create mode 100644 plugins/postcss-gradients-interpolation-method/test/examples/example.preserve-true.progressive-false.expect.css
create mode 100644 plugins/postcss-gradients-interpolation-method/tsconfig.json
diff --git a/.github/bin/new-plugin.mjs b/.github/bin/new-plugin.mjs
index 3707f55a6..bd94a32eb 100644
--- a/.github/bin/new-plugin.mjs
+++ b/.github/bin/new-plugin.mjs
@@ -89,7 +89,7 @@ console.log(`- Creating new plugin ${pluginName}`);
packageInfo.repository.directory = `plugins/${pluginSlug}`;
- await fsp.writeFile(path.join(pluginDir, 'package.json'), JSON.stringify(packageInfo, null, 2));
+ await fsp.writeFile(path.join(pluginDir, 'package.json'), JSON.stringify(packageInfo, null, '\t'));
console.log('- Updated "package.json"');
}
diff --git a/package-lock.json b/package-lock.json
index 411d48a04..e18639345 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1770,6 +1770,10 @@
"resolved": "plugins/postcss-font-format-keywords",
"link": true
},
+ "node_modules/@csstools/postcss-gradients-interpolation-method": {
+ "resolved": "plugins/postcss-gradients-interpolation-method",
+ "link": true
+ },
"node_modules/@csstools/postcss-hwb-function": {
"resolved": "plugins/postcss-hwb-function",
"link": true
@@ -6679,6 +6683,21 @@
"postcss": "^8.4"
}
},
+ "plugins/postcss-gradients-interpolation-method": {
+ "name": "@csstools/postcss-gradients-interpolation-method",
+ "version": "1.0.0",
+ "license": "CC0-1.0",
+ "devDependencies": {
+ "@csstools/postcss-progressive-custom-properties": "^1.1.0",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "peerDependencies": {
+ "postcss": "^8.3"
+ }
+ },
"plugins/postcss-hwb-function": {
"name": "@csstools/postcss-hwb-function",
"version": "1.0.0",
@@ -8077,6 +8096,13 @@
"postcss-value-parser": "^4.2.0"
}
},
+ "@csstools/postcss-gradients-interpolation-method": {
+ "version": "file:plugins/postcss-gradients-interpolation-method",
+ "requires": {
+ "@csstools/postcss-progressive-custom-properties": "^1.1.0",
+ "postcss-value-parser": "^4.2.0"
+ }
+ },
"@csstools/postcss-hwb-function": {
"version": "file:plugins/postcss-hwb-function",
"requires": {
diff --git a/plugins/postcss-double-position-gradients/CHANGELOG.md b/plugins/postcss-double-position-gradients/CHANGELOG.md
index 66a631bef..d05b773dc 100644
--- a/plugins/postcss-double-position-gradients/CHANGELOG.md
+++ b/plugins/postcss-double-position-gradients/CHANGELOG.md
@@ -3,6 +3,7 @@
### Unreleased (patch)
- Add typescript support
+- Fix `at` keyword with `at 20px 20px` being interpreted as a double position color stop.
### 3.1.0 (February 15, 2022)
diff --git a/plugins/postcss-double-position-gradients/src/index.ts b/plugins/postcss-double-position-gradients/src/index.ts
index 5048e4da3..afa068a80 100644
--- a/plugins/postcss-double-position-gradients/src/index.ts
+++ b/plugins/postcss-double-position-gradients/src/index.ts
@@ -4,6 +4,24 @@ import valueParser from 'postcss-value-parser';
import { hasSupportsAtRuleAncestor } from './has-supports-at-rule-ancestor';
import { includesGradientsFunction, isGradientsFunctions } from './is-gradient';
+const keywords = [
+ 'at',
+ 'bottom',
+ 'center',
+ 'circle',
+ 'closest-corner',
+ 'closest-side',
+ 'ellipse',
+ 'farthest-corner',
+ 'farthest-side',
+ 'from',
+ 'in',
+ 'left',
+ 'right',
+ 'to',
+ 'top',
+];
+
const isPunctuationCommaNode = node => node.type === 'div' && node.value === ',';
function isNumericNode(node) {
@@ -57,7 +75,21 @@ const basePlugin = (opts) => {
return x.type !== 'comment' && x.type !== 'space';
});
+ let inPrefix = false;
+
nodes.forEach((node, index, currentNodes) => {
+ if (node.type === 'word' && keywords.includes(node.value)) {
+ inPrefix = true;
+ }
+
+ if (node.type === 'div' && node.value === ',') {
+ inPrefix = false;
+ }
+
+ if (inPrefix) {
+ return;
+ }
+
const oneValueBack = Object(currentNodes[index - 1]);
const twoValuesBack = Object(currentNodes[index - 2]);
const nextNode = Object(currentNodes[index + 1]);
@@ -85,7 +117,7 @@ const basePlugin = (opts) => {
}
});
- return false;
+ return;
});
const modifiedValue = valueAST.toString();
diff --git a/plugins/postcss-double-position-gradients/test/basic.css b/plugins/postcss-double-position-gradients/test/basic.css
index f775685c1..1f6b9dd88 100644
--- a/plugins/postcss-double-position-gradients/test/basic.css
+++ b/plugins/postcss-double-position-gradients/test/basic.css
@@ -1,5 +1,6 @@
.test-linear-gradient {
background-image: linear-gradient(90deg, black 25% 50%, blue 50% 75%);
+ background-image: linear-gradient(black 25% 50%, blue 50% 75%);
}
.test-linear-gradient-no-spaces {
@@ -10,6 +11,10 @@
background-image: conic-gradient(yellowgreen 40%, gold 0deg 75% , #f06 0deg);
}
+.test-radial-gradient {
+ background-image: radial-gradient(5em circle at 50px 50%, yellow, blue);
+}
+
.test-invalid-function {
background-image: some-func(yellowgreen 40%, gold 0deg 75% , #f06 0deg);
}
diff --git a/plugins/postcss-double-position-gradients/test/basic.expect.css b/plugins/postcss-double-position-gradients/test/basic.expect.css
index c8525ccb5..0ac977529 100644
--- a/plugins/postcss-double-position-gradients/test/basic.expect.css
+++ b/plugins/postcss-double-position-gradients/test/basic.expect.css
@@ -1,6 +1,8 @@
.test-linear-gradient {
background-image: linear-gradient(90deg, black 25%,black 50%, blue 50%, blue 75%);
background-image: linear-gradient(90deg, black 25% 50%, blue 50% 75%);
+ background-image: linear-gradient(black 25%,black 50%, blue 50%, blue 75%);
+ background-image: linear-gradient(black 25% 50%, blue 50% 75%);
}
.test-linear-gradient-no-spaces {
@@ -13,6 +15,10 @@
background-image: conic-gradient(yellowgreen 40%, gold 0deg 75% , #f06 0deg);
}
+.test-radial-gradient {
+ background-image: radial-gradient(5em circle at 50px 50%, yellow, blue);
+}
+
.test-invalid-function {
background-image: some-func(yellowgreen 40%, gold 0deg 75% , #f06 0deg);
}
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 690e44a17..70ba5cf92 100644
--- a/plugins/postcss-double-position-gradients/test/basic.preserve.expect.css
+++ b/plugins/postcss-double-position-gradients/test/basic.preserve.expect.css
@@ -1,5 +1,6 @@
.test-linear-gradient {
background-image: linear-gradient(90deg, black 25%,black 50%, blue 50%, blue 75%);
+ background-image: linear-gradient(black 25%,black 50%, blue 50%, blue 75%);
}
.test-linear-gradient-no-spaces {
@@ -10,6 +11,10 @@
background-image: conic-gradient(yellowgreen 40%, gold 0deg ,gold 75% , #f06 0deg);
}
+.test-radial-gradient {
+ background-image: radial-gradient(5em circle at 50px 50%, yellow, blue);
+}
+
.test-invalid-function {
background-image: some-func(yellowgreen 40%, gold 0deg 75% , #f06 0deg);
}
diff --git a/plugins/postcss-gradients-interpolation-method/.gitignore b/plugins/postcss-gradients-interpolation-method/.gitignore
new file mode 100644
index 000000000..7172b04f1
--- /dev/null
+++ b/plugins/postcss-gradients-interpolation-method/.gitignore
@@ -0,0 +1,6 @@
+node_modules
+package-lock.json
+yarn.lock
+*.result.css
+*.result.css.map
+dist/*
diff --git a/plugins/postcss-gradients-interpolation-method/.nvmrc b/plugins/postcss-gradients-interpolation-method/.nvmrc
new file mode 100644
index 000000000..f0b10f153
--- /dev/null
+++ b/plugins/postcss-gradients-interpolation-method/.nvmrc
@@ -0,0 +1 @@
+v16.13.1
diff --git a/plugins/postcss-gradients-interpolation-method/.tape.mjs b/plugins/postcss-gradients-interpolation-method/.tape.mjs
new file mode 100644
index 000000000..0a038cc7a
--- /dev/null
+++ b/plugins/postcss-gradients-interpolation-method/.tape.mjs
@@ -0,0 +1,25 @@
+import postcssTape from '../../packages/postcss-tape/dist/index.mjs';
+import plugin from '@csstools/postcss-gradients-interpolation-method';
+
+postcssTape(plugin)({
+ basic: {
+ message: "supports basic usage",
+ warnings: 2,
+ },
+ 'examples/example': {
+ message: 'minimal example',
+ },
+ 'examples/example:preserve-true': {
+ message: 'minimal example',
+ options: {
+ preserve: true
+ }
+ },
+ 'examples/example:preserve-true:progressive-false': {
+ message: 'minimal example',
+ options: {
+ preserve: true,
+ enableProgressiveCustomProperties: false,
+ }
+ }
+});
diff --git a/plugins/postcss-gradients-interpolation-method/CHANGELOG.md b/plugins/postcss-gradients-interpolation-method/CHANGELOG.md
new file mode 100644
index 000000000..fb6afce1f
--- /dev/null
+++ b/plugins/postcss-gradients-interpolation-method/CHANGELOG.md
@@ -0,0 +1,5 @@
+# Changes to PostCSS Gradients Interpolation Method
+
+### 1.0.0 (Unreleased)
+
+- Initial version
diff --git a/plugins/postcss-gradients-interpolation-method/INSTALL.md b/plugins/postcss-gradients-interpolation-method/INSTALL.md
new file mode 100644
index 000000000..a384e7cbd
--- /dev/null
+++ b/plugins/postcss-gradients-interpolation-method/INSTALL.md
@@ -0,0 +1,176 @@
+# Installing PostCSS Gradients Interpolation Method
+
+[PostCSS Gradients Interpolation Method] runs in all Node environments, with special instructions for:
+
+| [Node](#node) | [PostCSS CLI](#postcss-cli) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) |
+| --- | --- | --- | --- | --- | --- |
+
+## Node
+
+Add [PostCSS Gradients Interpolation Method] to your project:
+
+```bash
+npm install postcss @csstools/postcss-gradients-interpolation-method --save-dev
+```
+
+Use it as a [PostCSS] plugin:
+
+```js
+const postcss = require('postcss');
+const postcssGradientsInterpolationMethod = require('@csstools/postcss-gradients-interpolation-method');
+
+postcss([
+ postcssGradientsInterpolationMethod(/* pluginOptions */)
+]).process(YOUR_CSS /*, processOptions */);
+```
+
+## PostCSS CLI
+
+Add [PostCSS CLI] to your project:
+
+```bash
+npm install postcss-cli @csstools/postcss-gradients-interpolation-method --save-dev
+```
+
+Use [PostCSS Gradients Interpolation Method] in your `postcss.config.js` configuration file:
+
+```js
+const postcssGradientsInterpolationMethod = require('@csstools/postcss-gradients-interpolation-method');
+
+module.exports = {
+ plugins: [
+ postcssGradientsInterpolationMethod(/* pluginOptions */)
+ ]
+}
+```
+
+## Webpack
+
+_Webpack version 5_
+
+Add [PostCSS Loader] to your project:
+
+```bash
+npm install postcss-loader @csstools/postcss-gradients-interpolation-method --save-dev
+```
+
+Use [PostCSS Gradients Interpolation Method] in your Webpack configuration:
+
+```js
+module.exports = {
+ module: {
+ rules: [
+ {
+ test: /\.css$/i,
+ use: [
+ "style-loader",
+ {
+ loader: "css-loader",
+ options: { importLoaders: 1 },
+ },
+ {
+ loader: "postcss-loader",
+ options: {
+ postcssOptions: {
+ plugins: [
+ [
+ "@csstools/postcss-gradients-interpolation-method",
+ {
+ // Options
+ },
+ ],
+ ],
+ },
+ },
+ },
+ ],
+ },
+ ],
+ },
+};
+```
+
+## Create React App
+
+Add [React App Rewired] and [React App Rewire PostCSS] to your project:
+
+```bash
+npm install react-app-rewired react-app-rewire-postcss @csstools/postcss-gradients-interpolation-method --save-dev
+```
+
+Use [React App Rewire PostCSS] and [PostCSS Gradients Interpolation Method] in your
+`config-overrides.js` file:
+
+```js
+const reactAppRewirePostcss = require('react-app-rewire-postcss');
+const postcssGradientsInterpolationMethod = require('@csstools/postcss-gradients-interpolation-method');
+
+module.exports = config => reactAppRewirePostcss(config, {
+ plugins: () => [
+ postcssGradientsInterpolationMethod(/* pluginOptions */)
+ ]
+});
+```
+
+## Gulp
+
+Add [Gulp PostCSS] to your project:
+
+```bash
+npm install gulp-postcss @csstools/postcss-gradients-interpolation-method --save-dev
+```
+
+Use [PostCSS Gradients Interpolation Method] in your Gulpfile:
+
+```js
+const postcss = require('gulp-postcss');
+const postcssGradientsInterpolationMethod = require('@csstools/postcss-gradients-interpolation-method');
+
+gulp.task('css', function () {
+ var plugins = [
+ postcssGradientsInterpolationMethod(/* pluginOptions */)
+ ];
+
+ return gulp.src('./src/*.css')
+ .pipe(postcss(plugins))
+ .pipe(gulp.dest('.'));
+});
+```
+
+## Grunt
+
+Add [Grunt PostCSS] to your project:
+
+```bash
+npm install grunt-postcss @csstools/postcss-gradients-interpolation-method --save-dev
+```
+
+Use [PostCSS Gradients Interpolation Method] in your Gruntfile:
+
+```js
+const postcssGradientsInterpolationMethod = require('@csstools/postcss-gradients-interpolation-method');
+
+grunt.loadNpmTasks('grunt-postcss');
+
+grunt.initConfig({
+ postcss: {
+ options: {
+ processors: [
+ postcssGradientsInterpolationMethod(/* pluginOptions */)
+ ]
+ },
+ dist: {
+ src: '*.css'
+ }
+ }
+});
+```
+
+[Gulp PostCSS]: https://github.com/postcss/gulp-postcss
+[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss
+[PostCSS]: https://github.com/postcss/postcss
+[PostCSS CLI]: https://github.com/postcss/postcss-cli
+[PostCSS Loader]: https://github.com/postcss/postcss-loader
+[PostCSS Gradients Interpolation Method]: https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-gradients-interpolation-method
+[React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss
+[React App Rewired]: https://github.com/timarney/react-app-rewired
diff --git a/plugins/postcss-gradients-interpolation-method/LICENSE.md b/plugins/postcss-gradients-interpolation-method/LICENSE.md
new file mode 100644
index 000000000..0bc1fa706
--- /dev/null
+++ b/plugins/postcss-gradients-interpolation-method/LICENSE.md
@@ -0,0 +1,108 @@
+# CC0 1.0 Universal
+
+## Statement of Purpose
+
+The laws of most jurisdictions throughout the world automatically confer
+exclusive Copyright and Related Rights (defined below) upon the creator and
+subsequent owner(s) (each and all, an “owner”) of an original work of
+authorship and/or a database (each, a “Work”).
+
+Certain owners wish to permanently relinquish those rights to a Work for the
+purpose of contributing to a commons of creative, cultural and scientific works
+(“Commons”) that the public can reliably and without fear of later claims of
+infringement build upon, modify, incorporate in other works, reuse and
+redistribute as freely as possible in any form whatsoever and for any purposes,
+including without limitation commercial purposes. These owners may contribute
+to the Commons to promote the ideal of a free culture and the further
+production of creative, cultural and scientific works, or to gain reputation or
+greater distribution for their Work in part through the use and efforts of
+others.
+
+For these and/or other purposes and motivations, and without any expectation of
+additional consideration or compensation, the person associating CC0 with a
+Work (the “Affirmer”), to the extent that he or she is an owner of Copyright
+and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and
+publicly distribute the Work under its terms, with knowledge of his or her
+Copyright and Related Rights in the Work and the meaning and intended legal
+effect of CC0 on those rights.
+
+1. Copyright and Related Rights. A Work made available under CC0 may be
+ protected by copyright and related or neighboring rights (“Copyright and
+ Related Rights”). Copyright and Related Rights include, but are not limited
+ to, the following:
+ 1. the right to reproduce, adapt, distribute, perform, display, communicate,
+ and translate a Work;
+ 2. moral rights retained by the original author(s) and/or performer(s);
+ 3. publicity and privacy rights pertaining to a person’s image or likeness
+ depicted in a Work;
+ 4. rights protecting against unfair competition in regards to a Work,
+ subject to the limitations in paragraph 4(i), below;
+ 5. rights protecting the extraction, dissemination, use and reuse of data in
+ a Work;
+ 6. database rights (such as those arising under Directive 96/9/EC of the
+ European Parliament and of the Council of 11 March 1996 on the legal
+ protection of databases, and under any national implementation thereof,
+ including any amended or successor version of such directive); and
+ 7. other similar, equivalent or corresponding rights throughout the world
+ based on applicable law or treaty, and any national implementations
+ thereof.
+
+2. Waiver. To the greatest extent permitted by, but not in contravention of,
+ applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
+ unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright
+ and Related Rights and associated claims and causes of action, whether now
+ known or unknown (including existing as well as future claims and causes of
+ action), in the Work (i) in all territories worldwide, (ii) for the maximum
+ duration provided by applicable law or treaty (including future time
+ extensions), (iii) in any current or future medium and for any number of
+ copies, and (iv) for any purpose whatsoever, including without limitation
+ commercial, advertising or promotional purposes (the “Waiver”). Affirmer
+ makes the Waiver for the benefit of each member of the public at large and
+ to the detriment of Affirmer’s heirs and successors, fully intending that
+ such Waiver shall not be subject to revocation, rescission, cancellation,
+ termination, or any other legal or equitable action to disrupt the quiet
+ enjoyment of the Work by the public as contemplated by Affirmer’s express
+ Statement of Purpose.
+
+3. Public License Fallback. Should any part of the Waiver for any reason be
+ judged legally invalid or ineffective under applicable law, then the Waiver
+ shall be preserved to the maximum extent permitted taking into account
+ Affirmer’s express Statement of Purpose. In addition, to the extent the
+ Waiver is so judged Affirmer hereby grants to each affected person a
+ royalty-free, non transferable, non sublicensable, non exclusive,
+ irrevocable and unconditional license to exercise Affirmer’s Copyright and
+ Related Rights in the Work (i) in all territories worldwide, (ii) for the
+ maximum duration provided by applicable law or treaty (including future time
+ extensions), (iii) in any current or future medium and for any number of
+ copies, and (iv) for any purpose whatsoever, including without limitation
+ commercial, advertising or promotional purposes (the “License”). The License
+ shall be deemed effective as of the date CC0 was applied by Affirmer to the
+ Work. Should any part of the License for any reason be judged legally
+ invalid or ineffective under applicable law, such partial invalidity or
+ ineffectiveness shall not invalidate the remainder of the License, and in
+ such case Affirmer hereby affirms that he or she will not (i) exercise any
+ of his or her remaining Copyright and Related Rights in the Work or (ii)
+ assert any associated claims and causes of action with respect to the Work,
+ in either case contrary to Affirmer’s express Statement of Purpose.
+
+4. Limitations and Disclaimers.
+ 1. No trademark or patent rights held by Affirmer are waived, abandoned,
+ surrendered, licensed or otherwise affected by this document.
+ 2. Affirmer offers the Work as-is and makes no representations or warranties
+ of any kind concerning the Work, express, implied, statutory or
+ otherwise, including without limitation warranties of title,
+ merchantability, fitness for a particular purpose, non infringement, or
+ the absence of latent or other defects, accuracy, or the present or
+ absence of errors, whether or not discoverable, all to the greatest
+ extent permissible under applicable law.
+ 3. Affirmer disclaims responsibility for clearing rights of other persons
+ that may apply to the Work or any use thereof, including without
+ limitation any person’s Copyright and Related Rights in the Work.
+ Further, Affirmer disclaims responsibility for obtaining any necessary
+ consents, permissions or other rights required for any use of the Work.
+ 4. Affirmer understands and acknowledges that Creative Commons is not a
+ party to this document and has no duty or obligation with respect to this
+ CC0 or use of the Work.
+
+For more information, please see
+http://creativecommons.org/publicdomain/zero/1.0/.
diff --git a/plugins/postcss-gradients-interpolation-method/README.md b/plugins/postcss-gradients-interpolation-method/README.md
new file mode 100644
index 000000000..6b4041a49
--- /dev/null
+++ b/plugins/postcss-gradients-interpolation-method/README.md
@@ -0,0 +1,145 @@
+# PostCSS Gradients Interpolation Method [
][postcss]
+
+[
][npm-url]
+[
][css-url]
+[
][cli-url]
+[
][discord]
+
+[PostCSS Gradients Interpolation Method] lets you use different interpolation methods in CSS gradient functions following [CSS Specification].
+
+```pcss
+.oklch {
+ background: linear-gradient(in oklch 90deg, black 25% , blue 75%);
+}
+
+:root {
+ --background: linear-gradient(in oklch 90deg, black 25%, blue 75%);
+}
+
+/* becomes */
+
+.oklch {
+ background: linear-gradient(90deg ,black 25%,color-mix(in oklch, black 90%, blue 10%) calc(25% + ((75% - 25%) * 0.1)),color-mix(in oklch, black 80%, blue 20%) calc(25% + ((75% - 25%) * 0.2)),color-mix(in oklch, black 70%, blue 30%) calc(25% + ((75% - 25%) * 0.3)),color-mix(in oklch, black 60%, blue 40%) calc(25% + ((75% - 25%) * 0.4)),color-mix(in oklch, black 50%, blue 50%) calc(25% + ((75% - 25%) * 0.5)),color-mix(in oklch, black 40%, blue 60%) calc(25% + ((75% - 25%) * 0.6)),color-mix(in oklch, black 30%, blue 70%) calc(25% + ((75% - 25%) * 0.7)),color-mix(in oklch, black 20%, blue 80%) calc(25% + ((75% - 25%) * 0.8)),color-mix(in oklch, black 10%, blue 90%) calc(25% + ((75% - 25%) * 0.9)),blue 75%);
+ background: linear-gradient(in oklch 90deg, black 25% , blue 75%);
+}
+
+:root {
+ --background: linear-gradient(90deg ,black 25%,color-mix(in oklch, black 90%, blue 10%) calc(25% + ((75% - 25%) * 0.1)),color-mix(in oklch, black 80%, blue 20%) calc(25% + ((75% - 25%) * 0.2)),color-mix(in oklch, black 70%, blue 30%) calc(25% + ((75% - 25%) * 0.3)),color-mix(in oklch, black 60%, blue 40%) calc(25% + ((75% - 25%) * 0.4)),color-mix(in oklch, black 50%, blue 50%) calc(25% + ((75% - 25%) * 0.5)),color-mix(in oklch, black 40%, blue 60%) calc(25% + ((75% - 25%) * 0.6)),color-mix(in oklch, black 30%, blue 70%) calc(25% + ((75% - 25%) * 0.7)),color-mix(in oklch, black 20%, blue 80%) calc(25% + ((75% - 25%) * 0.8)),color-mix(in oklch, black 10%, blue 90%) calc(25% + ((75% - 25%) * 0.9)),blue 75%);
+}
+
+@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) {
+:root {
+ --background: linear-gradient(in oklch 90deg, black 25%, blue 75%);
+}
+}
+```
+
+## Usage
+
+Add [PostCSS Gradients Interpolation Method] to your project:
+
+```bash
+npm install postcss @csstools/postcss-gradients-interpolation-method --save-dev
+```
+
+Use it as a [PostCSS] plugin:
+
+```js
+const postcss = require('postcss');
+const postcssGradientsInterpolationMethod = require('@csstools/postcss-gradients-interpolation-method');
+
+postcss([
+ postcssGradientsInterpolationMethod(/* pluginOptions */)
+]).process(YOUR_CSS /*, processOptions */);
+```
+
+[PostCSS Gradients Interpolation Method] runs in all Node environments, with special
+instructions for:
+
+| [Node](INSTALL.md#node) | [PostCSS CLI](INSTALL.md#postcss-cli) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) |
+| --- | --- | --- | --- | --- | --- |
+
+## Options
+
+### preserve
+
+The `preserve` option determines whether the original notation
+is preserved. By default, it is not preserved.
+
+```js
+postcssGradientsInterpolationMethod({ preserve: true })
+```
+
+```pcss
+.oklch {
+ background: linear-gradient(in oklch 90deg, black 25% , blue 75%);
+}
+
+:root {
+ --background: linear-gradient(in oklch 90deg, black 25%, blue 75%);
+}
+
+/* becomes */
+
+.oklch {
+ background: linear-gradient(90deg ,black 25%,color-mix(in oklch, black 90%, blue 10%) calc(25% + ((75% - 25%) * 0.1)),color-mix(in oklch, black 80%, blue 20%) calc(25% + ((75% - 25%) * 0.2)),color-mix(in oklch, black 70%, blue 30%) calc(25% + ((75% - 25%) * 0.3)),color-mix(in oklch, black 60%, blue 40%) calc(25% + ((75% - 25%) * 0.4)),color-mix(in oklch, black 50%, blue 50%) calc(25% + ((75% - 25%) * 0.5)),color-mix(in oklch, black 40%, blue 60%) calc(25% + ((75% - 25%) * 0.6)),color-mix(in oklch, black 30%, blue 70%) calc(25% + ((75% - 25%) * 0.7)),color-mix(in oklch, black 20%, blue 80%) calc(25% + ((75% - 25%) * 0.8)),color-mix(in oklch, black 10%, blue 90%) calc(25% + ((75% - 25%) * 0.9)),blue 75%);
+ background: linear-gradient(in oklch 90deg, black 25% , blue 75%);
+}
+
+:root {
+ --background: linear-gradient(90deg ,black 25%,color-mix(in oklch, black 90%, blue 10%) calc(25% + ((75% - 25%) * 0.1)),color-mix(in oklch, black 80%, blue 20%) calc(25% + ((75% - 25%) * 0.2)),color-mix(in oklch, black 70%, blue 30%) calc(25% + ((75% - 25%) * 0.3)),color-mix(in oklch, black 60%, blue 40%) calc(25% + ((75% - 25%) * 0.4)),color-mix(in oklch, black 50%, blue 50%) calc(25% + ((75% - 25%) * 0.5)),color-mix(in oklch, black 40%, blue 60%) calc(25% + ((75% - 25%) * 0.6)),color-mix(in oklch, black 30%, blue 70%) calc(25% + ((75% - 25%) * 0.7)),color-mix(in oklch, black 20%, blue 80%) calc(25% + ((75% - 25%) * 0.8)),color-mix(in oklch, black 10%, blue 90%) calc(25% + ((75% - 25%) * 0.9)),blue 75%);
+}
+
+@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) {
+:root {
+ --background: linear-gradient(in oklch 90deg, black 25%, blue 75%);
+}
+}
+```
+
+### enableProgressiveCustomProperties
+
+The `enableProgressiveCustomProperties` option determines whether the original notation
+is wrapped with `@supports` when used in Custom Properties. By default, it is enabled.
+
+⚠️ We only recommend disabling this when you set `preserve` to `false` or if you bring your own fix for Custom Properties. See what the plugin does in its [README](https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-progressive-custom-properties#readme).
+
+```js
+postcssGradientsInterpolationMethod({ enableProgressiveCustomProperties: false })
+```
+
+```pcss
+.oklch {
+ background: linear-gradient(in oklch 90deg, black 25% , blue 75%);
+}
+
+:root {
+ --background: linear-gradient(in oklch 90deg, black 25%, blue 75%);
+}
+
+/* becomes */
+
+.oklch {
+ background: linear-gradient(90deg ,black 25%,color-mix(in oklch, black 90%, blue 10%) calc(25% + ((75% - 25%) * 0.1)),color-mix(in oklch, black 80%, blue 20%) calc(25% + ((75% - 25%) * 0.2)),color-mix(in oklch, black 70%, blue 30%) calc(25% + ((75% - 25%) * 0.3)),color-mix(in oklch, black 60%, blue 40%) calc(25% + ((75% - 25%) * 0.4)),color-mix(in oklch, black 50%, blue 50%) calc(25% + ((75% - 25%) * 0.5)),color-mix(in oklch, black 40%, blue 60%) calc(25% + ((75% - 25%) * 0.6)),color-mix(in oklch, black 30%, blue 70%) calc(25% + ((75% - 25%) * 0.7)),color-mix(in oklch, black 20%, blue 80%) calc(25% + ((75% - 25%) * 0.8)),color-mix(in oklch, black 10%, blue 90%) calc(25% + ((75% - 25%) * 0.9)),blue 75%);
+ background: linear-gradient(in oklch 90deg, black 25% , blue 75%);
+}
+
+:root {
+ --background: linear-gradient(90deg ,black 25%,color-mix(in oklch, black 90%, blue 10%) calc(25% + ((75% - 25%) * 0.1)),color-mix(in oklch, black 80%, blue 20%) calc(25% + ((75% - 25%) * 0.2)),color-mix(in oklch, black 70%, blue 30%) calc(25% + ((75% - 25%) * 0.3)),color-mix(in oklch, black 60%, blue 40%) calc(25% + ((75% - 25%) * 0.4)),color-mix(in oklch, black 50%, blue 50%) calc(25% + ((75% - 25%) * 0.5)),color-mix(in oklch, black 40%, blue 60%) calc(25% + ((75% - 25%) * 0.6)),color-mix(in oklch, black 30%, blue 70%) calc(25% + ((75% - 25%) * 0.7)),color-mix(in oklch, black 20%, blue 80%) calc(25% + ((75% - 25%) * 0.8)),color-mix(in oklch, black 10%, blue 90%) calc(25% + ((75% - 25%) * 0.9)),blue 75%);
+ --background: linear-gradient(in oklch 90deg, black 25%, blue 75%);
+}
+```
+
+_Custom properties do not fallback to the previous declaration_
+
+[cli-url]: https://github.com/csstools/postcss-plugins/actions/workflows/test.yml?query=workflow/test
+[css-url]: https://cssdb.org/#TODO
+[discord]: https://discord.gg/bUadyRwkJS
+[npm-url]: https://www.npmjs.com/package/@csstools/postcss-gradients-interpolation-method
+
+[Gulp PostCSS]: https://github.com/postcss/gulp-postcss
+[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss
+[PostCSS]: https://github.com/postcss/postcss
+[PostCSS Loader]: https://github.com/postcss/postcss-loader
+[PostCSS Gradients Interpolation Method]: https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-gradients-interpolation-method
+[CSS Specification]: https://drafts.csswg.org/css-images-4/#linear-gradients
diff --git a/plugins/postcss-gradients-interpolation-method/docs/README.md b/plugins/postcss-gradients-interpolation-method/docs/README.md
new file mode 100644
index 000000000..5c1cd934d
--- /dev/null
+++ b/plugins/postcss-gradients-interpolation-method/docs/README.md
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+[] lets you use different interpolation methods in CSS gradient functions following [CSS Specification].
+
+```pcss
+
+
+/* becomes */
+
+
+```
+
+
+
+
+
+## Options
+
+### preserve
+
+The `preserve` option determines whether the original notation
+is preserved. By default, it is not preserved.
+
+```js
+({ preserve: true })
+```
+
+```pcss
+
+
+/* becomes */
+
+
+```
+
+### enableProgressiveCustomProperties
+
+The `enableProgressiveCustomProperties` option determines whether the original notation
+is wrapped with `@supports` when used in Custom Properties. By default, it is enabled.
+
+⚠️ We only recommend disabling this when you set `preserve` to `false` or if you bring your own fix for Custom Properties. See what the plugin does in its [README](https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-progressive-custom-properties#readme).
+
+```js
+({ enableProgressiveCustomProperties: false })
+```
+
+```pcss
+
+
+/* becomes */
+
+
+```
+
+_Custom properties do not fallback to the previous declaration_
+
+
+[CSS Specification]:
diff --git a/plugins/postcss-gradients-interpolation-method/package.json b/plugins/postcss-gradients-interpolation-method/package.json
new file mode 100644
index 000000000..083d26d4d
--- /dev/null
+++ b/plugins/postcss-gradients-interpolation-method/package.json
@@ -0,0 +1,75 @@
+{
+ "name": "@csstools/postcss-gradients-interpolation-method",
+ "description": "Use interpolation methods in CSS gradient functions",
+ "version": "1.0.0",
+ "author": "Jonathan Neal ",
+ "license": "CC0-1.0",
+ "engines": {
+ "node": "^12 || ^14 || >=16"
+ },
+ "main": "dist/index.cjs",
+ "module": "dist/index.mjs",
+ "types": "dist/index.d.ts",
+ "exports": {
+ ".": {
+ "import": "./dist/index.mjs",
+ "require": "./dist/index.cjs",
+ "default": "./dist/index.mjs"
+ }
+ },
+ "files": [
+ "CHANGELOG.md",
+ "LICENSE.md",
+ "README.md",
+ "dist"
+ ],
+ "devDependencies": {
+ "@csstools/postcss-progressive-custom-properties": "^1.1.0",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.3"
+ },
+ "scripts": {
+ "build": "rollup -c ../../rollup/default.js",
+ "clean": "node -e \"fs.rmSync('./dist', { recursive: true, force: true });\"",
+ "docs": "node ../../.github/bin/generate-docs/install.mjs && node ../../.github/bin/generate-docs/readme.mjs",
+ "lint": "npm run lint:eslint && npm run lint:package-json",
+ "lint:eslint": "eslint ./src --ext .js --ext .ts --ext .mjs --no-error-on-unmatched-pattern",
+ "lint:package-json": "node ../../.github/bin/format-package-json.mjs",
+ "prepublishOnly": "npm run clean && npm run build && npm run test",
+ "stryker": "stryker run --logLevel error",
+ "test": "node .tape.mjs && npm run test:exports",
+ "test:exports": "node ./test/_import.mjs && node ./test/_require.cjs",
+ "test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/csstools/postcss-plugins.git",
+ "directory": "plugins/postcss-gradients-interpolation-method"
+ },
+ "keywords": [
+ "color",
+ "conic",
+ "css",
+ "gradients",
+ "interpolation",
+ "linear",
+ "postcss",
+ "postcss-plugin",
+ "radial",
+ "repeating",
+ "syntax"
+ ],
+ "csstools": {
+ "cssdbId": "TODO",
+ "exportName": "postcssGradientsInterpolationMethod",
+ "humanReadableName": "PostCSS Gradients Interpolation Method",
+ "specUrl": "https://drafts.csswg.org/css-images-4/#linear-gradients"
+ },
+ "volta": {
+ "extends": "../../package.json"
+ },
+ "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-gradients-interpolation-method#readme",
+ "bugs": "https://github.com/csstools/postcss-plugins/issues"
+}
diff --git a/plugins/postcss-gradients-interpolation-method/src/color-stop-list.ts b/plugins/postcss-gradients-interpolation-method/src/color-stop-list.ts
new file mode 100644
index 000000000..7d7d1ba70
--- /dev/null
+++ b/plugins/postcss-gradients-interpolation-method/src/color-stop-list.ts
@@ -0,0 +1,93 @@
+import type { Node } from 'postcss-value-parser';
+
+export type ColorStop = {
+ color: string;
+ colorStopLength: string;
+ colorHintBetween: Array;
+ nodes: Array;
+}
+
+export function colorStopList(nodes: Array, interpolationArguments: string) : Array | false {
+ const stops: Array = [];
+ let currentStop: ColorStop = {
+ color: '',
+ colorStopLength: '',
+ colorHintBetween: [],
+ nodes: [],
+ };
+
+ for (let i = 0; i < nodes.length; i++) {
+ const node = nodes[i];
+ if (node.type === 'div' && node.value === ',') {
+ stops.push(currentStop);
+ currentStop = {
+ color: '',
+ colorStopLength: '',
+ colorHintBetween: [],
+ nodes: [],
+ };
+
+ continue;
+ }
+
+ currentStop.nodes.push(node);
+ }
+
+ stops.push(currentStop);
+
+ // Assign values and handle double position gradients.
+ const formattedStops : Array = [];
+ for (let i = 0; i < stops.length; i++) {
+ const stop = stops[i];
+
+ switch (stop.nodes.length) {
+ case 0:
+ break;
+ case 1:
+ return false;
+ case 2:
+ stop.color = stop.nodes[0].value;
+ stop.colorStopLength = stop.nodes[1].value;
+ formattedStops.push(stop);
+ break;
+ case 3:
+ formattedStops.push({
+ color: stop.nodes[0].value,
+ colorStopLength: stop.nodes[1].value,
+ colorHintBetween: [],
+ nodes: [
+ stop.nodes[0],
+ stop.nodes[1],
+ ],
+ });
+
+ formattedStops.push({
+ color: stop.nodes[0].value,
+ colorStopLength: stop.nodes[2].value,
+ colorHintBetween: [],
+ nodes: [
+ stop.nodes[0],
+ stop.nodes[2],
+ ],
+ });
+
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ for (let i = 0; i < formattedStops.length; i++) {
+ const stop = formattedStops[i];
+ if (!stop.color) {
+ stop.color = `color-mix(in ${interpolationArguments}, ${formattedStops[i - 1].color} 50%, ${formattedStops[i + 1].color} 50%)`;
+ stop.colorHintBetween = [
+ formattedStops[i - 1],
+ formattedStops[i + 1],
+ ];
+ }
+ }
+
+ return formattedStops;
+}
diff --git a/plugins/postcss-gradients-interpolation-method/src/has-supports-at-rule-ancestor.ts b/plugins/postcss-gradients-interpolation-method/src/has-supports-at-rule-ancestor.ts
new file mode 100644
index 000000000..36b3bad8d
--- /dev/null
+++ b/plugins/postcss-gradients-interpolation-method/src/has-supports-at-rule-ancestor.ts
@@ -0,0 +1,20 @@
+import { includesGradientsFunction } from './is-gradient';
+import type { AtRule, Node } from 'postcss';
+
+export function hasSupportsAtRuleAncestor(node: Node): boolean {
+ let parent = node.parent;
+ while (parent) {
+ if (parent.type !== 'atrule') {
+ parent = parent.parent;
+ continue;
+ }
+
+ if ((parent as AtRule).name === 'supports' && includesGradientsFunction((parent as AtRule).params)) {
+ return true;
+ }
+
+ parent = parent.parent;
+ }
+
+ return false;
+}
diff --git a/plugins/postcss-gradients-interpolation-method/src/index.ts b/plugins/postcss-gradients-interpolation-method/src/index.ts
new file mode 100644
index 000000000..1a498126b
--- /dev/null
+++ b/plugins/postcss-gradients-interpolation-method/src/index.ts
@@ -0,0 +1,235 @@
+import postcssProgressiveCustomProperties from '@csstools/postcss-progressive-custom-properties';
+import type { PluginCreator } from 'postcss';
+import type { Node } from 'postcss-value-parser';
+import valueParser from 'postcss-value-parser';
+import { ColorStop, colorStopList } from './color-stop-list';
+import { hasSupportsAtRuleAncestor } from './has-supports-at-rule-ancestor';
+import { includesGradientsFunction, isGradientsFunctions } from './is-gradient';
+
+const interpolationMethods = [
+ 'shorter',
+ 'longer',
+ 'increasing',
+ 'decreasing',
+ 'specified',
+];
+
+/**
+ * Transform double-position gradients in CSS.
+ * @param {{preserve?: boolean}} opts
+ * @returns {import('postcss').Plugin}
+ */
+const basePlugin = (opts) => {
+ return {
+ postcssPlugin: 'postcss-gradients-interpolation-method',
+ Declaration(decl, { result }) {
+ if (!includesGradientsFunction(decl.value)) {
+ return;
+ }
+
+ if (hasSupportsAtRuleAncestor(decl)) {
+ return;
+ }
+
+ let valueAST;
+
+ try {
+ valueAST = valueParser(decl.value);
+ } catch (error) {
+ decl.warn(
+ result,
+ `Failed to parse value '${decl.value}' as a CSS gradient. Leaving the original value intact.`,
+ );
+ }
+
+ if (typeof valueAST === 'undefined') {
+ // Bail if there's an error
+ return;
+ }
+
+ let hasUnparseableGradients = false;
+
+ valueAST.walk(func => {
+ if (func.type !== 'function' || !isGradientsFunctions(func.value)) {
+ return;
+ }
+
+ // Discarding comments and spaces
+ const nodes = func.nodes.filter((x) => {
+ return x.type !== 'comment' && x.type !== 'space';
+ });
+
+ // Build gradient data model.
+ const gradient: {
+ interpolationArguments: Array,
+ colorStops: Array,
+ argumentsRemainder: Array,
+ } = {
+ interpolationArguments: [],
+ argumentsRemainder: [],
+ colorStops: [],
+ };
+
+ for (let i = 0; i < nodes.length; i++) {
+ const node = nodes[i];
+ if (node.type === 'div' && node.value === ',') {
+ const interpolationArguments = gradient.interpolationArguments.map((x) => {
+ return valueParser.stringify(x);
+ }).join(' ');
+
+ const colorStops = colorStopList(nodes.slice(i), interpolationArguments);
+ if (colorStops) {
+ gradient.colorStops = colorStops;
+ break;
+ }
+
+ if (interpolationArguments) {
+ // If there are no interpolation arguments we do not emit warnings.
+ hasUnparseableGradients = true;
+ }
+ break;
+ }
+
+ if (node.type === 'word' && node.value === 'in' && nodes[i + 1]) {
+ gradient.interpolationArguments.push(nodes[i + 1]);
+ i++;
+
+ if (nodes[i + 1] && nodes[i + 1].type === 'word' && interpolationMethods.includes(nodes[i + 1].value)) {
+ gradient.interpolationArguments.push(nodes[i + 1]);
+ i++;
+ continue;
+ }
+
+ continue;
+ }
+
+ gradient.argumentsRemainder.push(node);
+ }
+
+ // No color stops or interpolation arguments found.
+ if (!gradient.interpolationArguments.length || !gradient.colorStops.length) {
+ return;
+ }
+
+ // Rebuild the entire function.
+ func.nodes = [];
+
+ if (gradient.argumentsRemainder.length) {
+ func.nodes.push(
+ ...gradient.argumentsRemainder.flatMap((x) => {
+ return [x, { type: 'space', value: ' ' }];
+ }),
+ );
+
+ func.nodes.push({
+ type: 'div',
+ value: ',',
+ });
+ }
+
+ const interpolationArguments = gradient.interpolationArguments.map((x) => {
+ return valueParser.stringify(x);
+ }).join(' ');
+
+ for (let i = 0; i < (gradient.colorStops.length); i++) {
+ const start = gradient.colorStops[i];
+ const end = gradient.colorStops[i + 1];
+
+ // Last color stop.
+ if (!end) {
+ func.nodes.push(
+ valueParser(`${start.color} ${start.colorStopLength}`),
+ );
+
+ continue;
+ }
+
+ // Two equal colors.
+ if (start.color === end.color) {
+ func.nodes.push(
+ valueParser(`${start.color} ${start.colorStopLength}`),
+ { type: 'div', value: ',' },
+ );
+
+ continue;
+ }
+
+ // Interpolate between colors.
+ for (let j = 0; j < 10; j++) {
+ if (j === 0) {
+ func.nodes.push(
+ valueParser(`${start.color} ${start.colorStopLength}`),
+ { type: 'div', value: ',' },
+ );
+
+ continue;
+ }
+
+ const color = `color-mix(in ${interpolationArguments}, ${start.color} ${100 - (j * 10)}%, ${end.color} ${(j * 10)}%)`;
+ const position = `calc(${start.colorStopLength} + ((${end.colorStopLength} - ${start.colorStopLength}) * ${j / 10}))`;
+
+ func.nodes.push(
+ valueParser(`${color} ${position}`),
+ { type: 'div', value: ',' },
+ );
+ }
+ }
+ });
+
+ if (hasUnparseableGradients) {
+ decl.warn(
+ result,
+ `Failed to parse value '${decl.value}' as a CSS gradient with interpolation. Leaving the original value intact.`,
+ );
+
+ return;
+ }
+
+ const modifiedValue = valueParser.stringify(valueAST);
+ if (modifiedValue === decl.value) {
+ return;
+ }
+
+ if (opts.preserve) {
+ decl.cloneBefore({
+ prop: decl.prop,
+ value: modifiedValue,
+ });
+ } else {
+ decl.value = modifiedValue;
+ }
+
+ },
+ };
+};
+
+basePlugin.postcss = true;
+
+type pluginOptions = {
+ preserve?: boolean;
+ enableProgressiveCustomProperties?: boolean;
+};
+
+// Transform gradient interpolation methods.
+const postcssPlugin: PluginCreator = (opts?: pluginOptions) => {
+ const options = Object.assign({
+ enableProgressiveCustomProperties: true,
+ preserve: true,
+ }, opts);
+
+ if (options.enableProgressiveCustomProperties && options.preserve) {
+ return {
+ postcssPlugin: 'postcss-gradients-interpolation-method',
+ plugins: [
+ postcssProgressiveCustomProperties(),
+ basePlugin(options),
+ ],
+ };
+ }
+
+ return basePlugin(options);
+};
+
+postcssPlugin.postcss = true;
+
+export default postcssPlugin;
diff --git a/plugins/postcss-gradients-interpolation-method/src/is-gradient.ts b/plugins/postcss-gradients-interpolation-method/src/is-gradient.ts
new file mode 100644
index 000000000..1cbfb708a
--- /dev/null
+++ b/plugins/postcss-gradients-interpolation-method/src/is-gradient.ts
@@ -0,0 +1,23 @@
+export function includesGradientsFunction(str: string): boolean {
+ return (
+ str.includes('in ') && (
+ str.includes('conic-gradient(') ||
+ str.includes('linear-gradient(') ||
+ str.includes('radial-gradient(') ||
+ str.includes('repeating-conic-gradient(') ||
+ str.includes('repeating-linear-gradient(') ||
+ str.includes('repeating-radial-gradient(')
+ )
+ );
+}
+
+export function isGradientsFunctions(str: string): boolean {
+ return (
+ str ==='conic-gradient' ||
+ str ==='linear-gradient' ||
+ str ==='radial-gradient' ||
+ str ==='repeating-conic-gradient' ||
+ str ==='repeating-linear-gradient' ||
+ str ==='repeating-radial-gradient'
+ );
+}
diff --git a/plugins/postcss-gradients-interpolation-method/test/_import.mjs b/plugins/postcss-gradients-interpolation-method/test/_import.mjs
new file mode 100644
index 000000000..e698ed8ea
--- /dev/null
+++ b/plugins/postcss-gradients-interpolation-method/test/_import.mjs
@@ -0,0 +1,6 @@
+import assert from 'assert';
+import plugin from '@csstools/postcss-gradients-interpolation-method';
+plugin();
+
+assert.ok(plugin.postcss, 'should have "postcss flag"');
+assert.equal(typeof plugin, 'function', 'should return a function');
diff --git a/plugins/postcss-gradients-interpolation-method/test/_require.cjs b/plugins/postcss-gradients-interpolation-method/test/_require.cjs
new file mode 100644
index 000000000..3a2b76cdb
--- /dev/null
+++ b/plugins/postcss-gradients-interpolation-method/test/_require.cjs
@@ -0,0 +1,6 @@
+const assert = require('assert');
+const plugin = require('@csstools/postcss-gradients-interpolation-method');
+plugin();
+
+assert.ok(plugin.postcss, 'should have "postcss flag"');
+assert.equal(typeof plugin, 'function', 'should return a function');
diff --git a/plugins/postcss-gradients-interpolation-method/test/basic.css b/plugins/postcss-gradients-interpolation-method/test/basic.css
new file mode 100644
index 000000000..671ea5033
--- /dev/null
+++ b/plugins/postcss-gradients-interpolation-method/test/basic.css
@@ -0,0 +1,21 @@
+.test-linear-gradient {
+ background-image: linear-gradient(in oklch 90deg, black 25% 50%,blue 70% 75%);
+
+ background-image: linear-gradient(in oklch shorter 90deg, black 25% 50%, blue 70% 75%);
+
+ --red: red;
+ /* Color stop variable */
+ background-image: linear-gradient(in oklch 90deg, black, var(--red), blue);
+ --perc-10: 10%;
+ /* Interpolation hint */
+ background-image: linear-gradient(in oklch 90deg, black, var(--perc-10), blue);
+}
+
+:root {
+ --gradient-prop-1: conic-gradient(in oklch, yellowgreen 0deg, gold 15deg, gold 50deg, #f06 180deg);
+ --gradient-prop-2: linear-gradient(in oklch 90deg, black 25%, red 45%, blue 50% 75%);
+ --gradient-prop-3: radial-gradient(in oklch, cyan 0%, transparent 20% 30%, salmon 40%);
+ --gradient-prop-4: repeating-conic-gradient(in oklch from 0deg, yellowgreen 40deg, gold 60deg 75deg, #f06 0deg);
+ --gradient-prop-5: repeating-linear-gradient(in oklch 90deg, black 25% 50%, blue 50% 75%);
+ --gradient-prop-6: repeating-radial-gradient(in oklch, red 0 8%, yellow 8% 16%, blue 16% 24%);
+}
diff --git a/plugins/postcss-gradients-interpolation-method/test/basic.expect.css b/plugins/postcss-gradients-interpolation-method/test/basic.expect.css
new file mode 100644
index 000000000..28d75d89d
--- /dev/null
+++ b/plugins/postcss-gradients-interpolation-method/test/basic.expect.css
@@ -0,0 +1,60 @@
+.test-linear-gradient {
+ background-image: linear-gradient(90deg ,black 25%,black 50%,color-mix(in oklch, black 90%, blue 10%) calc(50% + ((70% - 50%) * 0.1)),color-mix(in oklch, black 80%, blue 20%) calc(50% + ((70% - 50%) * 0.2)),color-mix(in oklch, black 70%, blue 30%) calc(50% + ((70% - 50%) * 0.3)),color-mix(in oklch, black 60%, blue 40%) calc(50% + ((70% - 50%) * 0.4)),color-mix(in oklch, black 50%, blue 50%) calc(50% + ((70% - 50%) * 0.5)),color-mix(in oklch, black 40%, blue 60%) calc(50% + ((70% - 50%) * 0.6)),color-mix(in oklch, black 30%, blue 70%) calc(50% + ((70% - 50%) * 0.7)),color-mix(in oklch, black 20%, blue 80%) calc(50% + ((70% - 50%) * 0.8)),color-mix(in oklch, black 10%, blue 90%) calc(50% + ((70% - 50%) * 0.9)),blue 70%,blue 75%);
+ background-image: linear-gradient(in oklch 90deg, black 25% 50%,blue 70% 75%);
+
+ background-image: linear-gradient(90deg ,black 25%,black 50%,color-mix(in oklch shorter, black 90%, blue 10%) calc(50% + ((70% - 50%) * 0.1)),color-mix(in oklch shorter, black 80%, blue 20%) calc(50% + ((70% - 50%) * 0.2)),color-mix(in oklch shorter, black 70%, blue 30%) calc(50% + ((70% - 50%) * 0.3)),color-mix(in oklch shorter, black 60%, blue 40%) calc(50% + ((70% - 50%) * 0.4)),color-mix(in oklch shorter, black 50%, blue 50%) calc(50% + ((70% - 50%) * 0.5)),color-mix(in oklch shorter, black 40%, blue 60%) calc(50% + ((70% - 50%) * 0.6)),color-mix(in oklch shorter, black 30%, blue 70%) calc(50% + ((70% - 50%) * 0.7)),color-mix(in oklch shorter, black 20%, blue 80%) calc(50% + ((70% - 50%) * 0.8)),color-mix(in oklch shorter, black 10%, blue 90%) calc(50% + ((70% - 50%) * 0.9)),blue 70%,blue 75%);
+
+ background-image: linear-gradient(in oklch shorter 90deg, black 25% 50%, blue 70% 75%);
+
+ --red: red;
+ /* Color stop variable */
+ background-image: linear-gradient(in oklch 90deg, black, var(--red), blue);
+ --perc-10: 10%;
+ /* Interpolation hint */
+ background-image: linear-gradient(in oklch 90deg, black, var(--perc-10), blue);
+}
+
+:root {
+ --gradient-prop-1: conic-gradient(yellowgreen 0deg,color-mix(in oklch, yellowgreen 90%, gold 10%) calc(0deg + ((15deg - 0deg) * 0.1)),color-mix(in oklch, yellowgreen 80%, gold 20%) calc(0deg + ((15deg - 0deg) * 0.2)),color-mix(in oklch, yellowgreen 70%, gold 30%) calc(0deg + ((15deg - 0deg) * 0.3)),color-mix(in oklch, yellowgreen 60%, gold 40%) calc(0deg + ((15deg - 0deg) * 0.4)),color-mix(in oklch, yellowgreen 50%, gold 50%) calc(0deg + ((15deg - 0deg) * 0.5)),color-mix(in oklch, yellowgreen 40%, gold 60%) calc(0deg + ((15deg - 0deg) * 0.6)),color-mix(in oklch, yellowgreen 30%, gold 70%) calc(0deg + ((15deg - 0deg) * 0.7)),color-mix(in oklch, yellowgreen 20%, gold 80%) calc(0deg + ((15deg - 0deg) * 0.8)),color-mix(in oklch, yellowgreen 10%, gold 90%) calc(0deg + ((15deg - 0deg) * 0.9)),gold 15deg,gold 50deg,color-mix(in oklch, gold 90%, #f06 10%) calc(50deg + ((180deg - 50deg) * 0.1)),color-mix(in oklch, gold 80%, #f06 20%) calc(50deg + ((180deg - 50deg) * 0.2)),color-mix(in oklch, gold 70%, #f06 30%) calc(50deg + ((180deg - 50deg) * 0.3)),color-mix(in oklch, gold 60%, #f06 40%) calc(50deg + ((180deg - 50deg) * 0.4)),color-mix(in oklch, gold 50%, #f06 50%) calc(50deg + ((180deg - 50deg) * 0.5)),color-mix(in oklch, gold 40%, #f06 60%) calc(50deg + ((180deg - 50deg) * 0.6)),color-mix(in oklch, gold 30%, #f06 70%) calc(50deg + ((180deg - 50deg) * 0.7)),color-mix(in oklch, gold 20%, #f06 80%) calc(50deg + ((180deg - 50deg) * 0.8)),color-mix(in oklch, gold 10%, #f06 90%) calc(50deg + ((180deg - 50deg) * 0.9)),#f06 180deg);
+ --gradient-prop-2: linear-gradient(90deg ,black 25%,color-mix(in oklch, black 90%, red 10%) calc(25% + ((45% - 25%) * 0.1)),color-mix(in oklch, black 80%, red 20%) calc(25% + ((45% - 25%) * 0.2)),color-mix(in oklch, black 70%, red 30%) calc(25% + ((45% - 25%) * 0.3)),color-mix(in oklch, black 60%, red 40%) calc(25% + ((45% - 25%) * 0.4)),color-mix(in oklch, black 50%, red 50%) calc(25% + ((45% - 25%) * 0.5)),color-mix(in oklch, black 40%, red 60%) calc(25% + ((45% - 25%) * 0.6)),color-mix(in oklch, black 30%, red 70%) calc(25% + ((45% - 25%) * 0.7)),color-mix(in oklch, black 20%, red 80%) calc(25% + ((45% - 25%) * 0.8)),color-mix(in oklch, black 10%, red 90%) calc(25% + ((45% - 25%) * 0.9)),red 45%,color-mix(in oklch, red 90%, blue 10%) calc(45% + ((50% - 45%) * 0.1)),color-mix(in oklch, red 80%, blue 20%) calc(45% + ((50% - 45%) * 0.2)),color-mix(in oklch, red 70%, blue 30%) calc(45% + ((50% - 45%) * 0.3)),color-mix(in oklch, red 60%, blue 40%) calc(45% + ((50% - 45%) * 0.4)),color-mix(in oklch, red 50%, blue 50%) calc(45% + ((50% - 45%) * 0.5)),color-mix(in oklch, red 40%, blue 60%) calc(45% + ((50% - 45%) * 0.6)),color-mix(in oklch, red 30%, blue 70%) calc(45% + ((50% - 45%) * 0.7)),color-mix(in oklch, red 20%, blue 80%) calc(45% + ((50% - 45%) * 0.8)),color-mix(in oklch, red 10%, blue 90%) calc(45% + ((50% - 45%) * 0.9)),blue 50%,blue 75%);
+ --gradient-prop-3: radial-gradient(cyan 0%,color-mix(in oklch, cyan 90%, transparent 10%) calc(0% + ((20% - 0%) * 0.1)),color-mix(in oklch, cyan 80%, transparent 20%) calc(0% + ((20% - 0%) * 0.2)),color-mix(in oklch, cyan 70%, transparent 30%) calc(0% + ((20% - 0%) * 0.3)),color-mix(in oklch, cyan 60%, transparent 40%) calc(0% + ((20% - 0%) * 0.4)),color-mix(in oklch, cyan 50%, transparent 50%) calc(0% + ((20% - 0%) * 0.5)),color-mix(in oklch, cyan 40%, transparent 60%) calc(0% + ((20% - 0%) * 0.6)),color-mix(in oklch, cyan 30%, transparent 70%) calc(0% + ((20% - 0%) * 0.7)),color-mix(in oklch, cyan 20%, transparent 80%) calc(0% + ((20% - 0%) * 0.8)),color-mix(in oklch, cyan 10%, transparent 90%) calc(0% + ((20% - 0%) * 0.9)),transparent 20%,transparent 30%,color-mix(in oklch, transparent 90%, salmon 10%) calc(30% + ((40% - 30%) * 0.1)),color-mix(in oklch, transparent 80%, salmon 20%) calc(30% + ((40% - 30%) * 0.2)),color-mix(in oklch, transparent 70%, salmon 30%) calc(30% + ((40% - 30%) * 0.3)),color-mix(in oklch, transparent 60%, salmon 40%) calc(30% + ((40% - 30%) * 0.4)),color-mix(in oklch, transparent 50%, salmon 50%) calc(30% + ((40% - 30%) * 0.5)),color-mix(in oklch, transparent 40%, salmon 60%) calc(30% + ((40% - 30%) * 0.6)),color-mix(in oklch, transparent 30%, salmon 70%) calc(30% + ((40% - 30%) * 0.7)),color-mix(in oklch, transparent 20%, salmon 80%) calc(30% + ((40% - 30%) * 0.8)),color-mix(in oklch, transparent 10%, salmon 90%) calc(30% + ((40% - 30%) * 0.9)),salmon 40%);
+ --gradient-prop-4: repeating-conic-gradient(from 0deg ,yellowgreen 40deg,color-mix(in oklch, yellowgreen 90%, gold 10%) calc(40deg + ((60deg - 40deg) * 0.1)),color-mix(in oklch, yellowgreen 80%, gold 20%) calc(40deg + ((60deg - 40deg) * 0.2)),color-mix(in oklch, yellowgreen 70%, gold 30%) calc(40deg + ((60deg - 40deg) * 0.3)),color-mix(in oklch, yellowgreen 60%, gold 40%) calc(40deg + ((60deg - 40deg) * 0.4)),color-mix(in oklch, yellowgreen 50%, gold 50%) calc(40deg + ((60deg - 40deg) * 0.5)),color-mix(in oklch, yellowgreen 40%, gold 60%) calc(40deg + ((60deg - 40deg) * 0.6)),color-mix(in oklch, yellowgreen 30%, gold 70%) calc(40deg + ((60deg - 40deg) * 0.7)),color-mix(in oklch, yellowgreen 20%, gold 80%) calc(40deg + ((60deg - 40deg) * 0.8)),color-mix(in oklch, yellowgreen 10%, gold 90%) calc(40deg + ((60deg - 40deg) * 0.9)),gold 60deg,gold 75deg,color-mix(in oklch, gold 90%, #f06 10%) calc(75deg + ((0deg - 75deg) * 0.1)),color-mix(in oklch, gold 80%, #f06 20%) calc(75deg + ((0deg - 75deg) * 0.2)),color-mix(in oklch, gold 70%, #f06 30%) calc(75deg + ((0deg - 75deg) * 0.3)),color-mix(in oklch, gold 60%, #f06 40%) calc(75deg + ((0deg - 75deg) * 0.4)),color-mix(in oklch, gold 50%, #f06 50%) calc(75deg + ((0deg - 75deg) * 0.5)),color-mix(in oklch, gold 40%, #f06 60%) calc(75deg + ((0deg - 75deg) * 0.6)),color-mix(in oklch, gold 30%, #f06 70%) calc(75deg + ((0deg - 75deg) * 0.7)),color-mix(in oklch, gold 20%, #f06 80%) calc(75deg + ((0deg - 75deg) * 0.8)),color-mix(in oklch, gold 10%, #f06 90%) calc(75deg + ((0deg - 75deg) * 0.9)),#f06 0deg);
+ --gradient-prop-5: repeating-linear-gradient(90deg ,black 25%,black 50%,color-mix(in oklch, black 90%, blue 10%) calc(50% + ((50% - 50%) * 0.1)),color-mix(in oklch, black 80%, blue 20%) calc(50% + ((50% - 50%) * 0.2)),color-mix(in oklch, black 70%, blue 30%) calc(50% + ((50% - 50%) * 0.3)),color-mix(in oklch, black 60%, blue 40%) calc(50% + ((50% - 50%) * 0.4)),color-mix(in oklch, black 50%, blue 50%) calc(50% + ((50% - 50%) * 0.5)),color-mix(in oklch, black 40%, blue 60%) calc(50% + ((50% - 50%) * 0.6)),color-mix(in oklch, black 30%, blue 70%) calc(50% + ((50% - 50%) * 0.7)),color-mix(in oklch, black 20%, blue 80%) calc(50% + ((50% - 50%) * 0.8)),color-mix(in oklch, black 10%, blue 90%) calc(50% + ((50% - 50%) * 0.9)),blue 50%,blue 75%);
+ --gradient-prop-6: repeating-radial-gradient(red 0,red 8%,color-mix(in oklch, red 90%, yellow 10%) calc(8% + ((8% - 8%) * 0.1)),color-mix(in oklch, red 80%, yellow 20%) calc(8% + ((8% - 8%) * 0.2)),color-mix(in oklch, red 70%, yellow 30%) calc(8% + ((8% - 8%) * 0.3)),color-mix(in oklch, red 60%, yellow 40%) calc(8% + ((8% - 8%) * 0.4)),color-mix(in oklch, red 50%, yellow 50%) calc(8% + ((8% - 8%) * 0.5)),color-mix(in oklch, red 40%, yellow 60%) calc(8% + ((8% - 8%) * 0.6)),color-mix(in oklch, red 30%, yellow 70%) calc(8% + ((8% - 8%) * 0.7)),color-mix(in oklch, red 20%, yellow 80%) calc(8% + ((8% - 8%) * 0.8)),color-mix(in oklch, red 10%, yellow 90%) calc(8% + ((8% - 8%) * 0.9)),yellow 8%,yellow 16%,color-mix(in oklch, yellow 90%, blue 10%) calc(16% + ((16% - 16%) * 0.1)),color-mix(in oklch, yellow 80%, blue 20%) calc(16% + ((16% - 16%) * 0.2)),color-mix(in oklch, yellow 70%, blue 30%) calc(16% + ((16% - 16%) * 0.3)),color-mix(in oklch, yellow 60%, blue 40%) calc(16% + ((16% - 16%) * 0.4)),color-mix(in oklch, yellow 50%, blue 50%) calc(16% + ((16% - 16%) * 0.5)),color-mix(in oklch, yellow 40%, blue 60%) calc(16% + ((16% - 16%) * 0.6)),color-mix(in oklch, yellow 30%, blue 70%) calc(16% + ((16% - 16%) * 0.7)),color-mix(in oklch, yellow 20%, blue 80%) calc(16% + ((16% - 16%) * 0.8)),color-mix(in oklch, yellow 10%, blue 90%) calc(16% + ((16% - 16%) * 0.9)),blue 16%,blue 24%);
+}
+
+@supports (background: conic-gradient(in oklch, red 0deg, red 0deg 1deg, red 2deg)) {
+:root {
+ --gradient-prop-1: conic-gradient(in oklch, yellowgreen 0deg, gold 15deg, gold 50deg, #f06 180deg);
+}
+}
+
+@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) {
+:root {
+ --gradient-prop-2: linear-gradient(in oklch 90deg, black 25%, red 45%, blue 50% 75%);
+}
+}
+
+@supports (background: radial-gradient(in oklch, red, red 1px 2px, red 3px)) {
+:root {
+ --gradient-prop-3: radial-gradient(in oklch, cyan 0%, transparent 20% 30%, salmon 40%);
+}
+}
+
+@supports (background: repeating-conic-gradient(in oklch from 0deg, red 0deg, red 0deg 1deg, red 2deg)) {
+:root {
+ --gradient-prop-4: repeating-conic-gradient(in oklch from 0deg, yellowgreen 40deg, gold 60deg 75deg, #f06 0deg);
+}
+}
+
+@supports (background: repeating-linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) {
+:root {
+ --gradient-prop-5: repeating-linear-gradient(in oklch 90deg, black 25% 50%, blue 50% 75%);
+}
+}
+
+@supports (background: repeating-radial-gradient(in oklch, red, red 1px 2px, red 3px)) {
+:root {
+ --gradient-prop-6: repeating-radial-gradient(in oklch, red 0 8%, yellow 8% 16%, blue 16% 24%);
+}
+}
diff --git a/plugins/postcss-gradients-interpolation-method/test/examples/example.css b/plugins/postcss-gradients-interpolation-method/test/examples/example.css
new file mode 100644
index 000000000..e151b08eb
--- /dev/null
+++ b/plugins/postcss-gradients-interpolation-method/test/examples/example.css
@@ -0,0 +1,7 @@
+.oklch {
+ background: linear-gradient(in oklch 90deg, black 25% , blue 75%);
+}
+
+:root {
+ --background: linear-gradient(in oklch 90deg, black 25%, blue 75%);
+}
diff --git a/plugins/postcss-gradients-interpolation-method/test/examples/example.expect.css b/plugins/postcss-gradients-interpolation-method/test/examples/example.expect.css
new file mode 100644
index 000000000..6f4d926ce
--- /dev/null
+++ b/plugins/postcss-gradients-interpolation-method/test/examples/example.expect.css
@@ -0,0 +1,14 @@
+.oklch {
+ background: linear-gradient(90deg ,black 25%,color-mix(in oklch, black 90%, blue 10%) calc(25% + ((75% - 25%) * 0.1)),color-mix(in oklch, black 80%, blue 20%) calc(25% + ((75% - 25%) * 0.2)),color-mix(in oklch, black 70%, blue 30%) calc(25% + ((75% - 25%) * 0.3)),color-mix(in oklch, black 60%, blue 40%) calc(25% + ((75% - 25%) * 0.4)),color-mix(in oklch, black 50%, blue 50%) calc(25% + ((75% - 25%) * 0.5)),color-mix(in oklch, black 40%, blue 60%) calc(25% + ((75% - 25%) * 0.6)),color-mix(in oklch, black 30%, blue 70%) calc(25% + ((75% - 25%) * 0.7)),color-mix(in oklch, black 20%, blue 80%) calc(25% + ((75% - 25%) * 0.8)),color-mix(in oklch, black 10%, blue 90%) calc(25% + ((75% - 25%) * 0.9)),blue 75%);
+ background: linear-gradient(in oklch 90deg, black 25% , blue 75%);
+}
+
+:root {
+ --background: linear-gradient(90deg ,black 25%,color-mix(in oklch, black 90%, blue 10%) calc(25% + ((75% - 25%) * 0.1)),color-mix(in oklch, black 80%, blue 20%) calc(25% + ((75% - 25%) * 0.2)),color-mix(in oklch, black 70%, blue 30%) calc(25% + ((75% - 25%) * 0.3)),color-mix(in oklch, black 60%, blue 40%) calc(25% + ((75% - 25%) * 0.4)),color-mix(in oklch, black 50%, blue 50%) calc(25% + ((75% - 25%) * 0.5)),color-mix(in oklch, black 40%, blue 60%) calc(25% + ((75% - 25%) * 0.6)),color-mix(in oklch, black 30%, blue 70%) calc(25% + ((75% - 25%) * 0.7)),color-mix(in oklch, black 20%, blue 80%) calc(25% + ((75% - 25%) * 0.8)),color-mix(in oklch, black 10%, blue 90%) calc(25% + ((75% - 25%) * 0.9)),blue 75%);
+}
+
+@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) {
+:root {
+ --background: linear-gradient(in oklch 90deg, black 25%, blue 75%);
+}
+}
diff --git a/plugins/postcss-gradients-interpolation-method/test/examples/example.preserve-true.expect.css b/plugins/postcss-gradients-interpolation-method/test/examples/example.preserve-true.expect.css
new file mode 100644
index 000000000..6f4d926ce
--- /dev/null
+++ b/plugins/postcss-gradients-interpolation-method/test/examples/example.preserve-true.expect.css
@@ -0,0 +1,14 @@
+.oklch {
+ background: linear-gradient(90deg ,black 25%,color-mix(in oklch, black 90%, blue 10%) calc(25% + ((75% - 25%) * 0.1)),color-mix(in oklch, black 80%, blue 20%) calc(25% + ((75% - 25%) * 0.2)),color-mix(in oklch, black 70%, blue 30%) calc(25% + ((75% - 25%) * 0.3)),color-mix(in oklch, black 60%, blue 40%) calc(25% + ((75% - 25%) * 0.4)),color-mix(in oklch, black 50%, blue 50%) calc(25% + ((75% - 25%) * 0.5)),color-mix(in oklch, black 40%, blue 60%) calc(25% + ((75% - 25%) * 0.6)),color-mix(in oklch, black 30%, blue 70%) calc(25% + ((75% - 25%) * 0.7)),color-mix(in oklch, black 20%, blue 80%) calc(25% + ((75% - 25%) * 0.8)),color-mix(in oklch, black 10%, blue 90%) calc(25% + ((75% - 25%) * 0.9)),blue 75%);
+ background: linear-gradient(in oklch 90deg, black 25% , blue 75%);
+}
+
+:root {
+ --background: linear-gradient(90deg ,black 25%,color-mix(in oklch, black 90%, blue 10%) calc(25% + ((75% - 25%) * 0.1)),color-mix(in oklch, black 80%, blue 20%) calc(25% + ((75% - 25%) * 0.2)),color-mix(in oklch, black 70%, blue 30%) calc(25% + ((75% - 25%) * 0.3)),color-mix(in oklch, black 60%, blue 40%) calc(25% + ((75% - 25%) * 0.4)),color-mix(in oklch, black 50%, blue 50%) calc(25% + ((75% - 25%) * 0.5)),color-mix(in oklch, black 40%, blue 60%) calc(25% + ((75% - 25%) * 0.6)),color-mix(in oklch, black 30%, blue 70%) calc(25% + ((75% - 25%) * 0.7)),color-mix(in oklch, black 20%, blue 80%) calc(25% + ((75% - 25%) * 0.8)),color-mix(in oklch, black 10%, blue 90%) calc(25% + ((75% - 25%) * 0.9)),blue 75%);
+}
+
+@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) {
+:root {
+ --background: linear-gradient(in oklch 90deg, black 25%, blue 75%);
+}
+}
diff --git a/plugins/postcss-gradients-interpolation-method/test/examples/example.preserve-true.progressive-false.expect.css b/plugins/postcss-gradients-interpolation-method/test/examples/example.preserve-true.progressive-false.expect.css
new file mode 100644
index 000000000..7b8499673
--- /dev/null
+++ b/plugins/postcss-gradients-interpolation-method/test/examples/example.preserve-true.progressive-false.expect.css
@@ -0,0 +1,9 @@
+.oklch {
+ background: linear-gradient(90deg ,black 25%,color-mix(in oklch, black 90%, blue 10%) calc(25% + ((75% - 25%) * 0.1)),color-mix(in oklch, black 80%, blue 20%) calc(25% + ((75% - 25%) * 0.2)),color-mix(in oklch, black 70%, blue 30%) calc(25% + ((75% - 25%) * 0.3)),color-mix(in oklch, black 60%, blue 40%) calc(25% + ((75% - 25%) * 0.4)),color-mix(in oklch, black 50%, blue 50%) calc(25% + ((75% - 25%) * 0.5)),color-mix(in oklch, black 40%, blue 60%) calc(25% + ((75% - 25%) * 0.6)),color-mix(in oklch, black 30%, blue 70%) calc(25% + ((75% - 25%) * 0.7)),color-mix(in oklch, black 20%, blue 80%) calc(25% + ((75% - 25%) * 0.8)),color-mix(in oklch, black 10%, blue 90%) calc(25% + ((75% - 25%) * 0.9)),blue 75%);
+ background: linear-gradient(in oklch 90deg, black 25% , blue 75%);
+}
+
+:root {
+ --background: linear-gradient(90deg ,black 25%,color-mix(in oklch, black 90%, blue 10%) calc(25% + ((75% - 25%) * 0.1)),color-mix(in oklch, black 80%, blue 20%) calc(25% + ((75% - 25%) * 0.2)),color-mix(in oklch, black 70%, blue 30%) calc(25% + ((75% - 25%) * 0.3)),color-mix(in oklch, black 60%, blue 40%) calc(25% + ((75% - 25%) * 0.4)),color-mix(in oklch, black 50%, blue 50%) calc(25% + ((75% - 25%) * 0.5)),color-mix(in oklch, black 40%, blue 60%) calc(25% + ((75% - 25%) * 0.6)),color-mix(in oklch, black 30%, blue 70%) calc(25% + ((75% - 25%) * 0.7)),color-mix(in oklch, black 20%, blue 80%) calc(25% + ((75% - 25%) * 0.8)),color-mix(in oklch, black 10%, blue 90%) calc(25% + ((75% - 25%) * 0.9)),blue 75%);
+ --background: linear-gradient(in oklch 90deg, black 25%, blue 75%);
+}
diff --git a/plugins/postcss-gradients-interpolation-method/tsconfig.json b/plugins/postcss-gradients-interpolation-method/tsconfig.json
new file mode 100644
index 000000000..e0d06239c
--- /dev/null
+++ b/plugins/postcss-gradients-interpolation-method/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "dist",
+ "declarationDir": "."
+ },
+ "include": ["./src/**/*"],
+ "exclude": ["dist"],
+}
diff --git a/plugins/postcss-progressive-custom-properties/src/custom/double-position-gradients.ts b/plugins/postcss-progressive-custom-properties/src/custom/double-position-gradients.ts
index 62216c634..a862280a8 100644
--- a/plugins/postcss-progressive-custom-properties/src/custom/double-position-gradients.ts
+++ b/plugins/postcss-progressive-custom-properties/src/custom/double-position-gradients.ts
@@ -1,5 +1,23 @@
import type { Node } from 'postcss-value-parser';
+const keywords = [
+ 'at',
+ 'bottom',
+ 'center',
+ 'circle',
+ 'closest-corner',
+ 'closest-side',
+ 'ellipse',
+ 'farthest-corner',
+ 'farthest-side',
+ 'from',
+ 'in',
+ 'left',
+ 'right',
+ 'to',
+ 'top',
+];
+
export function doublePositionGradients(node: Node): Array {
const supportConditions: Array = [];
@@ -12,14 +30,25 @@ export function doublePositionGradients(node: Node): Array {
node.value === 'repeating-linear-gradient' ||
node.value === 'repeating-radial-gradient'
)) {
+
let components = 0;
- let seenPrefix = false;
+ let inPrefix = false;
+ let hasColorInterpolationMethod = false;
nodesLoop: for (let i = 0; i < node.nodes.length; i++) {
const childNode = node.nodes[i];
+ if (childNode.type === 'word' && keywords.includes(childNode.value)) {
+ inPrefix = true;
+ }
+
if (childNode.type === 'div' && childNode.value.trim() === ',') {
components = 0;
- seenPrefix = true;
+ inPrefix = false;
+ continue;
+ }
+
+ if (childNode.type === 'word' && childNode.value === 'in') {
+ hasColorInterpolationMethod = true;
continue;
}
@@ -27,13 +56,36 @@ export function doublePositionGradients(node: Node): Array {
components++;
}
- if (seenPrefix && components === 3) {
+ if (hasColorInterpolationMethod) {
+ switch (node.value) {
+ case 'conic-gradient':
+ supportConditions.push('(background: conic-gradient(in oklch, red 0deg, red 0deg 1deg, red 2deg))');
+ break nodesLoop;
+ case 'linear-gradient':
+ supportConditions.push('(background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%))');
+ break nodesLoop;
+ case 'radial-gradient':
+ supportConditions.push('(background: radial-gradient(in oklch, red, red 1px 2px, red 3px))');
+ break nodesLoop;
+ case 'repeating-conic-gradient':
+ supportConditions.push('(background: repeating-conic-gradient(in oklch from 0deg, red 0deg, red 0deg 1deg, red 2deg))');
+ break nodesLoop;
+ case 'repeating-linear-gradient':
+ supportConditions.push('(background: repeating-linear-gradient(in oklch, red 0%, red 0% 1%, red 2%))');
+ break nodesLoop;
+ case 'repeating-radial-gradient':
+ supportConditions.push('(background: repeating-radial-gradient(in oklch, red, red 1px 2px, red 3px))');
+ break nodesLoop;
+ }
+ }
+
+ if (!inPrefix && components === 3) {
switch (node.value) {
case 'conic-gradient':
- supportConditions.push('(background: conic-gradient(red 0%, red 0deg 1%, red 2deg))');
+ supportConditions.push('(background: conic-gradient(red 0deg, red 0deg 1deg, red 2deg))');
break nodesLoop;
case 'linear-gradient':
- supportConditions.push('(background: linear-gradient(0deg, red 0% 1%, red 2%))');
+ supportConditions.push('(background: linear-gradient(red 0%, red 0% 1%, red 2%))');
break nodesLoop;
case 'radial-gradient':
supportConditions.push('(background: radial-gradient(red, red 1px 2px, red 3px))');
@@ -42,7 +94,7 @@ export function doublePositionGradients(node: Node): Array {
supportConditions.push('(background: repeating-conic-gradient(from 0deg, red 0deg, red 0deg 1deg, red 2deg))');
break nodesLoop;
case 'repeating-linear-gradient':
- supportConditions.push('(background: repeating-linear-gradient(0deg, red 0% 1%, red 2%))');
+ supportConditions.push('(background: repeating-linear-gradient(red 0%, red 0% 1%, red 2%))');
break nodesLoop;
case 'repeating-radial-gradient':
supportConditions.push('(background: repeating-radial-gradient(red, red 1px 2px, red 3px))');
diff --git a/plugins/postcss-progressive-custom-properties/test/basic.css b/plugins/postcss-progressive-custom-properties/test/basic.css
index 0d00d7b3e..2d530991c 100644
--- a/plugins/postcss-progressive-custom-properties/test/basic.css
+++ b/plugins/postcss-progressive-custom-properties/test/basic.css
@@ -85,3 +85,17 @@
--color-6: orange;
--color-6: color(rec2020 0.64331 0.19245 0.16771);
}
+
+:root {
+ /* interleaved with color interpolation */
+ --gradient-prop-6: linear-gradient(90deg, black 25%, black 50%, blue 50%, blue 75%);
+ --gradient-prop-7: conic-gradient(yellowgreen 40%, gold 0deg, gold 75%, #f06 0deg);
+ --gradient-prop-6: linear-gradient(in oklch 90deg, black 25% 50%, blue 50% 75%);
+ --gradient-prop-7: conic-gradient(in oklch, yellowgreen 40%, gold 0deg 75%, #f06 0deg);
+ --gradient-prop-8: repeating-linear-gradient(90deg, black 25%, black 50%, blue 50%, blue 75%);
+ --gradient-prop-9: repeating-conic-gradient(yellowgreen 40%, gold 0deg, gold 75%, #f06 0deg);
+ --gradient-prop-8: repeating-linear-gradient(in oklch 90deg, black 25% 50%, blue 50% 75%);
+ --gradient-prop-9: repeating-conic-gradient(in oklch from 0deg, yellowgreen 40deg, gold 60deg 75deg, #f06 0deg);
+ --gradient-prop-10: repeating-radial-gradient(red 0, red 8%, yellow 8%, yellow 16%, blue 16%, blue 24%);
+ --gradient-prop-10: repeating-radial-gradient(in oklch, red 0 8%, yellow 8% 16%, blue 16% 24%);
+}
diff --git a/plugins/postcss-progressive-custom-properties/test/basic.expect.css b/plugins/postcss-progressive-custom-properties/test/basic.expect.css
index 72a17d612..933906355 100644
--- a/plugins/postcss-progressive-custom-properties/test/basic.expect.css
+++ b/plugins/postcss-progressive-custom-properties/test/basic.expect.css
@@ -30,7 +30,7 @@
}
}
-@supports (background: linear-gradient(0deg, red 0% 1%, red 2%)) and (color: rgba(0 0 0 / 0)) and (color: color(rec2020 0 0 0)) {
+@supports (background: linear-gradient(red 0%, red 0% 1%, red 2%)) and (color: rgba(0 0 0 / 0)) and (color: color(rec2020 0 0 0)) {
:root {
--prop-2: linear-gradient(
45deg,
@@ -51,19 +51,19 @@
}
}
-@supports (background: linear-gradient(0deg, red 0% 1%, red 2%)) {
+@supports (background: linear-gradient(red 0%, red 0% 1%, red 2%)) {
:root {
--gradient-prop-6: linear-gradient(90deg, black 25% 50%, blue 50% 75%);
}
}
-@supports (background: conic-gradient(red 0%, red 0deg 1%, red 2deg)) {
+@supports (background: conic-gradient(red 0deg, red 0deg 1deg, red 2deg)) {
:root {
--gradient-prop-7: conic-gradient(yellowgreen 40%, gold 0deg 75%, #f06 0deg);
}
}
-@supports (background: repeating-linear-gradient(0deg, red 0% 1%, red 2%)) {
+@supports (background: repeating-linear-gradient(red 0%, red 0% 1%, red 2%)) {
:root {
--gradient-prop-8: repeating-linear-gradient(90deg, black 25% 50%, blue 50% 75%);
}
@@ -170,3 +170,42 @@
--color-6: color(rec2020 0.64331 0.19245 0.16771);
}
}
+
+:root {
+ /* interleaved with color interpolation */
+ --gradient-prop-6: linear-gradient(90deg, black 25%, black 50%, blue 50%, blue 75%);
+ --gradient-prop-7: conic-gradient(yellowgreen 40%, gold 0deg, gold 75%, #f06 0deg);
+ --gradient-prop-8: repeating-linear-gradient(90deg, black 25%, black 50%, blue 50%, blue 75%);
+ --gradient-prop-9: repeating-conic-gradient(yellowgreen 40%, gold 0deg, gold 75%, #f06 0deg);
+ --gradient-prop-10: repeating-radial-gradient(red 0, red 8%, yellow 8%, yellow 16%, blue 16%, blue 24%);
+}
+
+@supports (background: linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) {
+:root {
+ --gradient-prop-6: linear-gradient(in oklch 90deg, black 25% 50%, blue 50% 75%);
+}
+}
+
+@supports (background: conic-gradient(in oklch, red 0deg, red 0deg 1deg, red 2deg)) {
+:root {
+ --gradient-prop-7: conic-gradient(in oklch, yellowgreen 40%, gold 0deg 75%, #f06 0deg);
+}
+}
+
+@supports (background: repeating-linear-gradient(in oklch, red 0%, red 0% 1%, red 2%)) {
+:root {
+ --gradient-prop-8: repeating-linear-gradient(in oklch 90deg, black 25% 50%, blue 50% 75%);
+}
+}
+
+@supports (background: repeating-conic-gradient(in oklch from 0deg, red 0deg, red 0deg 1deg, red 2deg)) {
+:root {
+ --gradient-prop-9: repeating-conic-gradient(in oklch from 0deg, yellowgreen 40deg, gold 60deg 75deg, #f06 0deg);
+}
+}
+
+@supports (background: repeating-radial-gradient(in oklch, red, red 1px 2px, red 3px)) {
+:root {
+ --gradient-prop-10: repeating-radial-gradient(in oklch, red 0 8%, yellow 8% 16%, blue 16% 24%);
+}
+}
From 446be6fe8e44b45433d2306a05d604fb84a1a5f8 Mon Sep 17 00:00:00 2001
From: romainmenke
Date: Fri, 4 Mar 2022 17:29:33 +0100
Subject: [PATCH 3/8] labels, issue templates
---
.github/ISSUE_TEMPLATE/css-issue.yml | 1 +
.github/ISSUE_TEMPLATE/plugin-issue.yml | 1 +
.github/labeler.yml | 4 ++++
plugins/postcss-progressive-custom-properties/CHANGELOG.md | 4 ++++
4 files changed, 10 insertions(+)
diff --git a/.github/ISSUE_TEMPLATE/css-issue.yml b/.github/ISSUE_TEMPLATE/css-issue.yml
index db4b23450..e163519e4 100644
--- a/.github/ISSUE_TEMPLATE/css-issue.yml
+++ b/.github/ISSUE_TEMPLATE/css-issue.yml
@@ -78,6 +78,7 @@ body:
- PostCSS Focus Within
- PostCSS Font Variant
- PostCSS Gap Properties
+ - PostCSS Gradients Interpolation Method
- PostCSS HWB Function
- PostCSS Image Set Function
- PostCSS Is Pseudo Class
diff --git a/.github/ISSUE_TEMPLATE/plugin-issue.yml b/.github/ISSUE_TEMPLATE/plugin-issue.yml
index 65d72e7ec..232d12552 100644
--- a/.github/ISSUE_TEMPLATE/plugin-issue.yml
+++ b/.github/ISSUE_TEMPLATE/plugin-issue.yml
@@ -80,6 +80,7 @@ body:
- PostCSS Focus Within
- PostCSS Font Variant
- PostCSS Gap Properties
+ - PostCSS Gradients Interpolation Method
- PostCSS HWB Function
- PostCSS Image Set Function
- PostCSS Is Pseudo Class
diff --git a/.github/labeler.yml b/.github/labeler.yml
index c6b0a09e8..0515bea69 100644
--- a/.github/labeler.yml
+++ b/.github/labeler.yml
@@ -95,6 +95,10 @@
- plugins/postcss-gap-properties/**
- experimental/postcss-gap-properties/**
+"plugins/postcss-gradients-interpolation-method":
+ - plugins/postcss-gradients-interpolation-method/**
+ - experimental/postcss-gradients-interpolation-method/**
+
"plugins/postcss-hwb-function":
- plugins/postcss-hwb-function/**
- experimental/postcss-hwb-function/**
diff --git a/plugins/postcss-progressive-custom-properties/CHANGELOG.md b/plugins/postcss-progressive-custom-properties/CHANGELOG.md
index 30e7fce78..d06d9aa1a 100644
--- a/plugins/postcss-progressive-custom-properties/CHANGELOG.md
+++ b/plugins/postcss-progressive-custom-properties/CHANGELOG.md
@@ -1,5 +1,9 @@
# Changes to PostCSS Progressive Custom Properties
+## Unreleased (patch)
+
+- fix matching rules for gradient functions
+
## 1.2.0 (February 15, 2022)
- More matching rules for [double position gradients](https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-double-position-gradients#readme).
From b7b18252f341b891d52bf27b56d3e0d6d19aa9b2 Mon Sep 17 00:00:00 2001
From: romainmenke
Date: Fri, 4 Mar 2022 17:30:53 +0100
Subject: [PATCH 4/8] lint
---
.../package.json | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/plugins/postcss-gradients-interpolation-method/package.json b/plugins/postcss-gradients-interpolation-method/package.json
index 083d26d4d..0927ccd11 100644
--- a/plugins/postcss-gradients-interpolation-method/package.json
+++ b/plugins/postcss-gradients-interpolation-method/package.json
@@ -23,13 +23,13 @@
"README.md",
"dist"
],
+ "peerDependencies": {
+ "postcss": "^8.3"
+ },
"devDependencies": {
"@csstools/postcss-progressive-custom-properties": "^1.1.0",
"postcss-value-parser": "^4.2.0"
},
- "peerDependencies": {
- "postcss": "^8.3"
- },
"scripts": {
"build": "rollup -c ../../rollup/default.js",
"clean": "node -e \"fs.rmSync('./dist', { recursive: true, force: true });\"",
@@ -38,16 +38,17 @@
"lint:eslint": "eslint ./src --ext .js --ext .ts --ext .mjs --no-error-on-unmatched-pattern",
"lint:package-json": "node ../../.github/bin/format-package-json.mjs",
"prepublishOnly": "npm run clean && npm run build && npm run test",
- "stryker": "stryker run --logLevel error",
"test": "node .tape.mjs && npm run test:exports",
"test:exports": "node ./test/_import.mjs && node ./test/_require.cjs",
"test:rewrite-expects": "REWRITE_EXPECTS=true node .tape.mjs"
},
+ "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-gradients-interpolation-method#readme",
"repository": {
"type": "git",
"url": "https://github.com/csstools/postcss-plugins.git",
"directory": "plugins/postcss-gradients-interpolation-method"
},
+ "bugs": "https://github.com/csstools/postcss-plugins/issues",
"keywords": [
"color",
"conic",
@@ -69,7 +70,5 @@
},
"volta": {
"extends": "../../package.json"
- },
- "homepage": "https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-gradients-interpolation-method#readme",
- "bugs": "https://github.com/csstools/postcss-plugins/issues"
+ }
}
From ed34ffa141f4380ffdececeffd7e131fe44344fa Mon Sep 17 00:00:00 2001
From: romainmenke
Date: Fri, 4 Mar 2022 17:37:49 +0100
Subject: [PATCH 5/8] fixes
---
.../test/progressive-custom-properties.expect.css | 4 ++--
.../postcss-double-position-gradients/test/basic.expect.css | 4 ++--
.../test/generated-value-cases.preserve.expect.css | 2 +-
plugins/postcss-gradients-interpolation-method/docs/README.md | 2 ++
4 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/plugin-packs/postcss-preset-env/test/progressive-custom-properties.expect.css b/plugin-packs/postcss-preset-env/test/progressive-custom-properties.expect.css
index 28ec998dd..d821fd15c 100644
--- a/plugin-packs/postcss-preset-env/test/progressive-custom-properties.expect.css
+++ b/plugin-packs/postcss-preset-env/test/progressive-custom-properties.expect.css
@@ -10,7 +10,7 @@
--hwb: rgb(230, 93, 26);
}
-@supports (background: linear-gradient(0deg, red 0% 1%, red 2%)) {
+@supports (background: linear-gradient(red 0%, red 0% 1%, red 2%)) {
:root {
--gradient-prop-2: linear-gradient(90deg, black 25% 50%, blue 50% 75%);
}
@@ -28,7 +28,7 @@
}
}
-@supports (background: repeating-linear-gradient(0deg, red 0% 1%, red 2%)) {
+@supports (background: repeating-linear-gradient(red 0%, red 0% 1%, red 2%)) {
:root {
--gradient-prop-5: repeating-linear-gradient(90deg, black 25% 50%, blue 50% 75%);
}
diff --git a/plugins/postcss-double-position-gradients/test/basic.expect.css b/plugins/postcss-double-position-gradients/test/basic.expect.css
index 0ac977529..8c1fd5883 100644
--- a/plugins/postcss-double-position-gradients/test/basic.expect.css
+++ b/plugins/postcss-double-position-gradients/test/basic.expect.css
@@ -57,7 +57,7 @@
--gradient-prop-6: repeating-radial-gradient(red 0,red 8%, yellow 8%,yellow 16%, blue 16%, blue 24%);
}
-@supports (background: linear-gradient(0deg, red 0% 1%, red 2%)) {
+@supports (background: linear-gradient(red 0%, red 0% 1%, red 2%)) {
.test-all-functions-as-custom-properties {
--gradient-prop-2: linear-gradient(90deg, black 25% 50%, blue 50% 75%);
}
@@ -75,7 +75,7 @@
}
}
-@supports (background: repeating-linear-gradient(0deg, red 0% 1%, red 2%)) {
+@supports (background: repeating-linear-gradient(red 0%, red 0% 1%, red 2%)) {
.test-all-functions-as-custom-properties {
--gradient-prop-5: repeating-linear-gradient(90deg, black 25% 50%, blue 50% 75%);
}
diff --git a/plugins/postcss-double-position-gradients/test/generated-value-cases.preserve.expect.css b/plugins/postcss-double-position-gradients/test/generated-value-cases.preserve.expect.css
index 9c27ce70e..c3b151099 100644
--- a/plugins/postcss-double-position-gradients/test/generated-value-cases.preserve.expect.css
+++ b/plugins/postcss-double-position-gradients/test/generated-value-cases.preserve.expect.css
@@ -24,7 +24,7 @@
--some-var: linear-gradient(90deg, black 25%,black 50%, blue 50%, blue 75%);
}
-@supports (background: linear-gradient(0deg, red 0% 1%, red 2%)) {
+@supports (background: linear-gradient(red 0%, red 0% 1%, red 2%)) {
:root {
--some-var: linear-gradient(90deg, black 25% 50%, blue 50% 75%);
}
diff --git a/plugins/postcss-gradients-interpolation-method/docs/README.md b/plugins/postcss-gradients-interpolation-method/docs/README.md
index 5c1cd934d..c45ee57f7 100644
--- a/plugins/postcss-gradients-interpolation-method/docs/README.md
+++ b/plugins/postcss-gradients-interpolation-method/docs/README.md
@@ -16,6 +16,8 @@
[] lets you use different interpolation methods in CSS gradient functions following [CSS Specification].
+⚠️ This plugin assumes you have a separate plugin to transform `color-mix()` to something older browsers can understand.
+
```pcss
From 15c70e93b2b4d798d5e1f108c4a5da5219914ed7 Mon Sep 17 00:00:00 2001
From: romainmenke
Date: Fri, 4 Mar 2022 17:44:59 +0100
Subject: [PATCH 6/8] fixes
---
.../src/color-stop-list.ts | 13 +++++++------
.../test/basic.css | 3 ++-
.../test/basic.expect.css | 5 +++--
3 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/plugins/postcss-gradients-interpolation-method/src/color-stop-list.ts b/plugins/postcss-gradients-interpolation-method/src/color-stop-list.ts
index 7d7d1ba70..a0064b59f 100644
--- a/plugins/postcss-gradients-interpolation-method/src/color-stop-list.ts
+++ b/plugins/postcss-gradients-interpolation-method/src/color-stop-list.ts
@@ -1,4 +1,5 @@
import type { Node } from 'postcss-value-parser';
+import valueParser from 'postcss-value-parser';
export type ColorStop = {
color: string;
@@ -46,14 +47,14 @@ export function colorStopList(nodes: Array, interpolationArguments: string
case 1:
return false;
case 2:
- stop.color = stop.nodes[0].value;
- stop.colorStopLength = stop.nodes[1].value;
+ stop.color = valueParser.stringify(stop.nodes[0]);
+ stop.colorStopLength = valueParser.stringify(stop.nodes[1]);
formattedStops.push(stop);
break;
case 3:
formattedStops.push({
- color: stop.nodes[0].value,
- colorStopLength: stop.nodes[1].value,
+ color: valueParser.stringify(stop.nodes[0]),
+ colorStopLength: valueParser.stringify(stop.nodes[1]),
colorHintBetween: [],
nodes: [
stop.nodes[0],
@@ -62,8 +63,8 @@ export function colorStopList(nodes: Array, interpolationArguments: string
});
formattedStops.push({
- color: stop.nodes[0].value,
- colorStopLength: stop.nodes[2].value,
+ color: valueParser.stringify(stop.nodes[0]),
+ colorStopLength: valueParser.stringify(stop.nodes[2]),
colorHintBetween: [],
nodes: [
stop.nodes[0],
diff --git a/plugins/postcss-gradients-interpolation-method/test/basic.css b/plugins/postcss-gradients-interpolation-method/test/basic.css
index 671ea5033..89b791fd5 100644
--- a/plugins/postcss-gradients-interpolation-method/test/basic.css
+++ b/plugins/postcss-gradients-interpolation-method/test/basic.css
@@ -1,5 +1,6 @@
.test-linear-gradient {
- background-image: linear-gradient(in oklch 90deg, black 25% 50%,blue 70% 75%);
+ --perc-50: 50%;
+ background-image: linear-gradient(in oklch 90deg, black 20% var(--perc-50),blue 70% 75%);
background-image: linear-gradient(in oklch shorter 90deg, black 25% 50%, blue 70% 75%);
diff --git a/plugins/postcss-gradients-interpolation-method/test/basic.expect.css b/plugins/postcss-gradients-interpolation-method/test/basic.expect.css
index 28d75d89d..bf0dc5fc4 100644
--- a/plugins/postcss-gradients-interpolation-method/test/basic.expect.css
+++ b/plugins/postcss-gradients-interpolation-method/test/basic.expect.css
@@ -1,6 +1,7 @@
.test-linear-gradient {
- background-image: linear-gradient(90deg ,black 25%,black 50%,color-mix(in oklch, black 90%, blue 10%) calc(50% + ((70% - 50%) * 0.1)),color-mix(in oklch, black 80%, blue 20%) calc(50% + ((70% - 50%) * 0.2)),color-mix(in oklch, black 70%, blue 30%) calc(50% + ((70% - 50%) * 0.3)),color-mix(in oklch, black 60%, blue 40%) calc(50% + ((70% - 50%) * 0.4)),color-mix(in oklch, black 50%, blue 50%) calc(50% + ((70% - 50%) * 0.5)),color-mix(in oklch, black 40%, blue 60%) calc(50% + ((70% - 50%) * 0.6)),color-mix(in oklch, black 30%, blue 70%) calc(50% + ((70% - 50%) * 0.7)),color-mix(in oklch, black 20%, blue 80%) calc(50% + ((70% - 50%) * 0.8)),color-mix(in oklch, black 10%, blue 90%) calc(50% + ((70% - 50%) * 0.9)),blue 70%,blue 75%);
- background-image: linear-gradient(in oklch 90deg, black 25% 50%,blue 70% 75%);
+ --perc-50: 50%;
+ background-image: linear-gradient(90deg ,black 20%,black var(--perc-50),color-mix(in oklch, black 90%, blue 10%) calc(var(--perc-50) + ((70% - var(--perc-50)) * 0.1)),color-mix(in oklch, black 80%, blue 20%) calc(var(--perc-50) + ((70% - var(--perc-50)) * 0.2)),color-mix(in oklch, black 70%, blue 30%) calc(var(--perc-50) + ((70% - var(--perc-50)) * 0.3)),color-mix(in oklch, black 60%, blue 40%) calc(var(--perc-50) + ((70% - var(--perc-50)) * 0.4)),color-mix(in oklch, black 50%, blue 50%) calc(var(--perc-50) + ((70% - var(--perc-50)) * 0.5)),color-mix(in oklch, black 40%, blue 60%) calc(var(--perc-50) + ((70% - var(--perc-50)) * 0.6)),color-mix(in oklch, black 30%, blue 70%) calc(var(--perc-50) + ((70% - var(--perc-50)) * 0.7)),color-mix(in oklch, black 20%, blue 80%) calc(var(--perc-50) + ((70% - var(--perc-50)) * 0.8)),color-mix(in oklch, black 10%, blue 90%) calc(var(--perc-50) + ((70% - var(--perc-50)) * 0.9)),blue 70%,blue 75%);
+ background-image: linear-gradient(in oklch 90deg, black 20% var(--perc-50),blue 70% 75%);
background-image: linear-gradient(90deg ,black 25%,black 50%,color-mix(in oklch shorter, black 90%, blue 10%) calc(50% + ((70% - 50%) * 0.1)),color-mix(in oklch shorter, black 80%, blue 20%) calc(50% + ((70% - 50%) * 0.2)),color-mix(in oklch shorter, black 70%, blue 30%) calc(50% + ((70% - 50%) * 0.3)),color-mix(in oklch shorter, black 60%, blue 40%) calc(50% + ((70% - 50%) * 0.4)),color-mix(in oklch shorter, black 50%, blue 50%) calc(50% + ((70% - 50%) * 0.5)),color-mix(in oklch shorter, black 40%, blue 60%) calc(50% + ((70% - 50%) * 0.6)),color-mix(in oklch shorter, black 30%, blue 70%) calc(50% + ((70% - 50%) * 0.7)),color-mix(in oklch shorter, black 20%, blue 80%) calc(50% + ((70% - 50%) * 0.8)),color-mix(in oklch shorter, black 10%, blue 90%) calc(50% + ((70% - 50%) * 0.9)),blue 70%,blue 75%);
From eab8a1085b4bee2fc8441a4e1cd4210b70db9a04 Mon Sep 17 00:00:00 2001
From: romainmenke
Date: Fri, 4 Mar 2022 17:50:34 +0100
Subject: [PATCH 7/8] more docs
---
.../README.md | 19 +++++++++++++++++
.../docs/README.md | 21 +++++++++++++++++--
2 files changed, 38 insertions(+), 2 deletions(-)
diff --git a/plugins/postcss-gradients-interpolation-method/README.md b/plugins/postcss-gradients-interpolation-method/README.md
index 6b4041a49..fbb284fd8 100644
--- a/plugins/postcss-gradients-interpolation-method/README.md
+++ b/plugins/postcss-gradients-interpolation-method/README.md
@@ -34,6 +34,25 @@
}
```
+## Warnings
+
+⚠️ This plugin assumes you have a separate plugin to transform `color-mix()` to something older browsers can understand.
+
+⚠️ Color stops with only a color and Interpolation hints are not supported.
+We can not statically check if a certain value is a single color or an interpolation hint.
+
+These are equivalent in PostCSS :
+
+```pcss
+ --red: red;
+ /* Color stop variable */
+ background-image: linear-gradient(90deg, black, var(--red), blue);
+
+ --perc-10: 10%;
+ /* Interpolation hint */
+ background-image: linear-gradient(90deg, black, var(--perc-10), blue);
+```
+
## Usage
Add [PostCSS Gradients Interpolation Method] to your project:
diff --git a/plugins/postcss-gradients-interpolation-method/docs/README.md b/plugins/postcss-gradients-interpolation-method/docs/README.md
index c45ee57f7..8b73bbe47 100644
--- a/plugins/postcss-gradients-interpolation-method/docs/README.md
+++ b/plugins/postcss-gradients-interpolation-method/docs/README.md
@@ -16,8 +16,6 @@
[] lets you use different interpolation methods in CSS gradient functions following [CSS Specification].
-⚠️ This plugin assumes you have a separate plugin to transform `color-mix()` to something older browsers can understand.
-
```pcss
@@ -26,6 +24,25 @@
```
+## Warnings
+
+⚠️ This plugin assumes you have a separate plugin to transform `color-mix()` to something older browsers can understand.
+
+⚠️ Color stops with only a color and Interpolation hints are not supported.
+We can not statically check if a certain value is a single color or an interpolation hint.
+
+These are equivalent in PostCSS :
+
+```pcss
+ --red: red;
+ /* Color stop variable */
+ background-image: linear-gradient(90deg, black, var(--red), blue);
+
+ --perc-10: 10%;
+ /* Interpolation hint */
+ background-image: linear-gradient(90deg, black, var(--perc-10), blue);
+```
+
From b2a65211e4aa57d299ad0b24ea1c9beee5ac848a Mon Sep 17 00:00:00 2001
From: romainmenke
Date: Fri, 4 Mar 2022 18:01:16 +0100
Subject: [PATCH 8/8] more tests
---
.../.tape.mjs | 15 +++++++++
.../test/basic.preserve-false.expect.css | 22 +++++++++++++
...preserve-true.progressive-false.expect.css | 31 +++++++++++++++++++
3 files changed, 68 insertions(+)
create mode 100644 plugins/postcss-gradients-interpolation-method/test/basic.preserve-false.expect.css
create mode 100644 plugins/postcss-gradients-interpolation-method/test/basic.preserve-true.progressive-false.expect.css
diff --git a/plugins/postcss-gradients-interpolation-method/.tape.mjs b/plugins/postcss-gradients-interpolation-method/.tape.mjs
index 0a038cc7a..7f4807561 100644
--- a/plugins/postcss-gradients-interpolation-method/.tape.mjs
+++ b/plugins/postcss-gradients-interpolation-method/.tape.mjs
@@ -6,6 +6,21 @@ postcssTape(plugin)({
message: "supports basic usage",
warnings: 2,
},
+ 'basic:preserve-false': {
+ message: 'supports { preserve: false } usage',
+ warnings: 2,
+ options: {
+ preserve: false
+ }
+ },
+ 'basic:preserve-true:progressive-false': {
+ message: 'supports { preserve: true, enableProgressiveCustomProperties: false } usage',
+ warnings: 2,
+ options: {
+ preserve: true,
+ enableProgressiveCustomProperties: false,
+ }
+ },
'examples/example': {
message: 'minimal example',
},
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
new file mode 100644
index 000000000..cc2536073
--- /dev/null
+++ b/plugins/postcss-gradients-interpolation-method/test/basic.preserve-false.expect.css
@@ -0,0 +1,22 @@
+.test-linear-gradient {
+ --perc-50: 50%;
+ background-image: linear-gradient(90deg ,black 20%,black var(--perc-50),color-mix(in oklch, black 90%, blue 10%) calc(var(--perc-50) + ((70% - var(--perc-50)) * 0.1)),color-mix(in oklch, black 80%, blue 20%) calc(var(--perc-50) + ((70% - var(--perc-50)) * 0.2)),color-mix(in oklch, black 70%, blue 30%) calc(var(--perc-50) + ((70% - var(--perc-50)) * 0.3)),color-mix(in oklch, black 60%, blue 40%) calc(var(--perc-50) + ((70% - var(--perc-50)) * 0.4)),color-mix(in oklch, black 50%, blue 50%) calc(var(--perc-50) + ((70% - var(--perc-50)) * 0.5)),color-mix(in oklch, black 40%, blue 60%) calc(var(--perc-50) + ((70% - var(--perc-50)) * 0.6)),color-mix(in oklch, black 30%, blue 70%) calc(var(--perc-50) + ((70% - var(--perc-50)) * 0.7)),color-mix(in oklch, black 20%, blue 80%) calc(var(--perc-50) + ((70% - var(--perc-50)) * 0.8)),color-mix(in oklch, black 10%, blue 90%) calc(var(--perc-50) + ((70% - var(--perc-50)) * 0.9)),blue 70%,blue 75%);
+
+ background-image: linear-gradient(90deg ,black 25%,black 50%,color-mix(in oklch shorter, black 90%, blue 10%) calc(50% + ((70% - 50%) * 0.1)),color-mix(in oklch shorter, black 80%, blue 20%) calc(50% + ((70% - 50%) * 0.2)),color-mix(in oklch shorter, black 70%, blue 30%) calc(50% + ((70% - 50%) * 0.3)),color-mix(in oklch shorter, black 60%, blue 40%) calc(50% + ((70% - 50%) * 0.4)),color-mix(in oklch shorter, black 50%, blue 50%) calc(50% + ((70% - 50%) * 0.5)),color-mix(in oklch shorter, black 40%, blue 60%) calc(50% + ((70% - 50%) * 0.6)),color-mix(in oklch shorter, black 30%, blue 70%) calc(50% + ((70% - 50%) * 0.7)),color-mix(in oklch shorter, black 20%, blue 80%) calc(50% + ((70% - 50%) * 0.8)),color-mix(in oklch shorter, black 10%, blue 90%) calc(50% + ((70% - 50%) * 0.9)),blue 70%,blue 75%);
+
+ --red: red;
+ /* Color stop variable */
+ background-image: linear-gradient(in oklch 90deg, black, var(--red), blue);
+ --perc-10: 10%;
+ /* Interpolation hint */
+ background-image: linear-gradient(in oklch 90deg, black, var(--perc-10), blue);
+}
+
+:root {
+ --gradient-prop-1: conic-gradient(yellowgreen 0deg,color-mix(in oklch, yellowgreen 90%, gold 10%) calc(0deg + ((15deg - 0deg) * 0.1)),color-mix(in oklch, yellowgreen 80%, gold 20%) calc(0deg + ((15deg - 0deg) * 0.2)),color-mix(in oklch, yellowgreen 70%, gold 30%) calc(0deg + ((15deg - 0deg) * 0.3)),color-mix(in oklch, yellowgreen 60%, gold 40%) calc(0deg + ((15deg - 0deg) * 0.4)),color-mix(in oklch, yellowgreen 50%, gold 50%) calc(0deg + ((15deg - 0deg) * 0.5)),color-mix(in oklch, yellowgreen 40%, gold 60%) calc(0deg + ((15deg - 0deg) * 0.6)),color-mix(in oklch, yellowgreen 30%, gold 70%) calc(0deg + ((15deg - 0deg) * 0.7)),color-mix(in oklch, yellowgreen 20%, gold 80%) calc(0deg + ((15deg - 0deg) * 0.8)),color-mix(in oklch, yellowgreen 10%, gold 90%) calc(0deg + ((15deg - 0deg) * 0.9)),gold 15deg,gold 50deg,color-mix(in oklch, gold 90%, #f06 10%) calc(50deg + ((180deg - 50deg) * 0.1)),color-mix(in oklch, gold 80%, #f06 20%) calc(50deg + ((180deg - 50deg) * 0.2)),color-mix(in oklch, gold 70%, #f06 30%) calc(50deg + ((180deg - 50deg) * 0.3)),color-mix(in oklch, gold 60%, #f06 40%) calc(50deg + ((180deg - 50deg) * 0.4)),color-mix(in oklch, gold 50%, #f06 50%) calc(50deg + ((180deg - 50deg) * 0.5)),color-mix(in oklch, gold 40%, #f06 60%) calc(50deg + ((180deg - 50deg) * 0.6)),color-mix(in oklch, gold 30%, #f06 70%) calc(50deg + ((180deg - 50deg) * 0.7)),color-mix(in oklch, gold 20%, #f06 80%) calc(50deg + ((180deg - 50deg) * 0.8)),color-mix(in oklch, gold 10%, #f06 90%) calc(50deg + ((180deg - 50deg) * 0.9)),#f06 180deg);
+ --gradient-prop-2: linear-gradient(90deg ,black 25%,color-mix(in oklch, black 90%, red 10%) calc(25% + ((45% - 25%) * 0.1)),color-mix(in oklch, black 80%, red 20%) calc(25% + ((45% - 25%) * 0.2)),color-mix(in oklch, black 70%, red 30%) calc(25% + ((45% - 25%) * 0.3)),color-mix(in oklch, black 60%, red 40%) calc(25% + ((45% - 25%) * 0.4)),color-mix(in oklch, black 50%, red 50%) calc(25% + ((45% - 25%) * 0.5)),color-mix(in oklch, black 40%, red 60%) calc(25% + ((45% - 25%) * 0.6)),color-mix(in oklch, black 30%, red 70%) calc(25% + ((45% - 25%) * 0.7)),color-mix(in oklch, black 20%, red 80%) calc(25% + ((45% - 25%) * 0.8)),color-mix(in oklch, black 10%, red 90%) calc(25% + ((45% - 25%) * 0.9)),red 45%,color-mix(in oklch, red 90%, blue 10%) calc(45% + ((50% - 45%) * 0.1)),color-mix(in oklch, red 80%, blue 20%) calc(45% + ((50% - 45%) * 0.2)),color-mix(in oklch, red 70%, blue 30%) calc(45% + ((50% - 45%) * 0.3)),color-mix(in oklch, red 60%, blue 40%) calc(45% + ((50% - 45%) * 0.4)),color-mix(in oklch, red 50%, blue 50%) calc(45% + ((50% - 45%) * 0.5)),color-mix(in oklch, red 40%, blue 60%) calc(45% + ((50% - 45%) * 0.6)),color-mix(in oklch, red 30%, blue 70%) calc(45% + ((50% - 45%) * 0.7)),color-mix(in oklch, red 20%, blue 80%) calc(45% + ((50% - 45%) * 0.8)),color-mix(in oklch, red 10%, blue 90%) calc(45% + ((50% - 45%) * 0.9)),blue 50%,blue 75%);
+ --gradient-prop-3: radial-gradient(cyan 0%,color-mix(in oklch, cyan 90%, transparent 10%) calc(0% + ((20% - 0%) * 0.1)),color-mix(in oklch, cyan 80%, transparent 20%) calc(0% + ((20% - 0%) * 0.2)),color-mix(in oklch, cyan 70%, transparent 30%) calc(0% + ((20% - 0%) * 0.3)),color-mix(in oklch, cyan 60%, transparent 40%) calc(0% + ((20% - 0%) * 0.4)),color-mix(in oklch, cyan 50%, transparent 50%) calc(0% + ((20% - 0%) * 0.5)),color-mix(in oklch, cyan 40%, transparent 60%) calc(0% + ((20% - 0%) * 0.6)),color-mix(in oklch, cyan 30%, transparent 70%) calc(0% + ((20% - 0%) * 0.7)),color-mix(in oklch, cyan 20%, transparent 80%) calc(0% + ((20% - 0%) * 0.8)),color-mix(in oklch, cyan 10%, transparent 90%) calc(0% + ((20% - 0%) * 0.9)),transparent 20%,transparent 30%,color-mix(in oklch, transparent 90%, salmon 10%) calc(30% + ((40% - 30%) * 0.1)),color-mix(in oklch, transparent 80%, salmon 20%) calc(30% + ((40% - 30%) * 0.2)),color-mix(in oklch, transparent 70%, salmon 30%) calc(30% + ((40% - 30%) * 0.3)),color-mix(in oklch, transparent 60%, salmon 40%) calc(30% + ((40% - 30%) * 0.4)),color-mix(in oklch, transparent 50%, salmon 50%) calc(30% + ((40% - 30%) * 0.5)),color-mix(in oklch, transparent 40%, salmon 60%) calc(30% + ((40% - 30%) * 0.6)),color-mix(in oklch, transparent 30%, salmon 70%) calc(30% + ((40% - 30%) * 0.7)),color-mix(in oklch, transparent 20%, salmon 80%) calc(30% + ((40% - 30%) * 0.8)),color-mix(in oklch, transparent 10%, salmon 90%) calc(30% + ((40% - 30%) * 0.9)),salmon 40%);
+ --gradient-prop-4: repeating-conic-gradient(from 0deg ,yellowgreen 40deg,color-mix(in oklch, yellowgreen 90%, gold 10%) calc(40deg + ((60deg - 40deg) * 0.1)),color-mix(in oklch, yellowgreen 80%, gold 20%) calc(40deg + ((60deg - 40deg) * 0.2)),color-mix(in oklch, yellowgreen 70%, gold 30%) calc(40deg + ((60deg - 40deg) * 0.3)),color-mix(in oklch, yellowgreen 60%, gold 40%) calc(40deg + ((60deg - 40deg) * 0.4)),color-mix(in oklch, yellowgreen 50%, gold 50%) calc(40deg + ((60deg - 40deg) * 0.5)),color-mix(in oklch, yellowgreen 40%, gold 60%) calc(40deg + ((60deg - 40deg) * 0.6)),color-mix(in oklch, yellowgreen 30%, gold 70%) calc(40deg + ((60deg - 40deg) * 0.7)),color-mix(in oklch, yellowgreen 20%, gold 80%) calc(40deg + ((60deg - 40deg) * 0.8)),color-mix(in oklch, yellowgreen 10%, gold 90%) calc(40deg + ((60deg - 40deg) * 0.9)),gold 60deg,gold 75deg,color-mix(in oklch, gold 90%, #f06 10%) calc(75deg + ((0deg - 75deg) * 0.1)),color-mix(in oklch, gold 80%, #f06 20%) calc(75deg + ((0deg - 75deg) * 0.2)),color-mix(in oklch, gold 70%, #f06 30%) calc(75deg + ((0deg - 75deg) * 0.3)),color-mix(in oklch, gold 60%, #f06 40%) calc(75deg + ((0deg - 75deg) * 0.4)),color-mix(in oklch, gold 50%, #f06 50%) calc(75deg + ((0deg - 75deg) * 0.5)),color-mix(in oklch, gold 40%, #f06 60%) calc(75deg + ((0deg - 75deg) * 0.6)),color-mix(in oklch, gold 30%, #f06 70%) calc(75deg + ((0deg - 75deg) * 0.7)),color-mix(in oklch, gold 20%, #f06 80%) calc(75deg + ((0deg - 75deg) * 0.8)),color-mix(in oklch, gold 10%, #f06 90%) calc(75deg + ((0deg - 75deg) * 0.9)),#f06 0deg);
+ --gradient-prop-5: repeating-linear-gradient(90deg ,black 25%,black 50%,color-mix(in oklch, black 90%, blue 10%) calc(50% + ((50% - 50%) * 0.1)),color-mix(in oklch, black 80%, blue 20%) calc(50% + ((50% - 50%) * 0.2)),color-mix(in oklch, black 70%, blue 30%) calc(50% + ((50% - 50%) * 0.3)),color-mix(in oklch, black 60%, blue 40%) calc(50% + ((50% - 50%) * 0.4)),color-mix(in oklch, black 50%, blue 50%) calc(50% + ((50% - 50%) * 0.5)),color-mix(in oklch, black 40%, blue 60%) calc(50% + ((50% - 50%) * 0.6)),color-mix(in oklch, black 30%, blue 70%) calc(50% + ((50% - 50%) * 0.7)),color-mix(in oklch, black 20%, blue 80%) calc(50% + ((50% - 50%) * 0.8)),color-mix(in oklch, black 10%, blue 90%) calc(50% + ((50% - 50%) * 0.9)),blue 50%,blue 75%);
+ --gradient-prop-6: repeating-radial-gradient(red 0,red 8%,color-mix(in oklch, red 90%, yellow 10%) calc(8% + ((8% - 8%) * 0.1)),color-mix(in oklch, red 80%, yellow 20%) calc(8% + ((8% - 8%) * 0.2)),color-mix(in oklch, red 70%, yellow 30%) calc(8% + ((8% - 8%) * 0.3)),color-mix(in oklch, red 60%, yellow 40%) calc(8% + ((8% - 8%) * 0.4)),color-mix(in oklch, red 50%, yellow 50%) calc(8% + ((8% - 8%) * 0.5)),color-mix(in oklch, red 40%, yellow 60%) calc(8% + ((8% - 8%) * 0.6)),color-mix(in oklch, red 30%, yellow 70%) calc(8% + ((8% - 8%) * 0.7)),color-mix(in oklch, red 20%, yellow 80%) calc(8% + ((8% - 8%) * 0.8)),color-mix(in oklch, red 10%, yellow 90%) calc(8% + ((8% - 8%) * 0.9)),yellow 8%,yellow 16%,color-mix(in oklch, yellow 90%, blue 10%) calc(16% + ((16% - 16%) * 0.1)),color-mix(in oklch, yellow 80%, blue 20%) calc(16% + ((16% - 16%) * 0.2)),color-mix(in oklch, yellow 70%, blue 30%) calc(16% + ((16% - 16%) * 0.3)),color-mix(in oklch, yellow 60%, blue 40%) calc(16% + ((16% - 16%) * 0.4)),color-mix(in oklch, yellow 50%, blue 50%) calc(16% + ((16% - 16%) * 0.5)),color-mix(in oklch, yellow 40%, blue 60%) calc(16% + ((16% - 16%) * 0.6)),color-mix(in oklch, yellow 30%, blue 70%) calc(16% + ((16% - 16%) * 0.7)),color-mix(in oklch, yellow 20%, blue 80%) calc(16% + ((16% - 16%) * 0.8)),color-mix(in oklch, yellow 10%, blue 90%) calc(16% + ((16% - 16%) * 0.9)),blue 16%,blue 24%);
+}
diff --git a/plugins/postcss-gradients-interpolation-method/test/basic.preserve-true.progressive-false.expect.css b/plugins/postcss-gradients-interpolation-method/test/basic.preserve-true.progressive-false.expect.css
new file mode 100644
index 000000000..b4c915411
--- /dev/null
+++ b/plugins/postcss-gradients-interpolation-method/test/basic.preserve-true.progressive-false.expect.css
@@ -0,0 +1,31 @@
+.test-linear-gradient {
+ --perc-50: 50%;
+ background-image: linear-gradient(90deg ,black 20%,black var(--perc-50),color-mix(in oklch, black 90%, blue 10%) calc(var(--perc-50) + ((70% - var(--perc-50)) * 0.1)),color-mix(in oklch, black 80%, blue 20%) calc(var(--perc-50) + ((70% - var(--perc-50)) * 0.2)),color-mix(in oklch, black 70%, blue 30%) calc(var(--perc-50) + ((70% - var(--perc-50)) * 0.3)),color-mix(in oklch, black 60%, blue 40%) calc(var(--perc-50) + ((70% - var(--perc-50)) * 0.4)),color-mix(in oklch, black 50%, blue 50%) calc(var(--perc-50) + ((70% - var(--perc-50)) * 0.5)),color-mix(in oklch, black 40%, blue 60%) calc(var(--perc-50) + ((70% - var(--perc-50)) * 0.6)),color-mix(in oklch, black 30%, blue 70%) calc(var(--perc-50) + ((70% - var(--perc-50)) * 0.7)),color-mix(in oklch, black 20%, blue 80%) calc(var(--perc-50) + ((70% - var(--perc-50)) * 0.8)),color-mix(in oklch, black 10%, blue 90%) calc(var(--perc-50) + ((70% - var(--perc-50)) * 0.9)),blue 70%,blue 75%);
+ background-image: linear-gradient(in oklch 90deg, black 20% var(--perc-50),blue 70% 75%);
+
+ background-image: linear-gradient(90deg ,black 25%,black 50%,color-mix(in oklch shorter, black 90%, blue 10%) calc(50% + ((70% - 50%) * 0.1)),color-mix(in oklch shorter, black 80%, blue 20%) calc(50% + ((70% - 50%) * 0.2)),color-mix(in oklch shorter, black 70%, blue 30%) calc(50% + ((70% - 50%) * 0.3)),color-mix(in oklch shorter, black 60%, blue 40%) calc(50% + ((70% - 50%) * 0.4)),color-mix(in oklch shorter, black 50%, blue 50%) calc(50% + ((70% - 50%) * 0.5)),color-mix(in oklch shorter, black 40%, blue 60%) calc(50% + ((70% - 50%) * 0.6)),color-mix(in oklch shorter, black 30%, blue 70%) calc(50% + ((70% - 50%) * 0.7)),color-mix(in oklch shorter, black 20%, blue 80%) calc(50% + ((70% - 50%) * 0.8)),color-mix(in oklch shorter, black 10%, blue 90%) calc(50% + ((70% - 50%) * 0.9)),blue 70%,blue 75%);
+
+ background-image: linear-gradient(in oklch shorter 90deg, black 25% 50%, blue 70% 75%);
+
+ --red: red;
+ /* Color stop variable */
+ background-image: linear-gradient(in oklch 90deg, black, var(--red), blue);
+ --perc-10: 10%;
+ /* Interpolation hint */
+ background-image: linear-gradient(in oklch 90deg, black, var(--perc-10), blue);
+}
+
+:root {
+ --gradient-prop-1: conic-gradient(yellowgreen 0deg,color-mix(in oklch, yellowgreen 90%, gold 10%) calc(0deg + ((15deg - 0deg) * 0.1)),color-mix(in oklch, yellowgreen 80%, gold 20%) calc(0deg + ((15deg - 0deg) * 0.2)),color-mix(in oklch, yellowgreen 70%, gold 30%) calc(0deg + ((15deg - 0deg) * 0.3)),color-mix(in oklch, yellowgreen 60%, gold 40%) calc(0deg + ((15deg - 0deg) * 0.4)),color-mix(in oklch, yellowgreen 50%, gold 50%) calc(0deg + ((15deg - 0deg) * 0.5)),color-mix(in oklch, yellowgreen 40%, gold 60%) calc(0deg + ((15deg - 0deg) * 0.6)),color-mix(in oklch, yellowgreen 30%, gold 70%) calc(0deg + ((15deg - 0deg) * 0.7)),color-mix(in oklch, yellowgreen 20%, gold 80%) calc(0deg + ((15deg - 0deg) * 0.8)),color-mix(in oklch, yellowgreen 10%, gold 90%) calc(0deg + ((15deg - 0deg) * 0.9)),gold 15deg,gold 50deg,color-mix(in oklch, gold 90%, #f06 10%) calc(50deg + ((180deg - 50deg) * 0.1)),color-mix(in oklch, gold 80%, #f06 20%) calc(50deg + ((180deg - 50deg) * 0.2)),color-mix(in oklch, gold 70%, #f06 30%) calc(50deg + ((180deg - 50deg) * 0.3)),color-mix(in oklch, gold 60%, #f06 40%) calc(50deg + ((180deg - 50deg) * 0.4)),color-mix(in oklch, gold 50%, #f06 50%) calc(50deg + ((180deg - 50deg) * 0.5)),color-mix(in oklch, gold 40%, #f06 60%) calc(50deg + ((180deg - 50deg) * 0.6)),color-mix(in oklch, gold 30%, #f06 70%) calc(50deg + ((180deg - 50deg) * 0.7)),color-mix(in oklch, gold 20%, #f06 80%) calc(50deg + ((180deg - 50deg) * 0.8)),color-mix(in oklch, gold 10%, #f06 90%) calc(50deg + ((180deg - 50deg) * 0.9)),#f06 180deg);
+ --gradient-prop-1: conic-gradient(in oklch, yellowgreen 0deg, gold 15deg, gold 50deg, #f06 180deg);
+ --gradient-prop-2: linear-gradient(90deg ,black 25%,color-mix(in oklch, black 90%, red 10%) calc(25% + ((45% - 25%) * 0.1)),color-mix(in oklch, black 80%, red 20%) calc(25% + ((45% - 25%) * 0.2)),color-mix(in oklch, black 70%, red 30%) calc(25% + ((45% - 25%) * 0.3)),color-mix(in oklch, black 60%, red 40%) calc(25% + ((45% - 25%) * 0.4)),color-mix(in oklch, black 50%, red 50%) calc(25% + ((45% - 25%) * 0.5)),color-mix(in oklch, black 40%, red 60%) calc(25% + ((45% - 25%) * 0.6)),color-mix(in oklch, black 30%, red 70%) calc(25% + ((45% - 25%) * 0.7)),color-mix(in oklch, black 20%, red 80%) calc(25% + ((45% - 25%) * 0.8)),color-mix(in oklch, black 10%, red 90%) calc(25% + ((45% - 25%) * 0.9)),red 45%,color-mix(in oklch, red 90%, blue 10%) calc(45% + ((50% - 45%) * 0.1)),color-mix(in oklch, red 80%, blue 20%) calc(45% + ((50% - 45%) * 0.2)),color-mix(in oklch, red 70%, blue 30%) calc(45% + ((50% - 45%) * 0.3)),color-mix(in oklch, red 60%, blue 40%) calc(45% + ((50% - 45%) * 0.4)),color-mix(in oklch, red 50%, blue 50%) calc(45% + ((50% - 45%) * 0.5)),color-mix(in oklch, red 40%, blue 60%) calc(45% + ((50% - 45%) * 0.6)),color-mix(in oklch, red 30%, blue 70%) calc(45% + ((50% - 45%) * 0.7)),color-mix(in oklch, red 20%, blue 80%) calc(45% + ((50% - 45%) * 0.8)),color-mix(in oklch, red 10%, blue 90%) calc(45% + ((50% - 45%) * 0.9)),blue 50%,blue 75%);
+ --gradient-prop-2: linear-gradient(in oklch 90deg, black 25%, red 45%, blue 50% 75%);
+ --gradient-prop-3: radial-gradient(cyan 0%,color-mix(in oklch, cyan 90%, transparent 10%) calc(0% + ((20% - 0%) * 0.1)),color-mix(in oklch, cyan 80%, transparent 20%) calc(0% + ((20% - 0%) * 0.2)),color-mix(in oklch, cyan 70%, transparent 30%) calc(0% + ((20% - 0%) * 0.3)),color-mix(in oklch, cyan 60%, transparent 40%) calc(0% + ((20% - 0%) * 0.4)),color-mix(in oklch, cyan 50%, transparent 50%) calc(0% + ((20% - 0%) * 0.5)),color-mix(in oklch, cyan 40%, transparent 60%) calc(0% + ((20% - 0%) * 0.6)),color-mix(in oklch, cyan 30%, transparent 70%) calc(0% + ((20% - 0%) * 0.7)),color-mix(in oklch, cyan 20%, transparent 80%) calc(0% + ((20% - 0%) * 0.8)),color-mix(in oklch, cyan 10%, transparent 90%) calc(0% + ((20% - 0%) * 0.9)),transparent 20%,transparent 30%,color-mix(in oklch, transparent 90%, salmon 10%) calc(30% + ((40% - 30%) * 0.1)),color-mix(in oklch, transparent 80%, salmon 20%) calc(30% + ((40% - 30%) * 0.2)),color-mix(in oklch, transparent 70%, salmon 30%) calc(30% + ((40% - 30%) * 0.3)),color-mix(in oklch, transparent 60%, salmon 40%) calc(30% + ((40% - 30%) * 0.4)),color-mix(in oklch, transparent 50%, salmon 50%) calc(30% + ((40% - 30%) * 0.5)),color-mix(in oklch, transparent 40%, salmon 60%) calc(30% + ((40% - 30%) * 0.6)),color-mix(in oklch, transparent 30%, salmon 70%) calc(30% + ((40% - 30%) * 0.7)),color-mix(in oklch, transparent 20%, salmon 80%) calc(30% + ((40% - 30%) * 0.8)),color-mix(in oklch, transparent 10%, salmon 90%) calc(30% + ((40% - 30%) * 0.9)),salmon 40%);
+ --gradient-prop-3: radial-gradient(in oklch, cyan 0%, transparent 20% 30%, salmon 40%);
+ --gradient-prop-4: repeating-conic-gradient(from 0deg ,yellowgreen 40deg,color-mix(in oklch, yellowgreen 90%, gold 10%) calc(40deg + ((60deg - 40deg) * 0.1)),color-mix(in oklch, yellowgreen 80%, gold 20%) calc(40deg + ((60deg - 40deg) * 0.2)),color-mix(in oklch, yellowgreen 70%, gold 30%) calc(40deg + ((60deg - 40deg) * 0.3)),color-mix(in oklch, yellowgreen 60%, gold 40%) calc(40deg + ((60deg - 40deg) * 0.4)),color-mix(in oklch, yellowgreen 50%, gold 50%) calc(40deg + ((60deg - 40deg) * 0.5)),color-mix(in oklch, yellowgreen 40%, gold 60%) calc(40deg + ((60deg - 40deg) * 0.6)),color-mix(in oklch, yellowgreen 30%, gold 70%) calc(40deg + ((60deg - 40deg) * 0.7)),color-mix(in oklch, yellowgreen 20%, gold 80%) calc(40deg + ((60deg - 40deg) * 0.8)),color-mix(in oklch, yellowgreen 10%, gold 90%) calc(40deg + ((60deg - 40deg) * 0.9)),gold 60deg,gold 75deg,color-mix(in oklch, gold 90%, #f06 10%) calc(75deg + ((0deg - 75deg) * 0.1)),color-mix(in oklch, gold 80%, #f06 20%) calc(75deg + ((0deg - 75deg) * 0.2)),color-mix(in oklch, gold 70%, #f06 30%) calc(75deg + ((0deg - 75deg) * 0.3)),color-mix(in oklch, gold 60%, #f06 40%) calc(75deg + ((0deg - 75deg) * 0.4)),color-mix(in oklch, gold 50%, #f06 50%) calc(75deg + ((0deg - 75deg) * 0.5)),color-mix(in oklch, gold 40%, #f06 60%) calc(75deg + ((0deg - 75deg) * 0.6)),color-mix(in oklch, gold 30%, #f06 70%) calc(75deg + ((0deg - 75deg) * 0.7)),color-mix(in oklch, gold 20%, #f06 80%) calc(75deg + ((0deg - 75deg) * 0.8)),color-mix(in oklch, gold 10%, #f06 90%) calc(75deg + ((0deg - 75deg) * 0.9)),#f06 0deg);
+ --gradient-prop-4: repeating-conic-gradient(in oklch from 0deg, yellowgreen 40deg, gold 60deg 75deg, #f06 0deg);
+ --gradient-prop-5: repeating-linear-gradient(90deg ,black 25%,black 50%,color-mix(in oklch, black 90%, blue 10%) calc(50% + ((50% - 50%) * 0.1)),color-mix(in oklch, black 80%, blue 20%) calc(50% + ((50% - 50%) * 0.2)),color-mix(in oklch, black 70%, blue 30%) calc(50% + ((50% - 50%) * 0.3)),color-mix(in oklch, black 60%, blue 40%) calc(50% + ((50% - 50%) * 0.4)),color-mix(in oklch, black 50%, blue 50%) calc(50% + ((50% - 50%) * 0.5)),color-mix(in oklch, black 40%, blue 60%) calc(50% + ((50% - 50%) * 0.6)),color-mix(in oklch, black 30%, blue 70%) calc(50% + ((50% - 50%) * 0.7)),color-mix(in oklch, black 20%, blue 80%) calc(50% + ((50% - 50%) * 0.8)),color-mix(in oklch, black 10%, blue 90%) calc(50% + ((50% - 50%) * 0.9)),blue 50%,blue 75%);
+ --gradient-prop-5: repeating-linear-gradient(in oklch 90deg, black 25% 50%, blue 50% 75%);
+ --gradient-prop-6: repeating-radial-gradient(red 0,red 8%,color-mix(in oklch, red 90%, yellow 10%) calc(8% + ((8% - 8%) * 0.1)),color-mix(in oklch, red 80%, yellow 20%) calc(8% + ((8% - 8%) * 0.2)),color-mix(in oklch, red 70%, yellow 30%) calc(8% + ((8% - 8%) * 0.3)),color-mix(in oklch, red 60%, yellow 40%) calc(8% + ((8% - 8%) * 0.4)),color-mix(in oklch, red 50%, yellow 50%) calc(8% + ((8% - 8%) * 0.5)),color-mix(in oklch, red 40%, yellow 60%) calc(8% + ((8% - 8%) * 0.6)),color-mix(in oklch, red 30%, yellow 70%) calc(8% + ((8% - 8%) * 0.7)),color-mix(in oklch, red 20%, yellow 80%) calc(8% + ((8% - 8%) * 0.8)),color-mix(in oklch, red 10%, yellow 90%) calc(8% + ((8% - 8%) * 0.9)),yellow 8%,yellow 16%,color-mix(in oklch, yellow 90%, blue 10%) calc(16% + ((16% - 16%) * 0.1)),color-mix(in oklch, yellow 80%, blue 20%) calc(16% + ((16% - 16%) * 0.2)),color-mix(in oklch, yellow 70%, blue 30%) calc(16% + ((16% - 16%) * 0.3)),color-mix(in oklch, yellow 60%, blue 40%) calc(16% + ((16% - 16%) * 0.4)),color-mix(in oklch, yellow 50%, blue 50%) calc(16% + ((16% - 16%) * 0.5)),color-mix(in oklch, yellow 40%, blue 60%) calc(16% + ((16% - 16%) * 0.6)),color-mix(in oklch, yellow 30%, blue 70%) calc(16% + ((16% - 16%) * 0.7)),color-mix(in oklch, yellow 20%, blue 80%) calc(16% + ((16% - 16%) * 0.8)),color-mix(in oklch, yellow 10%, blue 90%) calc(16% + ((16% - 16%) * 0.9)),blue 16%,blue 24%);
+ --gradient-prop-6: repeating-radial-gradient(in oklch, red 0 8%, yellow 8% 16%, blue 16% 24%);
+}