Computed style inspector 'best match' is wrong
Categories
(DevTools :: Inspector, defect, P2)
Tracking
(firefox68 fixed)
| Tracking | Status | |
|---|---|---|
| firefox68 | --- | fixed |
People
(Reporter: temhawk, Assigned: miker)
References
Details
(Whiteboard: [dt-q])
Attachments
(3 files)
Updated•7 years ago
|
| Assignee | ||
Updated•7 years ago
|
| Assignee | ||
Updated•6 years ago
|
| Assignee | ||
Comment 2•6 years ago
|
||
The first question we need to ask here is how the weighting is calculated... the hierarchy looks like this:
<header style="color: #FF0000 !important">
<a href="#" style="color: #00FF00;">
<span>foo</span>
</a>
</header>
The computed view assumes that the !important color overrides it's children but the browser doesn't.
| Assignee | ||
Comment 3•6 years ago
|
||
So it is clear that <a> tags do not inherit colors so even though the header style contains !important the color is not inherited.
| Assignee | ||
Comment 4•6 years ago
|
||
A full list of CSS properties... properties that are inherited have yes in the inherited column:
https://www.w3.org/TR/CSS22/propidx.html
To understand how we need to deal with this we need to find the special cases where CSS inheritance is blocked e.g. the <a> tag blocks color from being inherited by it's children.
| Assignee | ||
Comment 5•6 years ago
|
||
@emilio You appear to be the person to ask about this as your name is all over our CSS cascade code.
Don't worry about our DevTools CSS Cascade calculation being completely wrong... there is an issue about that (bug 1535281).
My question is that surely the !important declaration inside <header> should be inherited by the <span> but the <a> tag's style somehow trumps it.
Chrome does the same thing so I am guessing we are missing something here?
Also, are there specific tags that block !important properties like this and, if so, how do we know which ones?
Comment 6•6 years ago
|
||
That's just not how !important works. !important overrides other declarations for a given element, but doesn't affect inheritance.
So in this case the !important will only mean that the <header> will get that color over any other more specific declarations.
Once the <header>s computed color is #ff0000, it inherits to children, but its children can override it with any other declaration that applies to them, regardless of importance.
| Assignee | ||
Comment 7•6 years ago
|
||
(In reply to Emilio Cobos Álvarez (:emilio) from comment #6)
That's just not how !important works.
!importantoverrides other declarations for a given element, but doesn't affect inheritance.So in this case the !important will only mean that the
<header>will get that color over any other more specific declarations.Once the
<header>s computed color is#ff0000, it inherits to children, but its children can override it with any other declaration that applies to them, regardless of importance.
Of course that is the case... it's been a long day ;)
| Assignee | ||
Comment 8•6 years ago
|
||
The Problem
In devtools/server/actors/inspector/css-logic.js the CSS cascade is currently calculated like this (descending order):
- User or author
// normal user rules are level with author rules... wrong. - Inline style, normal weight
// inline style is part of the specificity calculation... this shouldn't be here. - Inline style, !important
// inline style is part of the specificity calculation... this shouldn't be here. - Non-inline style !important
// From which stylesheet? They all have different priorities. - Important rules
// From which stylesheet? They all have different priorities. - Non-important rules
// From which stylesheet? They all have different priorities. - Specificity
- Sheet Index
- Rule Line
- Rule Column
It should be clear from my comments above that our cascade algorithm is not correct.
What we should have been doing
According to https://www.w3.org/TR/CSS2/cascade.html#cascading-order we should have been doing it like this (descending order):
- User & !important
- Author & !important
- Author, normal weight
- User, normal weight
- User-Agent, normal weight
- specificity
- Sheet Index
- Rule Line
- Rule Column
What we should do now
Now according to https://www.w3.org/TR/css-cascade-3/#cascading (which platform follows now) and https://www.w3.org/TR/css-cascade-4/#cascading we should now be doing this (descending order):
- Transition declarations [css-transitions-1]
- User-Agent & !important
- User & !important
- Author & !important
- CSS Animations, @keyframes
- Author, normal weight
- User, normal weight
- User-Agent, normal weight
- specificity
- Sheet Index - Declarations from imported style sheets are ordered as if their style sheets were substituted in place of the @import rule.
- Rule Line
- Rule Column
CSS Animations Example
h2 {
animation: a 3s;
}
@keyframes a {
0% {
color:red;
}
100% {
color:lime;
}
}
CSS Transition Example
h2 {
transition: color 0.5s ease;
}
h2:hover {
color: purple;
}
| Assignee | ||
Comment 10•6 years ago
|
||
We also pay no attention to the distance an inherited style is away from a node. This means that all inherited styles are classed as equal so the rule closest to the end of the stylesheet wins.
The closest parent is what we need when there are only inherited styles.
| Assignee | ||
Comment 11•6 years ago
|
||
Try
https://treeherder.mozilla.org/#/jobs?repo=try&revision=f1bad5e5282812225da95c0ea9e2ef173640b5da
Summary
!!Comparing numerous complex websites such as github, facebook, cnn etc. the cascade now matchers that of Chrome so we are in a much better place.!!
According to https://www.w3.org/TR/css-cascade-3/#cascading (which platform follows now) and https://www.w3.org/TR/css-cascade-4/#cascading we should now be doing this (descending order):
- Transition declarations
- User-Agent & !important
- User & !important
- Author & !important
- CSS Animations, @keyframes
- Author, normal weight
- User, normal weight
- User-Agent, normal weight
- specificity
- Sheet Index
- Rule Line
- Rule Column
We are only dealing with CSS selectors here so we can safely drop Transition declarations and CSS Animations because their presence here is irrelevant when it comes to the CSS cascade information we display in the computed view.
This leaves us with:
- User-Agent & !important
- User & !important
- Author & !important
- Author, normal weight
- User, normal weight
- User-Agent, normal weight
- specificity
- Sheet Index
- Rule Line
- Rule Column
Changes
- References to content stylesheets have been changed to author stylesheet to closely match the technical terms author, user and agent stylesheets.
- Simplified and modernized a bunch of for loops to make the code easier to understand.
- Previous to these changes all matching parent rules were classed as equal e.g. color on the body tag was equal to color on a node's immediate container. We now use the
distancevariable to tell how close a rule is to the current node. This is the highest qualifier in our cascade calculation. - The
_agentSheet,_authorSheetand_userSheetproperties are now used to obtain a sheets origin. elementStylewas renamed toinlineStylein order to correctly identify the rule's origin.- We used to sort the matchedSelectors to move rules with
STATUS.MATCHEDaboveSTATUS.PARENT_MATCHbut this is unnecessary now that we have thedistanceproperty so we no longer do this. - The
compareTo()method has been updated to match https://www.w3.org/TR/css-cascade-3/#cascading (which platform follows now) and https://www.w3.org/TR/css-cascade-4/#cascading. It has also been simplified and made far less prone to error.
Updated•6 years ago
|
Comment 12•6 years ago
|
||
Comment 13•6 years ago
|
||
| bugherder | ||
Updated•5 years ago
|
Description
•