- From: José Arturo Cano Melani <jose@activisual.net>
- Date: Tue, 12 Aug 2025 11:06:04 -0500
- To: www-style@w3.org
- Message-ID: <CAMfmACHBdAQWCaZ13ar+dCFOG9upUxsnojHN=jYbdDFbXv00hA@mail.gmail.com>
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 Thursday, 14 August 2025 14:04:26 UTC