Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
f75fdfe
First pass at adding a stylelint script.
afercia Aug 6, 2026
d3b5f72
Remove custom rule from gutenberg.
afercia Aug 6, 2026
3c92e31
Clean up stylelintignore.
afercia Aug 6, 2026
0373528
Clean up config.
afercia Aug 6, 2026
7021245
Add Grunt task and clean up.
afercia Aug 7, 2026
e950a5b
Remove stylelint-config-wordpress package.
afercia Aug 7, 2026
9dee5b3
Ignore admin color scheme auto generated files.
afercia Aug 8, 2026
61d1313
Ignore files copied to wp-includes js.
afercia Aug 8, 2026
5b38b15
Remove Stylelint configuration from Twenty Twenty theme.
afercia Aug 9, 2026
ba8c7ec
Remove Stylelint configuration from Twenty Twenty-One theme.
afercia Aug 9, 2026
8264a7d
Remove comments.
afercia Aug 9, 2026
bbfefbd
Add lint:css:themes script for bundled themes.
afercia Aug 9, 2026
0ff2efe
Build theme files.
afercia Aug 9, 2026
3ee935a
Use the root stylelintrc for twentytwentyone.
afercia Aug 9, 2026
1cab9fb
For twentytwentyone try adding a postcss script and run it twice.
afercia Aug 10, 2026
4a4598d
Start refining rules.
afercia Aug 10, 2026
96ceaa0
Add rules for empty lines before.
afercia Aug 10, 2026
51250c3
Solve the indentation and leading space issues avoiding to run postcs…
afercia Aug 10, 2026
cd671ed
Improve comment-empty-line-before.
afercia Aug 10, 2026
2c912e6
Improve comment.
afercia Aug 10, 2026
edfc735
Improve selector-list-comma-space-after.
afercia Aug 10, 2026
7dbc41e
Refine empty libe before rule.
afercia Aug 11, 2026
6b11ce5
Add selector-no-qualifying-type warning.
afercia Aug 11, 2026
276faed
Refine more rules.
afercia Aug 11, 2026
a5a0238
Improve order of rules related to indentation.
afercia Aug 11, 2026
fbbaf14
Reduce max-empty-lines to 1.
afercia Aug 11, 2026
4f74f53
Disable comment-empty-line-before.
afercia Aug 11, 2026
3914149
Run stylelint directly so that it walks upwards until it finds the ro…
afercia Aug 11, 2026
6585fdf
Update test-and-zip-default-themes gh action.
afercia Aug 11, 2026
902f287
Add bacl @wordpress/scripts to twentytwentyone.
afercia Aug 11, 2026
5096419
Add stylelint-plugin-logical-css to twentytwentyone.
afercia Aug 11, 2026
45e54e3
Update twentytwentyone styles.
afercia Aug 11, 2026
ad0fe03
Pass the glob as a quoted pattern.
afercia Aug 11, 2026
6beb1cd
Add optimizeLegibility to value-keyword-case exceptions.
afercia Aug 12, 2026
e96609a
Add @stylistic/selector-descendant-combinator-no-non-space true.
afercia Aug 12, 2026
7d07a9f
Adjust a few rules.
afercia Aug 17, 2026
c75a315
Ignore dashicons font-family.
afercia Aug 17, 2026
51923e4
Apply a few minor JS coding standards to stylelintrc.js.
afercia Aug 17, 2026
13ce60d
Try warnings threshold mechanism.
afercia Aug 19, 2026
08f8657
Normalize the glob path for Windows on CI.
afercia Aug 19, 2026
c19ca2f
Increase warnings threshold.
afercia Sep 5, 2026
2174d46
Remove all changes related to themes.
afercia Sep 11, 2026
b283dcc
Align threshold with current trunk.
afercia Sep 23, 2026
07e5fd8
Build/Test Tools: Use Stylelint bulk suppressions as the CSS baseline.
lancewillett Sep 23, 2026
d4c7b23
Build/Test Tools: Treat the Stylelint config files as configuration i…
lancewillett Sep 23, 2026
fb0d728
Make the class selector pattern match the current coding standards.
afercia Sep 28, 2026
e87de52
Revert changes to css files.
afercia Sep 28, 2026
e312de0
Upgrade sylelint and stylelint-plugin-logical-css versions.
afercia Sep 28, 2026
efd3c93
Checkout latest css changes from trunk.
afercia Sep 29, 2026
9742529
Update Stylelint suppressions list.
afercia Sep 29, 2026
2deae6d
Rebase and update suppressions list.
afercia Oct 2, 2026
17d3864
Address part of CR.
afercia Oct 2, 2026
31ebec9
Add lint:css:update-suppressions script.
afercia Oct 2, 2026
fa968e2
Improve error message and add instructions.
afercia Oct 5, 2026
6ffd6f7
Decrease suppressions count.
afercia Oct 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .stylelintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Ignore WordPress plugin files.
src/wp-content/plugins/**/*

