Skip to content

Align @10up/stylelint-config with 10up CSS Engineering Best Practices#468

Open
fabiankaegy wants to merge 14 commits intodevelopfrom
feature/update-style-linting-to-match-new-css-guidance
Open

Align @10up/stylelint-config with 10up CSS Engineering Best Practices#468
fabiankaegy wants to merge 14 commits intodevelopfrom
feature/update-style-linting-to-match-new-css-guidance

Conversation

@fabiankaegy
Copy link
Member

@fabiankaegy fabiankaegy commented Jan 21, 2026

Description

This PR updates the @10up/stylelint-config package to fully enforce the 10up CSS Engineering Best Practices. The configuration now includes rules that enforce low specificity, consistent naming conventions, and code quality standards.

Changes

New Rules Added

Specificity Controls:

  • selector-max-specificity: "0,2,1" - Limits selector specificity to maintain low complexity
  • selector-max-id: 0 - Disallows ID selectors for styling (IDs reserved for JS hooks and anchors)
  • max-nesting-depth: 2 - Limits CSS nesting to 2 levels (pseudo-classes excluded)
  • no-descending-specificity: true - Re-enabled to prevent specificity ordering issues

Code Quality:

  • declaration-no-important: true - Disallows !important declarations
  • selector-no-qualifying-type: true - Prevents type selectors qualifying class selectors (e.g., a.button)
  • shorthand-property-no-redundant-values: true - Ensures efficient shorthand property usage

Naming Conventions:

  • selector-class-pattern - Enabled to enforce kebab-case for class names
  • keyframes-name-pattern - Added to enforce kebab-case for animation names

Additional Changes

  • Tests: Added comprehensive test suite covering all new rules with both valid and invalid CSS patterns
  • Documentation: Updated README with detailed explanations of each rule, examples, and override guidance

Breaking Changes

⚠️ This is a minor version bump with potential breaking changes for consuming projects:

Projects using this configuration may need to update existing CSS to comply with:

  • ID selectors are now disallowed for styling
  • Class names must use kebab-case (no camelCase or snake_case)
  • Maximum selector specificity is enforced at 0,2,1
  • Nesting depth is limited to 2 levels
  • !important declarations are disallowed

Migration Guide

Projects can override specific rules if needed:

{
  "extends": ["@10up/stylelint-config"],
  "rules": {
    // Override as needed
    "selector-max-specificity": "0,3,2",
    "declaration-no-important": null
  }
}

Disallows the use of !important in CSS declarations to maintain
better CSS maintainability and reduce specificity issues.

Aligns with 10up CSS best practices.
Enforces kebab-case naming for CSS animation keyframes to maintain
consistent naming conventions across the codebase.

Aligns with 10up CSS best practices.
Limits CSS nesting to a maximum of 2 levels (excluding pseudo-classes)
to maintain low specificity and improve code readability.

Aligns with 10up CSS best practices.
Prevents CSS specificity issues where a less specific selector
comes after a more specific one, which can cause unexpected behavior.

Aligns with 10up CSS best practices.
Enforces kebab-case naming for CSS class selectors to maintain
consistent and readable naming conventions.

Aligns with 10up CSS best practices.
Disallows ID selectors in CSS. IDs should be reserved for JavaScript
hooks and anchor links, not for styling purposes.

Aligns with 10up CSS best practices.
Limits selector specificity to a maximum of 0,2,1 (0 IDs, 2 classes/
attributes, 1 element) to maintain low specificity and improve CSS
maintainability.

Aligns with 10up CSS best practices.
Prevents qualifying class selectors with type selectors (e.g. a.button
should be .button) to reduce specificity and improve selector efficiency.
Attribute selectors are excluded from this rule.

Aligns with 10up CSS best practices.
Ensures shorthand properties don't contain redundant values
(e.g. margin: 10px 10px should be margin: 10px) to write
more efficient CSS.

Aligns with 10up CSS best practices.
Adds test cases covering all newly added rules:
- Specificity limits (selector-max-specificity, selector-max-id, max-nesting-depth)
- Importance rules (declaration-no-important, no-descending-specificity)
- Naming conventions (selector-class-pattern, keyframes-name-pattern)
- Selector quality (selector-no-qualifying-type, shorthand-property-no-redundant-values)

Tests verify both valid and invalid CSS patterns to ensure rules
are properly enforced.
Adds comprehensive documentation explaining how the stylelint
configuration enforces 10up CSS best practices including:

- Low specificity enforcement
- Avoiding !important
- Naming conventions (kebab-case)
- Selector quality rules
- How to override rules when necessary

Provides clear explanations and examples for each enforced principle
to help developers understand the reasoning behind the rules.
@changeset-bot
Copy link

changeset-bot bot commented Jan 21, 2026

🦋 Changeset detected

Latest commit: c51c6df

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@10up/stylelint-config Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@fabiankaegy fabiankaegy changed the title Align @10up/stylelint-config with 10up CSS Engineering Best Practices Align @10up/stylelint-config with 10up CSS Engineering Best Practices Jan 21, 2026
dmtrmrv
dmtrmrv previously approved these changes Jan 21, 2026
Copy link
Contributor

@dmtrmrv dmtrmrv left a comment

Choose a reason for hiding this comment

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

This looks good to me! I assume that this will create some noise in existing projects but if need be the rules can be silenced.

@fabiankaegy
Copy link
Member Author

(I will take a look at the tests and then we will talk about releasing strategy in the next few days / week since we are transitioning who is owning maintenance of toolkit :))

@nicholasio
Copy link
Member

@fabiankaegy, just noting that this is still using classic tokens, and I created one recently, but they expire in 90 days. I will need to change the publishing strategy soon to avoid this issue.

Updates test cases to use valid CSS that complies with all stylelint rules
while still testing the specific rules we want to validate. Uses CSS custom
properties to avoid color value violations and proper formatting to avoid
stylistic rule violations.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

Comments