Re: Proposal: CSS `specificity` Property for Explicit Selector Weight

Hi there,

Please note technical discussion no longer happens in www-style, instead we use this repo: https://github.com/w3c/csswg-drafts/issues/

Regarding controlling specificity, I think you may find :where() useful: https://developer.mozilla.org/en-US/docs/Web/CSS/:where
The idea is that if you wrap the parts of your selector that should not affect specificity with :where(), then you should very rarely need to artificially increase specificity with hacks such as those listed below.

Cheers,
Lea

--
Lea Verou, PhD
Product, web standards, usability, and everything in between
👩🏽 (she/her)

🔗 https://lea.verou.me
🐦 @leaverou





> On Aug 12, 2025, at 19:06, José Arturo Cano Melani <jose@activisual.net> wrote:
> 
> Hi CSSWG,
> 
> I propose a new CSS property, `specificity`, to allow developers to explicitly set a selector's weight, addressing the pain points of the current specificity system that force artificial selector conditions.
> 
> Problem
> -------
> The current CSS specificity system (IDs=100, classes=10, elements=1) often requires developers to use hacks to achieve desired precedence, such as:
> - Repeating classes (e.g., `td.status.status.status` for 0-3-1) to override selectors like `.table td.status` (0-1-1).
> - Adding artificial selectors (e.g., `#dummy`, `.body .table td.status`) to boost specificity.
> - Overusing `!important`, which creates maintenance issues and lacks granularity.
> 
> These practices lead to:
> - Unmaintainable, verbose CSS that obscures intent.
> - Semantic noise from meaningless selector chains.
> - Debugging challenges, as developers must manually calculate specificity scores.
> - Escalating specificity wars in large or legacy codebases.
> 
> Proposed Solution
> -----------------
> Introduce a `specificity` property to set a selector's weight directly:
> 
>   td.status {
>     specificity: 300;
>     border: solid 1px blue;
>   }
> 
> - Value: `<integer>` (non-negative, e.g., 300 = three classes) or `auto` (default, uses traditional specificity).
> - Applies to: All elements.
> - Computed value: As specified.
> - Cascade: Overrides the selector's calculated specificity in the cascade algorithm.
> 
> Examples
> --------
> 1. Override a more specific selector:
>    .table td.status { /* Specificity: 0-1-1 = 110 */
>      border: solid 1px red;
>    }
>    td.status { /* Specificity: 300 */
>      specificity: 300;
>      border: solid 1px blue;
>    }
>    Result: `td.status` wins without hacks like `td.status.status.status`..
> 
> 2. Fine-grained control:
>    td.status { /* Specificity: 200 */
>      specificity: 200;
>      border: solid 1px blue;
>    }
>    .table td.status { /* Specificity: 0-1-1 = 110 */
>      border: solid 1px red;
>    }
>    Result: `td.status` overrides without artificial selectors.
> 
> Benefits
> --------
> - Eliminates hacks like class repetition or dummy IDs.
> - Simplifies debugging by making specificity explicit.
> - Offers precise control without altering selector semantics.
> - Complements `@layer` and `@scope` for comprehensive cascade management.
> 
> Challenges and Mitigations
> -------------------------
> 1. Backward Compatibility:
>    - Default to `auto` for traditional specificity.
>    - Unsupported browsers ignore `specificity`, falling back to standard rules.
>    - Use `@supports` for progressive enhancement.
> 
> 2. Potential Abuse:
>    - Cap maximum value (e.g., 10000) to prevent excessive weights.
>    - Encourage `@layer` for large-scale priority management.
> 
> 3. Implementation:
>    - Treat `specificity` as an override to calculated specificity, applied before cascade resolution.
>    - Display in DevTools alongside traditional specificity scores.
> 
> Integration with Cascade
> -----------------------
> - Sort rules by origin and importance (`!important` vs. non-`!important`).
> - Within each group, use `specificity` property (if set) or traditional specificity.
> - Resolve ties by source order.
> 
> Prior Art
> ---------
> - Issue #5057 (Selector Boundary): Related but focuses on selector matching, not explicit weights.
> - `@layer`: Manages group priority, not individual selectors.
> - `:is()`/`:where()`: Adjusts specificity indirectly, not numerically.
> 
> Call to Action
> --------------
> I propose adding `specificity` to CSS Cascade Level 6 or a new spec. Seeking feedback on:
> - Syntax (`specificity` vs. `weight`/`rule_weight`).
> - Interaction with `@layer`, `@scope`, and `!important`.
> - Implementation feasibility and browser concerns.
> 
> 
> Thanks,
> Jose A. Cano
> 
> P.S. I’m sharing this on X and DEV Community to gather developer feedback. Suggestions welcome!

Received on Monday, 18 August 2025 10:38:22 UTC