From 4a4b81cf51524b5f74a877e8e7ce66881b5ac383 Mon Sep 17 00:00:00 2001
From: Tab Atkins
spec:css-syntax-3; type:dfn; text:identifier
+spec:css-color-4; type:property; text:color
+spec:css-pseudo-4; type:selector;
+ text: ::first-line
+ text: ::first-letter
+ text: ::before
+ text: ::after
@@ -1906,35 +1912,187 @@ The Hyperlink Pseudo-class: '':any-link''
The Link History Pseudo-classes: '':link'' and '':visited''
- User agents commonly display unvisited hyperlinks differently from
- previously visited ones. Selectors
- provides the pseudo-classes :link and
- :visited to distinguish them:
+ User agents commonly display unvisited hyperlinks
+ differently from previously visited ones.
+ Selectors provides the pseudo-classes
+ :link and :visited
+ to distinguish them.
+ Roughly:
-
-
After some amount of time, user agents may choose to return a
visited link to the (unvisited) '':link'' state.
- The two states are mutually exclusive.
+ The two states are mutually exclusive
+ (no element can ever match '':link:visited''),
+ but their actual interaction is more complex than that,
+ for privacy reasons explained below.
+
+ In full, the behavior is actually that the '':link'' pseudo-class applies to all links,
+ but the '':visited'' pseudo-class applies the following behavior and restrictions:
+
+ footnote and already visited:
+ For example, with the following common example style sheet:
+
+
+ :link { color: blue; }
+ :visited { color: purple; }
+
+
+ Visited links show up as purple only for rendering to the screen.
+ If the document uses JS to query the element’s style,
+ it will instead report ''color: blue'',
+ as if the element only matched '':link''.
+
+ Similarly, if HTML's <{canvas}> element develops an ability to render HTML to the canvas with CSS styling,
+ then either the links would be styled blue
+ (because by default, <{canvas}> gives the document the ability to inspect the results),
+ or the visited links will be purple,
+ but <{canvas}> will restrict the page's ability to inspect the pixels of the result.
+
+ :link {
+ color: blue;
+ background-image: url("unvisited.png");
+ }
+ :visited {
+ color: purple;
+ background-image: url("visited.png");
+ }
+
+
+ With this style sheet,
+ a visited link will be colored purple,
+ but have the "unvisited.png" background,
+ because 'background-image' is not one of the allowed :visited properties,
+ and so whatever value it gets from a '':visited'' style
+ is not recorded in the element's :visited styles.
+
+ :visited + span { color: red; }
+
- .footnote:visited
+ Even tho this style sheet is applying an allowed :visited property to the span element,
+ the span’s relevant link can never be its previous sibling
+ (it can only be the span or one of its ancestors).
+ Since the [=apply :visited styling|:visible styling algorithm=]
+ only checks if the element's relevant link is '':visited''
+ (and treats all other links on the page as unvisited),
+ this selector will never actually match anything.
Why does '':visited'' have this strange behavior and restrictions?
+
+ Originally, '':link'' and '':visited'' did indeed work in the simple way
+ described at the beginning of this chapter,
+ like two ordinary mutually-exclusive pseudo-classes.
+ It was eventually discovered, however,
+ that this allowed pages to determine what other sites a user had visited,
+ by listing a bunch of links off-screen
+ and using JS to tell whether they were styled with '':link'' or '':visited''.
+
+ This was bad both for user's privacy
+ (for obvious reasons, sharing a user's browsing history with everyone is bad)
+ and for their security
+ (phishing attacks could, for example, tell which bank website a user visited,
+ and render their phishing page to match that bank specifically,
+ making it more likely to fool the user).
+
+ Rendering visited links in a different style was too useful to throw away entirely,
+ so instead user agents developed the above algorithm
+ to "lie" about the style in some contexts,
+ but still rendering the link with '':visited'' styles normally,
+ without paying too much extra computation time.
+
+ The very limited list of allowed :visited properties
+ further limits the possibility of a page figuring things out.
+ If '':visited'' could apply any property,
+ pages could still,
+ for example,
+ apply a particular 'background-image' only when a link is visited,
+ and then record whether that image was loaded from their server,
+ giving them the exact information we were trying to hide!
+ Similarly, any layout-affecting property,
+ like 'width',
+ might affect the positions of other elements on the page;
+ lying about these knock-on effects to hide the styling
+ would be much more expensive for the user agent.
+ Limiting it just a handful of properties that can only apply colors
+ ensures that as little information is leakable as possible.
+
The Target Pseudo-class: '':target''
@@ -3293,7 +3451,7 @@ Grammar
in a <
The Link History Pseudo-classes: '':link'' and '':visited''
- User agents commonly display unvisited hyperlinks
+ User agents commonly render unvisited hyperlinks
differently from previously visited ones.
Selectors provides the pseudo-classes
:link and :visited