Open emilio opened 6 years ago
Gecko's behavior seems to be the only one that makes any sense to me, reading the spec.
In my opinion, Blink/WebKit's behavior seems to make more sense. Custom properties are not allowed visited properties, so var()
uses the cascaded value from other rules matching the link. Given that the purpose of visited link styling limitation is user's privacy protection, this sounds reasonable to me.
In Edge 16, the link is also brown.
CSS Selectors says "record the values of the allowed :visited properties", but it does not specify if the recorded value is the specified one or the computed one. It seems Firefox does the latter and the others do the former.
In my opinion, Blink/WebKit's behavior seems to make more sense. Custom properties are not allowed visited properties, so var() uses the cascaded value from other rules matching the link. Given that the purpose of visited link styling limitation is user's privacy protection, this sounds reasonable to me.
I guess that's fair, yeah... It's somewhat weird that they do variable substitution but not computation.
it does not specify if the recorded value is the specified one or the computed one.
IMHO, it shouldn't matter in this case. The --foo: yellow
declaration in the :visited
rule should be ignored altogether because --foo
is not listed among "allowed :visited properties". So either way, the --foo
property value for a visited link should be one specified or cascaded to the :link
state. Please correct me if I miss something.
should be ignored altogether because
--foo
is not listed among "allowed :visited properties"
True, but color
is listed. So the value of color
when the element matches :visited
should be recorded. This will be var(--foo)
if it's the specified value, or rgb(255, 255, 0)
if it's the computed one.
The former will compute to rgb(165, 42, 42)
when not matching :visited
, the latter will stay as rgb(255, 255, 0)
.
I think from the spec wording, Firefox is right. "Compute the element's style as if the relevant link was :visited" should include matching, cascading, and resolving variable references. I'm not sure how could you justify that something like:
<!doctype html>
<style>
:link {
--foo: brown;
}
:visited {
--foo: yellow;
color: var(--foo);
}
</style>
<a href="">Which color?</a>
Should display brown if the link is visited, since clearly computing the style as if the element was :visited would've never matched :link
.
@Loirooriol Oof, that's a stray commit. The exact spec text for :visited
management is under discussion in https://github.com/w3c/csswg-drafts/pull/2105 and https://github.com/w3c/csswg-drafts/issues/2037 but isn't ready yet.
Under the current spec, both interpretations are valid, although ignoring --foo: yellow
in the color
declaration is more aggressive than necessary. It must, however, not return yellow in the OM, and probably can't return yellow in any property that's not otherwise supported for :visited
links, either, as this can leak information.
In my opinion the :visited and :link should be removed from specification because of privacy reason.
I think that's not realistic. When writing Gecko's new style engine we almost broke visited in some subtle ways and people noticed: https://bugzilla.mozilla.org/show_bug.cgi?id=1417781
It'd be nice to do something like https://bugzilla.mozilla.org/show_bug.cgi?id=1398414, ensure it's web-compatible, ship it, and then :visited stops being a privacy issue at all and all this complexity goes away, but not sure that's going to be done any time soon.
Any privacy setting to disable/enable it?
BTW. I think the spec should be created with security in mind.
Same-origin policy? To mark as visited only internal links? Then all styles can work. Visiting of the same origin sub-pages can be detected with other methods. For example onclick or cookies/IP.
CSS Selectors says "record the values of the allowed :visited properties", but it does not specify if the recorded value is the specified one or the computed one.
The commit (that I accidentally pushed earlier; it's still visible from the #2105 PR) specifies in step 2 that you compute styles, then in step 3 you record the styles; the implication is that you're recording computed styles. I can make that more clear.
(The custom property itself is not recorded, and so any properties other than the ":visited properties" won't see the values of custom properties set in a :visited rule. But the :visited properties will, since their var()s get resolved before they're recorded.)
Thus, in @emilio's example, the link is yellow when visited, but a background-image: linear-gradient(var(--foo), white);
declaration would create a brown->white gradient (since background-image
isn't a :visited property).
Should the following test-case be brown or yellow?
Right now Gecko is yellow, blink / webkit are brown.