cssupgrade 0.0.0-stage → 2026.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +22 -0
- package/.editorconfig +27 -0
- package/.gitattributes +1 -0
- package/.github/agents/superjoe.agent.md +65 -0
- package/.github/copilot-instructions.md +32 -0
- package/.github/dependabot.yml +10 -0
- package/.github/workflows/ci.yml +37 -0
- package/.github/workflows/pr.yml +28 -0
- package/.github/workflows/release.yml +22 -0
- package/.oxfmtrc.json +3 -0
- package/.pre-commit-config.yaml +52 -0
- package/.pre-commit-hooks.yaml +8 -0
- package/AGENTS.md +54 -0
- package/CONTRIBUTING.md +40 -0
- package/LICENSE +24 -0
- package/README.md +173 -2
- package/bin/cssupgrade.js +320 -0
- package/images/logo-dark.svg +10 -0
- package/images/logo-light.svg +10 -0
- package/package.json +34 -4
- package/skills/cssupgrade/SKILL.md +16 -0
- package/src/index.js +53 -0
- package/src/newlyAvailable.js +1 -0
- package/src/parser.js +43 -0
- package/src/pool.js +165 -0
- package/src/prefilters.js +29 -0
- package/src/widelyAvailable/cssNesting.js +918 -0
- package/src/widelyAvailable.js +1 -0
- package/src/worker.js +31 -0
- package/tests/baseline.test.js +51 -0
- package/tests/cli.test.js +229 -0
- package/tests/css-nesting.test.js +838 -0
- package/tests/fixtures/silent-worker.js +5 -0
- package/tests/general.test.js +42 -0
- package/tests/parser.test.js +43 -0
- package/tests/pool.test.js +242 -0
- package/tests/prefilters.test.js +24 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cssupgrade",
|
|
3
|
+
"displayName": "CSSupgrade",
|
|
4
|
+
"description": "Auto-upgrade CSS syntax to new features based on browser support.",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "Johannes Maron",
|
|
8
|
+
"email": "security@codingjoe.dev"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/codingjoe/cssupgrade",
|
|
11
|
+
"repository": "https://github.com/codingjoe/cssupgrade",
|
|
12
|
+
"license": "BSD-2-Clause",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"css",
|
|
15
|
+
"modernize",
|
|
16
|
+
"upgrade",
|
|
17
|
+
"codemod",
|
|
18
|
+
"ast",
|
|
19
|
+
"transform",
|
|
20
|
+
"nesting"
|
|
21
|
+
]
|
|
22
|
+
}
|
package/.editorconfig
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# http://editorconfig.org
|
|
2
|
+
|
|
3
|
+
root = true
|
|
4
|
+
|
|
5
|
+
[*]
|
|
6
|
+
indent_style = space
|
|
7
|
+
indent_size = 4
|
|
8
|
+
trim_trailing_whitespace = true
|
|
9
|
+
insert_final_newline = true
|
|
10
|
+
charset = utf-8
|
|
11
|
+
end_of_line = lf
|
|
12
|
+
max_line_length = 88
|
|
13
|
+
|
|
14
|
+
[*.{json,yml,yaml,mjs,js,jsx,vue,toml}]
|
|
15
|
+
indent_size = 2
|
|
16
|
+
ij_javascript_force_semicolon_style = false
|
|
17
|
+
|
|
18
|
+
[*.{html,htm,svg,xml}]
|
|
19
|
+
indent_size = 2
|
|
20
|
+
max_line_length = 120
|
|
21
|
+
|
|
22
|
+
[LICENSE]
|
|
23
|
+
insert_final_newline = false
|
|
24
|
+
|
|
25
|
+
[*.{md,markdown}]
|
|
26
|
+
indent_size = 2
|
|
27
|
+
max_line_length = 80
|
package/.gitattributes
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
package-lock.json linguist-generated
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
# For format details, see: https://gh.io/customagents/config
|
|
3
|
+
|
|
4
|
+
name: SuperJoe
|
|
5
|
+
description: CodingJoe's digital clone following his coding guidelines and best practices.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# SuperJoe
|
|
9
|
+
|
|
10
|
+
## Planning
|
|
11
|
+
|
|
12
|
+
You MUST ALWAYS follow the `naming-things` guidelines. Use the following command to access the guidelines:
|
|
13
|
+
|
|
14
|
+
```console
|
|
15
|
+
curl -sSL https://raw.githubusercontent.com/codingjoe/naming-things/refs/heads/main/README.md | head -n 500
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
You MUST ALWAYS read the `CONTRIBUTING.md` file before planning or writing any code.
|
|
19
|
+
You MUST ALWAYS search the documentation and amend or update it as necessary.
|
|
20
|
+
You MUST ALWAYS check for pre-commit hooks and run them before committing code.
|
|
21
|
+
You MUST ALWAYS ensure that all new code is fully tested with 100% coverage. Unreachable code branches MUST be removed.
|
|
22
|
+
|
|
23
|
+
## Writing Code
|
|
24
|
+
|
|
25
|
+
Less code is more! Use the latest language features and libraries to achieve more with less code.
|
|
26
|
+
|
|
27
|
+
Do not add new dependencies, but if you do, they must be widely adopted and well-maintained in the open-source community.
|
|
28
|
+
|
|
29
|
+
You are a strong FOSS advocate with a preference for permissive licenses like BSD or MIT.
|
|
30
|
+
|
|
31
|
+
Use generators instead of adding items to lists or arrays.
|
|
32
|
+
|
|
33
|
+
Use class syntax for all object-oriented code.
|
|
34
|
+
Use named functions instead of anonymous functions whenever possible.
|
|
35
|
+
Avoid overly complex functions. Break them into smaller functions if necessary.
|
|
36
|
+
Docstrings should be written in present tense imperative mood.
|
|
37
|
+
They must start with a capital letter and end with a period.
|
|
38
|
+
Docstrings must describe the external behavior of the function, class, or method.
|
|
39
|
+
Docstrings should avoid redundant phrases like "This function" or "This method".
|
|
40
|
+
Class docstrings must not repeat the class name or start with a verb since they don't do anything themselves.
|
|
41
|
+
Avoid code comments unless they describe behavior of 3rd party code or complex algorithms.
|
|
42
|
+
Avoid loops in favor of recursive functions or generator functions.
|
|
43
|
+
Avoid functions or other code inside functions.
|
|
44
|
+
Avoid if-statements in favor of switch/match-statements or polymorphism.
|
|
45
|
+
Do not assign names to objects which are returned in the next line.
|
|
46
|
+
|
|
47
|
+
## Python
|
|
48
|
+
|
|
49
|
+
Follow PEP 8 guidelines for code style.
|
|
50
|
+
EAFP (Easier to Ask Forgiveness than Permission) is preferred over LBYL (Look Before You Leap).
|
|
51
|
+
Use type hints for all public functions, classes, and methods.
|
|
52
|
+
Use dataclasses for simple data structures.
|
|
53
|
+
Use context managers for resource management.
|
|
54
|
+
Use list/set/dict comprehensions instead of loops for creating collections.
|
|
55
|
+
Use generators for large data sets to save memory.
|
|
56
|
+
Use the walrus operator (`:=`) for inline assignments when it improves readability.
|
|
57
|
+
|
|
58
|
+
### JavaScript
|
|
59
|
+
|
|
60
|
+
Use `#` for private methods.
|
|
61
|
+
Write docstrings with jsdoc type annotations for all functions, classes, and methods.
|
|
62
|
+
|
|
63
|
+
### TypeScript
|
|
64
|
+
|
|
65
|
+
Use `#` for private methods.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
YOUR PRIORITY IS TO ENSURE THE SAFETY OF ALL TRANSFORMATIONS.
|
|
2
|
+
|
|
3
|
+
When writing code, you MUST ALWAYS follow the [naming guidelines](https://raw.githubusercontent.com/codingjoe/naming-things/refs/heads/main/README.md).
|
|
4
|
+
|
|
5
|
+
Usage:
|
|
6
|
+
|
|
7
|
+
```console
|
|
8
|
+
curl -sL https://raw.githubusercontent.com/codingjoe/naming-things/refs/heads/main/README.md | head -n 500
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
All code must be fully tested with a 100% coverage. Unreachable code must be removed.
|
|
12
|
+
Follow the [CONTRIBUTING.md](./CONTRIBUTING.md) guidelines for testing and linting.
|
|
13
|
+
|
|
14
|
+
All transformers must be documented in the README.md.
|
|
15
|
+
|
|
16
|
+
Use class syntax for all object-oriented code.
|
|
17
|
+
Use named functions instead of anonymous functions whenever possible.
|
|
18
|
+
Use `#` for private methods.
|
|
19
|
+
|
|
20
|
+
Avoid overly complex functions. Break them into smaller functions if necessary.
|
|
21
|
+
|
|
22
|
+
Write docstrings with jsdoc type annotations for all functions, classes, and methods.
|
|
23
|
+
Docstrings should be written in present tense imperative mood.
|
|
24
|
+
They must start with a capital letter and end with a period.
|
|
25
|
+
Docstrings must describe the external behavior of the function, class, or method.
|
|
26
|
+
Docstrings should avoid redundant phrases like "This function" or "This method".
|
|
27
|
+
Class docstrings must not repeat the class name or start with a verb since they don't do anything themselves.
|
|
28
|
+
Avoid code comments unless they describe behavior of 3rd party code or complex algorithms.
|
|
29
|
+
Avoid loops in favor of recursive functions or generator functions.
|
|
30
|
+
Avoid functions or other code inside functions.
|
|
31
|
+
Avoid if-statements in favor of switch-statements or polymorphism.
|
|
32
|
+
Do not assign names to objects which are returned in the next line.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
on:
|
|
3
|
+
push:
|
|
4
|
+
branches:
|
|
5
|
+
- main
|
|
6
|
+
pull_request:
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
jobs:
|
|
10
|
+
readme:
|
|
11
|
+
name: "Word Weasel / README.md"
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
timeout-minutes: 1
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v7
|
|
16
|
+
- id: read_readme
|
|
17
|
+
run: |
|
|
18
|
+
echo "::set-output name=content::$(cat README.md)"
|
|
19
|
+
- uses: codingjoe/word-weasel@v1
|
|
20
|
+
with:
|
|
21
|
+
text: ${{ steps.read_readme.outputs.content }}
|
|
22
|
+
node-test:
|
|
23
|
+
name: Test
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@v7
|
|
27
|
+
- name: Set up Node.js
|
|
28
|
+
uses: actions/setup-node@v7
|
|
29
|
+
with:
|
|
30
|
+
node-version-file: package.json
|
|
31
|
+
- run: npm ci
|
|
32
|
+
- run: npm test
|
|
33
|
+
- uses: codecov/codecov-action@v7
|
|
34
|
+
with:
|
|
35
|
+
token: ${{ secrets.CODECOV_TOKEN }}
|
|
36
|
+
flags: css
|
|
37
|
+
files: lcov.info
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Write better PRs and commit messages
|
|
2
|
+
name: "Word Weasel"
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
types:
|
|
6
|
+
- opened
|
|
7
|
+
- edited
|
|
8
|
+
- reopened
|
|
9
|
+
permissions: {}
|
|
10
|
+
jobs:
|
|
11
|
+
pr-title:
|
|
12
|
+
name: "PR Title"
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
timeout-minutes: 1
|
|
15
|
+
if: ${{ github.actor != 'dependabot[bot]' }}
|
|
16
|
+
steps:
|
|
17
|
+
- uses: codingjoe/word-weasel@v1
|
|
18
|
+
with:
|
|
19
|
+
text: ${{ github.event.pull_request.title }}
|
|
20
|
+
pr-body:
|
|
21
|
+
name: "PR Body"
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
timeout-minutes: 1
|
|
24
|
+
if: ${{ github.actor != 'dependabot[bot]' }}
|
|
25
|
+
steps:
|
|
26
|
+
- uses: codingjoe/word-weasel@v1
|
|
27
|
+
with:
|
|
28
|
+
text: ${{ github.event.pull_request.body }}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
on:
|
|
3
|
+
release:
|
|
4
|
+
types: [published]
|
|
5
|
+
permissions:
|
|
6
|
+
id-token: write
|
|
7
|
+
contents: read
|
|
8
|
+
jobs:
|
|
9
|
+
npmjs:
|
|
10
|
+
name: npmjs.org
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v7
|
|
14
|
+
- uses: actions/setup-node@v7
|
|
15
|
+
with:
|
|
16
|
+
node-version-file: package.json
|
|
17
|
+
registry-url: 'https://registry.npmjs.org'
|
|
18
|
+
- run: npm install -g npm@latest
|
|
19
|
+
- run: npm ci
|
|
20
|
+
- run: npm config set git-tag-version=false
|
|
21
|
+
- run: npm version ${{ github.event.release.tag_name }}
|
|
22
|
+
- run: npm publish
|
package/.oxfmtrc.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: v6.0.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: trailing-whitespace
|
|
6
|
+
- id: check-merge-conflict
|
|
7
|
+
- id: check-json
|
|
8
|
+
- id: check-yaml
|
|
9
|
+
- id: destroyed-symlinks
|
|
10
|
+
- id: check-executables-have-shebangs
|
|
11
|
+
- id: end-of-file-fixer
|
|
12
|
+
- id: no-commit-to-branch
|
|
13
|
+
args: [--branch, main]
|
|
14
|
+
- id: detect-private-key
|
|
15
|
+
- repo: https://github.com/hukkin/mdformat
|
|
16
|
+
rev: 1.0.0
|
|
17
|
+
hooks:
|
|
18
|
+
- id: mdformat
|
|
19
|
+
additional_dependencies:
|
|
20
|
+
- mdformat-config
|
|
21
|
+
- mdformat-footnote
|
|
22
|
+
- mdformat-gfm
|
|
23
|
+
- mdformat-gfm-alerts
|
|
24
|
+
- mdformat-frontmatter
|
|
25
|
+
args: [--number]
|
|
26
|
+
- repo: https://github.com/google/yamlfmt
|
|
27
|
+
rev: v0.21.0
|
|
28
|
+
hooks:
|
|
29
|
+
- id: yamlfmt
|
|
30
|
+
- repo: https://github.com/btford/write-good
|
|
31
|
+
rev: v1.0.8
|
|
32
|
+
hooks:
|
|
33
|
+
- id: write-good
|
|
34
|
+
args: [--no-passive]
|
|
35
|
+
- repo: https://github.com/oxc-project/mirrors-oxlint
|
|
36
|
+
rev: v1.60.0
|
|
37
|
+
hooks:
|
|
38
|
+
- id: oxlint
|
|
39
|
+
- repo: https://github.com/oxc-project/mirrors-oxfmt
|
|
40
|
+
rev: v0.78.0
|
|
41
|
+
hooks:
|
|
42
|
+
- id: oxfmt
|
|
43
|
+
- repo: https://github.com/codingjoe/esupgrade
|
|
44
|
+
rev: 2026.1.2 # Use the latest release
|
|
45
|
+
hooks:
|
|
46
|
+
- id: esupgrade
|
|
47
|
+
ci:
|
|
48
|
+
autoupdate_schedule: weekly
|
|
49
|
+
skip:
|
|
50
|
+
- no-commit-to-branch
|
|
51
|
+
- write-good
|
|
52
|
+
- esupgrade
|
package/AGENTS.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# CSSupgrade
|
|
2
|
+
|
|
3
|
+
The package includes transformers for upgrading CSS syntax.
|
|
4
|
+
|
|
5
|
+
## Categories
|
|
6
|
+
|
|
7
|
+
- [Widely Available](./src/widelyAvailable/): Transformers for features available in all major browsers for at least 30 months.
|
|
8
|
+
- [Newly Available](./src/newlyAvailable/): Transformers for features available in all major browsers for 0-30 months.
|
|
9
|
+
|
|
10
|
+
For a full list of transformations, see [README.md](./README.md).
|
|
11
|
+
|
|
12
|
+
## Package Structure
|
|
13
|
+
|
|
14
|
+
- [bin/](./bin/): Command-line interface script.
|
|
15
|
+
- [src/](./src/): Source code and transformers.
|
|
16
|
+
- [tests/](./tests/): Test suite.
|
|
17
|
+
|
|
18
|
+
For contributing guidelines, see [CONTRIBUTING.md](./CONTRIBUTING.md).
|
|
19
|
+
|
|
20
|
+
## Instructions
|
|
21
|
+
|
|
22
|
+
Use EOF syntax to run node scripts directly from the command line. For example:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
node --input-type=module <<'EOF'
|
|
26
|
+
import { transform } from './src/index.js';
|
|
27
|
+
|
|
28
|
+
const sample = '.a { color: red } .a .b { color: blue }';
|
|
29
|
+
const res = transform(sample);
|
|
30
|
+
console.log('modified:', res.modified);
|
|
31
|
+
console.log('code:\n' + res.code);
|
|
32
|
+
EOF
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Writing Transformers
|
|
36
|
+
|
|
37
|
+
The pipeline parses CSS with `parseCss` from `src/parser.js`, which returns the
|
|
38
|
+
css-tree syntax tree and the ranges of all comments.
|
|
39
|
+
|
|
40
|
+
Every transformer declares a pre-filter in `src/prefilters.js`, so files that
|
|
41
|
+
cannot contain the pattern skip the parse. See [CONTRIBUTING.md](./CONTRIBUTING.md).
|
|
42
|
+
|
|
43
|
+
## Writing Docs
|
|
44
|
+
|
|
45
|
+
### README.md
|
|
46
|
+
|
|
47
|
+
We add one new section per transformation:
|
|
48
|
+
|
|
49
|
+
1. Headline + MDN link
|
|
50
|
+
2. One diff-based example.
|
|
51
|
+
3. Notable exception, which are not transformed.
|
|
52
|
+
|
|
53
|
+
We MUST NOT add any comments about "what it does".
|
|
54
|
+
The functionality documentation is fully covered by the diff-based example.
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
To run tests locally, follow these steps:
|
|
4
|
+
|
|
5
|
+
```console
|
|
6
|
+
npm ci
|
|
7
|
+
npm test
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
We use pre-commit hooks to lint and format code before committing.
|
|
11
|
+
|
|
12
|
+
To install the pre-commit hooks, run:
|
|
13
|
+
|
|
14
|
+
```console
|
|
15
|
+
uvx pre-commit install
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Or instead run the linters once with:
|
|
19
|
+
|
|
20
|
+
```console
|
|
21
|
+
uvx pre-commit run --all-files
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Naming conventions
|
|
25
|
+
|
|
26
|
+
When writing code, please follow the [naming guidelines](https://raw.githubusercontent.com/codingjoe/naming-things/refs/heads/main/README.md).
|
|
27
|
+
|
|
28
|
+
## Baseline release dates
|
|
29
|
+
|
|
30
|
+
The baseline date can be found on
|
|
31
|
+
https://github.com/web-platform-dx/web-features named `baseline_low_date`.
|
|
32
|
+
|
|
33
|
+
## Pre-filters
|
|
34
|
+
|
|
35
|
+
Every transformer needs a pre-filter in `src/prefilters.js` and a sample in
|
|
36
|
+
`tests/prefilters.test.js`. A pre-filter lists conditions on the source text,
|
|
37
|
+
and each condition must be necessary: when the source text misses a condition,
|
|
38
|
+
the transformer cannot change the tree. The test suite transforms every sample
|
|
39
|
+
with and without pre-filters and compares the results, so an unsound condition
|
|
40
|
+
fails the tests.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
BSD 2-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025, Johannes Maron
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
list of conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
|
13
|
+
and/or other materials provided with the distribution.
|
|
14
|
+
|
|
15
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
16
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
17
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
18
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
19
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
20
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
21
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
22
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
23
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
24
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,174 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="./images/logo-dark.svg?v=2">
|
|
4
|
+
<source media="(prefers-color-scheme: light)" srcset="./images/logo-light.svg?v=2">
|
|
5
|
+
<img alt="CSSupgrade: Auto-upgrade your CSS syntax" src="./images/logo-light.svg?v=2">
|
|
6
|
+
</picture>
|
|
7
|
+
</p>
|
|
2
8
|
|
|
3
|
-
|
|
9
|
+
# CSSupgrade [](https://www.npmjs.com/package/cssupgrade) [](https://codecov.io/gh/codingjoe/cssupgrade) [](https://github.com/codingjoe/cssupgrade/blob/main/LICENSE)
|
|
10
|
+
|
|
11
|
+
Keeping your CSS up to date with full browser compatibility.
|
|
12
|
+
|
|
13
|
+
## Sponsors
|
|
14
|
+
|
|
15
|
+
[](https://github.com/sponsors/codingjoe)
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
CSSupgrade is safe and meant to be used automatically on your codebase.
|
|
20
|
+
We recommend integrating it into your development workflow using [pre-commit], [husky], or as an agent skill.
|
|
21
|
+
|
|
22
|
+
### CLI
|
|
23
|
+
|
|
24
|
+
To try it out on a repository without writing changes, run:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npx -y cssupgrade $(git ls-files '*.css')
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
To transform code from standard input, pass `-` as the input path:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
echo '.a { .b { color: red } }' | npx cssupgrade -
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
For help with available options:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npx cssupgrade --help
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### pre-commit
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
uvx pre-commit install
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
```yaml
|
|
49
|
+
# .pre-commit-config.yaml
|
|
50
|
+
repos:
|
|
51
|
+
- repo: https://github.com/codingjoe/cssupgrade
|
|
52
|
+
rev: 2026.1.0 # Use the latest release
|
|
53
|
+
hooks:
|
|
54
|
+
- id: cssupgrade
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
pre-commit run cssupgrade --all-files
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Husky
|
|
62
|
+
|
|
63
|
+
Assuming Husky is already initialized and `.husky/pre-commit` already contains `set -e`, append:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
echo "git diff --cached --name-only --diff-filter=ACMR -z -- '*.css' | xargs -0 sh -c 'test \"\$#\" -eq 0 && exit 0; npx -y cssupgrade --write -- \"\$@\"' sh" >> .husky/pre-commit
|
|
67
|
+
echo "git diff --cached --name-only --diff-filter=ACMR -z -- '*.css' | xargs -0 sh -c 'test \"\$#\" -eq 0 && exit 0; git add -- \"\$@\"' sh" >> .husky/pre-commit
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Agent Skill
|
|
71
|
+
|
|
72
|
+
CSSupgrade is available as a skill in [Claude Code]. The plugin is distributed via the [codingjoe/claude-plugins](https://github.com/codingjoe/claude-plugins) marketplace. To use it:
|
|
73
|
+
|
|
74
|
+
1. Run `/plugin marketplace add codingjoe/claude-plugins`
|
|
75
|
+
2. Run `/plugin install cssupgrade@codingjoe`
|
|
76
|
+
|
|
77
|
+
The skill will analyze your selected styles and suggest transformations based on the Baseline browser support policy.
|
|
78
|
+
|
|
79
|
+
<picture>
|
|
80
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://web-platform-dx.github.io/assets/img/baseline-wordmark-dark.svg">
|
|
81
|
+
<source media="(prefers-color-scheme: light)" srcset="https://web-platform-dx.github.io/assets/img/baseline-wordmark.svg">
|
|
82
|
+
<img alt="Baseline: widely available" src="https://web-platform-dx.github.io/assets/img/baseline-wordmark.svg" height="32" align="right">
|
|
83
|
+
</picture>
|
|
84
|
+
|
|
85
|
+
## Browser Support & Baseline
|
|
86
|
+
|
|
87
|
+
All transformations are based on [Web Platform Baseline][baseline] features. Baseline tracks which web platform features are safe to use across browsers.
|
|
88
|
+
|
|
89
|
+
By default, CSSupgrade uses **widely available** features, meaning they work in all major browsers (Chrome, Edge, Safari, Firefox) for at least 30 months. This ensures full compatibility while keeping your styles modern.
|
|
90
|
+
|
|
91
|
+
You can opt into **newly available** features (available in all browsers for 0-30 months) with:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
npx cssupgrade --baseline newly-available <files>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
For more information about Baseline browser support, visit [web.dev/baseline][baseline].
|
|
98
|
+
|
|
99
|
+
## Supported File Types & Languages
|
|
100
|
+
|
|
101
|
+
- `.css` - CSS stylesheets
|
|
102
|
+
|
|
103
|
+
## Transformations
|
|
104
|
+
|
|
105
|
+
> [!NOTE]
|
|
106
|
+
> A transformation applies only to CSS that the parser accepts. Unknown at-rules
|
|
107
|
+
> and invalid declarations stay unchanged.
|
|
108
|
+
|
|
109
|
+
Rules that cannot nest keep their original text.
|
|
110
|
+
|
|
111
|
+
<picture>
|
|
112
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://web-platform-dx.github.io/assets/img/baseline-widely-word-dark.svg">
|
|
113
|
+
<source media="(prefers-color-scheme: light)" srcset="https://web-platform-dx.github.io/assets/img/baseline-widely-word.svg">
|
|
114
|
+
<img alt="Baseline: widely available" src="https://web-platform-dx.github.io/assets/img/baseline-widely-word.svg" height="32" align="right">
|
|
115
|
+
</picture>
|
|
116
|
+
|
|
117
|
+
### Widely available
|
|
118
|
+
|
|
119
|
+
#### Flat rules → [CSS nesting][mdn-nesting]
|
|
120
|
+
|
|
121
|
+
```diff
|
|
122
|
+
.card {
|
|
123
|
+
padding: 1rem;
|
|
124
|
+
-}
|
|
125
|
+
-.card .title { font-weight: bold; }
|
|
126
|
+
-.card:hover { color: red; }
|
|
127
|
+
+ .title { font-weight: bold; }
|
|
128
|
+
+ &:hover { color: red; }
|
|
129
|
+
+}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Only adjacent rules are nested, so the cascade order stays the same.
|
|
133
|
+
Every child selector must repeat a parent selector, and all parent selectors must have the same specificity.
|
|
134
|
+
Rules inside `@media`, `@supports`, `@container`, `@layer`, `@scope`, and `@starting-style` blocks are nested as well.
|
|
135
|
+
|
|
136
|
+
```css
|
|
137
|
+
/* Not transformed - `@keyframes` children are keyframe selectors */
|
|
138
|
+
@keyframes fade {
|
|
139
|
+
from { opacity: 0 }
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
<picture>
|
|
144
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://web-platform-dx.github.io/assets/img/baseline-newly-word-dark.svg">
|
|
145
|
+
<source media="(prefers-color-scheme: light)" srcset="https://web-platform-dx.github.io/assets/img/baseline-newly-word.svg">
|
|
146
|
+
<img alt="Baseline: Newly available" src="https://web-platform-dx.github.io/assets/img/baseline-newly-word.svg" height="32" align="right">
|
|
147
|
+
</picture>
|
|
148
|
+
|
|
149
|
+
### Newly available
|
|
150
|
+
|
|
151
|
+
No transformations are available yet.
|
|
152
|
+
|
|
153
|
+
## Versioning
|
|
154
|
+
|
|
155
|
+
CSSupgrade uses the [calver] `YYYY.MINOR.PATCH` versioning scheme.
|
|
156
|
+
|
|
157
|
+
The year indicates the baseline version. New transformations are added in minor releases, while patches are reserved for bug fixes.
|
|
158
|
+
|
|
159
|
+
## Related Projects
|
|
160
|
+
|
|
161
|
+
Thanks to [esupgrade] for inspiring CSSupgrade.
|
|
162
|
+
|
|
163
|
+
### Distinction
|
|
164
|
+
|
|
165
|
+
[esupgrade] upgrades JavaScript and TypeScript syntax.
|
|
166
|
+
CSSupgrade applies the same Baseline policy to CSS.
|
|
167
|
+
|
|
168
|
+
[baseline]: https://web.dev/baseline/
|
|
169
|
+
[calver]: https://calver.org/
|
|
170
|
+
[claude code]: https://code.claude.com
|
|
171
|
+
[esupgrade]: https://github.com/codingjoe/esupgrade
|
|
172
|
+
[husky]: https://typicode.github.io/husky/
|
|
173
|
+
[mdn-nesting]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_nesting
|
|
174
|
+
[pre-commit]: https://pre-commit.com/
|