- From: Lea Verou <lea@verou.me>
- Date: Mon, 18 Aug 2025 13:38:05 +0300
- To: José Arturo Cano Melani <jose@activisual.net>
- Cc: www-style list <www-style@w3.org>
- Message-Id: <D388746D-0777-469F-941F-8AC971269085@verou.me>
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