Add stylelint CSS linting - #12934
Conversation
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
|
Nice, given the new |
|
The first run of the css linter job on this PR reports 2746 errors while locally I get 2823 errors. Will look into it. At a first check it appears some files aren't scanned in the job:
|
9d6e06f to
f14b5fb
Compare
|
The bundled themes The one for
Although there are working forks of the Even after making them work, the linting for both themes reports several errors, mostly because of outdated configuration:
It appears the linting scripts of these two themes haven't been used for a long time. Likely, they have been intensively used during the themes development but now they are way behind. Also, bundled themes are part of Core. To me, it makes sense to have a ceentralized tool to lint everything. In the latest commit I added a As said earlier, for now it's best to focus on the functionality. The set of rules can be refined later. It will need some adjustments as some rules aren't applicable in Core, for example |
c0f141a to
b3c8e48
Compare
|
Regarding the a11y rules that were used in twentytwenty, I tried to re-add them to the Core Stylelint configuration by using the compatible stylelint-a11y plugin fork. It's a useful experiment to check a few CSS patterns that are potentially harmful for accessibility:
Among other rules provided by the plugin, this one might be useful: media-prefers-reduced-motion I would suggest to experiment these rules at a later stage, after the initial configuration is proved to be stable and reliable, |
18cae71 to
b4fad4e
Compare
Trac ticket: https://core.trac.wordpress.org/ticket/29792
Work In Progress (WIP) to add Stylelint CSS coding standards rules enforcement to Core.
Documenting the work done so far:
Core
Two new npm scripts are added together with a Grunt task that can be run individually and is also part of
grunt precommit:css. Under the hood, they use thelint-stylewp-script:The linting rules are defined in the
.stylelintrc.jsfile in the root of the project.Paths and files to be excluded are defined in
.stylelintignore.The themes directory is excluded.
Themes
Some bundled themes already have their own Stylelint scripts:
lint:cssas a standalone script that is not part of the build process. Only for.cssfiles. Useslint-stylewp-script.lint:scssandlint-fix:scssfor the.scssfiles. Plus,build:stylelint, which is part of the build process, for the.cssfiles. All the thre scripts usestylelintdirectly.These existing scripts use their own Stylelint configuration. It made sense when these two themes were under development. I think these should be removed in favor of a centralized Stylelint configuration in core that lints also the themes. This PR adds:
They use the same rules defined in the
.stylelintrc.jsfile in the root of the project.Paths to be excluded are defined in
.stylelintignore-themesinstead.Note on the existing config in Twenty Twenty:
The
lint-stylescript from wp-scripts doesn't walk the directory tree upwards to auto-discover a Stylelint configuration. It expects a configuration in the theme's root. Instead, when used directly, Stylelint does. This doesn't allow to use the Core configuration from the theme.Also, Twenty Twenty uses the
stylelint-a11yStylelint 'plugin' to add two lint rules:If the 'ad-hoc' configurations for the two themes get removed in favor of a centralized configuration, these two a11y ruels would be lost. A decision should be made on whether to add them to the centralized configuration.
Rules
The WordPress CSS Coding Standards (more readable in their GitHub page version) are described in a conversational language style and are difficult to summarize point by point. Extracting some of the most important ones to document the related rules.
The rules configuration extends the rules from the
@wordpress/stylelint-config/scss-stylisticone and add or change rules to cover the following points:One blank line between blocks in a section
Each selector should be on its own line
This was tricky to address as some rules conflict. To make sure indentation linting is performed correctly, a specific order of some rules needs to be preserver.
All properties and values should be lowercase, except for font names and vendor-specific properties
@stylistic/property-casevalue-keyword-casewith exceptions forcurrentColorandoptimizeLegibilityAvoid RGB format
'function-disallowed-list': ['rgb']Line height should also be unit-less, unless necessary to be defined as a specific pixel value.
declaration-property-unit-allowed-listwith'line-height': []Font weights should be defined using numeric values
'font-weight-notation': 'numeric'Refrain from using over-qualified selectors, div.container can simply be stated as .container
Right now, there are 1815 violations of this rule in Core. It's a lot. Things like
input[type="text"]or simplya.currentare considered invalid. As such, I added the ruleselector-no-qualifying-typeand changed the severity type towarning. A decision on how to handle these warnings can be made later.Remove multiple spaces between selector combinators
This is not mentioned in the coding standards but I addressed it anyways to cover cases like
.myclass1 .myclass2 {}The added rule is:
'@stylistic/selector-descendant-combinator-no-non-space': true.Recommended changes to the CSS Coding Standards
Similar to the WordPress PHP Coding Standards for file names, use lowercase and separate words with hyphens when naming selectors. Avoid camelcase and underscores.
Gutenberg already uses a BEM-like naming convention that uses underscores for class selectors. Some new selectors recently introduced in core already follow that convention e.g.:
.wp-tooltip__toggle.On the other hand, there are several violations already in core for both class and ID selectors. A few examples:
.ac_match.privacy_requests#login_error#dashboard_right_now#TB_windowAll of these aren't allowed by the current CSS Coding Standarrds. They can't be changed though, because of backward compatibility concerns.
As such, the current recommendation to use hyphens and avoid underscores isn't applicable.
Add two blank lines between sections
This is not doable with Stylelint. The rule
'@stylistic/max-empty-lines': 1cannot distinguish between nprmal comments and section comments. Two blank lines between sections add little value anyways. Suggest to remove this point from the Coding Standards.Long comments should manually break the line length at 80 characters.
@stylistic/max-line-lengthcan be used to set a global maximum line length. It cannot distinguish between lines of code and lines of comments. Either we set a global 80 characters limit or we should use another tool e.g. a custom postcss script to apply the line length limit only to comments. A little overkill to me. We could just decide to not lint it or change this point in the Coding Standards.Property Ordering
All the points in this sections are not enforceable with Stylelint. They can be kept as genereal recommendation but they will always be subject to personal preferences.
Testing
Don't forget to run
npm installbefore testing.For now, it is important to check the following:
npm run lint:cssandgrunt lint:css.Rather than running the linting on the whole codebase with
npm run lint:cssornpm run lint:css:fixI suggest to also start with lintin single files so to get a clearer view of how it works. Start with a small file, for example:npx stylelint src/wp-admin/css/color-picker.cssThen, run the inter with the auto-fix flag:
npx stylelint src/wp-admin/css/color-picker.css --fixThen, try larger files, for example:
As of Core revision 63292, the Stylelint scan reports the following:
Most of these errors are trivial fixes. Running the auto-fix will reduce the errors to 646. They will need to either be manually fixed or have a
stylelint-disablecomment when appropriate.Use of AI Tools
None.
This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.