Re: [csswg-drafts] [css-selectors] Improve the usefulness of specificity of Tags & IDs (#4690)

Hi Jen and others!

I know this thread is closed already, but I don’t find a place where to put my suggestion on how CSS specificity could be calculated to solve a lot of scope problems. We all know the problem when an precise selector (THIS camel is blue) loses against some selector somewhere else (animals on THIS planet are green).

My suggestion: Instead of calculating a singular specificity for a CSS selector, the specificity should be calculated regarding the DOM element it is matching with. (How specific does the selector describe the target element.)
When the parser compares the selector and the DOM path of the matching element it could rate all the selector’s parts on the basis of there DOM tree level from the element’s point of view: the further up the ID, class or whatever in the selector, the less it counts (because it covers larger scope which is more unspecific).
An easy to understand calculation could be multiplying the selector part’s rating with 0.1^[DOM tree level difference].

Example:
```
<div id="my-module">
  <ul class="foos">
    <li>Some foo</li>
    <li>A second foo</li>
    <li id="my-foo">My foo</li>
  </ul>
</div>
```
A frequent case is that several selectors match for one element, take the li #my-foo for instance:
```
SELECTOR                                   SPECIFICITY
#my-module ul.foos li { color: blue; }  => 0 - 1 - 1 - 2  (inline - ID - class - style)
#my-foo { color: red; }                 => 0 - 1 - 0 - 0
```
Now #my-foo gets painted blue. Although the first selector doesn’t mention this specific element, it wins over the second selector which actually is more precise.
My suggestion now considers how many DOM tree levels the matching selector’s parts are above the element’s (#my-foo) point of view:
```
#my-module  1 * 0.1^2  = 0.01  (2 levels above)
ul          1 * 0.1^1  = 0.1   (1 level above)
.foos       1 * 0.1^1  = 0.1   (1 level above)
li          1 * 0.1^0  = 1     (0 levels above)
#my-foo     1 * 0.1^0  = 1     (0 levels above)
```
The part values then get summated like in the current CSS calculation. That leads to:
```
#my-module ul.foos li { color: blue; }  => 0.0 - 0.01 - 0.1 - 1.1
#my-foo { color: red; }                 => 0.0 - 1.00 - 0.0 - 0.0

(Redundant decimals here are just for better visibility.)
```
Now the precise second selector wins in the b (ID) section of a-b-c-d like it should be, because it is more specific. Every “closer” (DOM-tree-wise) description would win now.
This would avoid scope leaks, because we now can narrow the scope. All elements of an HTML code block that has an ID (unique) could now get safely styled if their rules start with the code block’s ID.

Regards,
Thomas

-- 
GitHub Notification of comment by ThomasGutmann
Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/4690#issuecomment-1410946189 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Tuesday, 31 January 2023 19:27:15 UTC