# Ignore WordPress theme files.
src/wp-content/themes/**/*

# Ignore WordPress block files.
src/wp-includes/blocks/**/*

# Ignore admin color schemes auto generated files.
src/wp-admin/css/colors/*/*.css

# Ignore WordPress included dist files.
src/wp-includes/css/dist/**/*

# Ignore files copied to wp-includes js.
src/wp-includes/js/**/*

# Ignore WordPress JS vendor files.
src/js/_enqueues/vendor/**/*

# Ignore minified CSS files.
**/*.min.css

# Ignore RTL CSS files.
**/*-rtl.css
**/*-rtl.min.css
106 changes: 106 additions & 0 deletions .stylelintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/** @type {import('stylelint').Config} */
module.exports = {
extends: '@wordpress/stylelint-config/scss-stylistic',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The stylistic configs used in Gutenberg's config were used for backwards compatibility. Stylelint v16 removed all stylistic rules (rules to do with formatting instead of linting errors), but before that point, they were included in the base recommended stylelint config.

Stylelint's stylistic rules directly conflict with Prettier which also applies formatting to CSS files. If we're adding Stylelint rules where ones were not present before, I would recommend using the base config for your extends (@wordpress/stylelint-config/scss) which doesn't contain any stylistic rules, and keep Prettier as the source of truth for formatting.

Alternatively, you could make Stylelint the source of truth for formatting CSS files and disable Prettier for CSS.

I believe there are some small rules which Stylelint implements which Prettier will not (lines between selectors being the one I can think of off the top of my head) so imo the best approach would be to use the scss config and then specifically add any rules you need from the stylistic config explicitly.

I am looking to create an issue/PR to do the same in the Gutenberg config as and when I have time for the same reasons, I just haven't gotten around to it yet.

You can consider this a suggestion, if you want to move forward with your PR anyway, don't consider me a blocker 👍

plugins: [
'stylelint-plugin-logical-css',
'@wordpress/theme/stylelint-plugins/no-token-fallback-values',
],
reportNeedlessDisables: true,
rules: {
'at-rule-empty-line-before': [
'always',
{
except: [ 'blockless-after-blockless' ],
ignore: [ 'first-nested', 'after-comment' ],
},
],
'at-rule-no-unknown': null,
'comment-empty-line-before': null,
'declaration-property-unit-allowed-list': [
{
'line-height': [],
},
],
'declaration-property-value-allowed-list': [
{
'flex-direction': '/^(?!(row|column)-reverse).*$/',
},
{
message: ( property, value ) =>
`Avoid "${ value }" value for the "${ property }" property. For accessibility reasons, visual, reading, and DOM order must match. Only use the reverse values when they do not affect reading order, meaning, and interaction.`,
},
],
'font-family-no-missing-generic-family-keyword': [
true,
{
ignoreFontFamilies: [ 'dashicons' ],
},
],
'font-weight-notation': 'numeric',
'function-disallowed-list': [ 'rgb' ],
'no-descending-specificity': null,
'no-invalid-position-at-import-rule': null,
'property-disallowed-list': [
[ 'order' ],
{
message:
'Avoid the order property. For accessibility reasons, visual, reading, and DOM order must match. Only use the order property when it does not affect reading order, meaning, and interaction.',
},
],
'rule-empty-line-before': [
'always',
{
except: [ 'first-nested' ],
ignore: [ 'after-comment' ],
},
],
'selector-class-pattern': [
'^([a-z][a-z0-9]*)(-[a-z0-9]+)*$',
{
message:
'Class selector should use lowercase and separate words with hyphens',
},
],
'selector-id-pattern': [
'^([a-z][a-z0-9]*)(-[a-z0-9]+)*$',
{
message:
'ID selector should use lowercase and separate words with hyphens',
},
],
'selector-no-qualifying-type': true,
'value-keyword-case': [
'lower',
{
ignoreKeywords: [
'currentColor',
'optimizeLegibility',
],
},
],
'scss/at-else-empty-line-before': null,
'scss/at-extend-no-missing-placeholder': null,
'scss/at-if-closing-brace-newline-after': null,
'scss/at-if-closing-brace-space-after': null,
'scss/comment-no-empty': null,
'scss/load-partial-extension': null,
'scss/no-global-function-names': null,
'scss/operator-no-newline-after': null,
'scss/operator-no-unspaced': null,
'scss/selector-no-redundant-nesting-selector': null,
'@stylistic/max-empty-lines': 1,
'@stylistic/max-line-length': null,
'@stylistic/selector-descendant-combinator-no-non-space': true,
// Keep these lines. Don't change their order otherwise indentation will break.
// It's not about a literal 'execution order', but rather a compatibility issue.
'@stylistic/block-closing-brace-newline-before': 'always',
'@stylistic/block-opening-brace-newline-after': 'always',
'@stylistic/declaration-block-semicolon-newline-after': 'always',
'@stylistic/selector-list-comma-space-after': 'always-single-line',
'@stylistic/selector-list-comma-newline-after': 'always',
'@stylistic/declaration-colon-newline-after': 'always-multi-line',
'@stylistic/indentation': 'tab',
// End keep these lines.
},
reportDescriptionlessDisables: true,
};
17 changes: 15 additions & 2 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -1823,8 +1823,21 @@ module.exports = function(grunt) {
'qunit:compiled'
] );

grunt.registerTask( 'lint:css', 'Runs Stylelint on core CSS.', function() {
var done = this.async();

grunt.util.spawn( {
cmd: 'node',
args: [ 'tools/stylelint/lint-css.js' ],
opts: { stdio: 'inherit' }
}, function( error ) {
done( ! error );
} );
} );

grunt.registerTask( 'precommit:css', [
'postcss:core'
'postcss:core',
'lint:css',
] );

grunt.registerTask( 'precommit:php', [
Expand Down Expand Up @@ -1921,7 +1934,7 @@ module.exports = function(grunt) {
}

if ( code === 0 ) {
if ( [ 'package.json', 'Gruntfile.js', 'composer.json' ].some( testPath ) ) {
if ( [ 'package.json', 'Gruntfile.js', 'composer.json', '.stylelintrc.js', '.stylelintignore' ].some( testPath ) ) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing the Stylelint config triggers the full prerelease here (PHP formatting, JS, CSS, images) when precommit:css would be enough. stylelint-suppressions.json isn't in the list either, so editing only the suppressions file runs no lint locally.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added by @lancewillett in 71bcf1a yes, worth considering adding stylelint-suppressions.json.

grunt.log.writeln( 'Configuration files modified. Running `prerelease`.' );
taskList.push( 'prerelease' );
} else {
Expand Down
Loading
Loading