@@ -1982,187 +1982,35 @@ The Hyperlink Pseudo-class: '':any-link''</h3>
1982
1982
<h3 id="link">
1983
1983
The Link History Pseudo-classes: '':link'' and '':visited''</h3>
1984
1984
1985
- User agents commonly display unvisited <a href="#the-any-link-pseudo">hyperlinks</a>
1986
- differently from previously visited ones.
1987
- Selectors provides the pseudo-classes
1988
- <dfn id='link-pseudo'>:link</dfn> and <dfn id='visited-pseudo'>:visited</dfn>
1989
- to distinguish them.
1990
- Roughly:
1991
-
1992
- * The '':link'' pseudo-class applies to links that have
1985
+ User agents commonly display unvisited <a href="#the-any-link-pseudo">hyperlinks</a> differently from
1986
+ previously visited ones. Selectors
1987
+ provides the pseudo-classes <dfn id='link-pseudo'>:link</dfn> and
1988
+ <dfn id='visited-pseudo'>:visited</dfn> to distinguish them:
1989
+
1990
+ <ul>
1991
+ <li> The '':link'' pseudo-class applies to links that have
1993
1992
not yet been visited.
1994
- * The '':visited'' pseudo-class applies once the link has
1993
+ <li> The '':visited'' pseudo-class applies once the link has
1995
1994
been visited by the user.
1995
+ </ul>
1996
1996
1997
1997
After some amount of time, user agents may choose to return a
1998
1998
visited link to the (unvisited) '':link'' state.
1999
1999
2000
- The two states are mutually exclusive
2001
- (no element can ever match '':link:visited'' ),
2002
- but their actual interaction is more complex than that,
2003
- for privacy reasons explained below.
2004
-
2005
- In full, the behavior is actually that the '':link'' pseudo-class applies to all links,
2006
- but the '':visited'' pseudo-class applies the following behavior and restrictions:
2007
-
2008
- <div algorithm=":visited styling">
2009
- To <dfn>apply :visited styling</dfn> to an element |el|:
2010
-
2011
- 1. Check to see if |el| has a <a>relevant link</a> .
2012
- The <dfn for=":visited">relevant link</dfn> for an element
2013
- is the element itself,
2014
- if it's an element that would match '':link'' ,
2015
- or else the closest ancestor that would match '':link'' .
2016
-
2017
- If |el| does not have a <a>relevant link</a> ,
2018
- then '':visited'' has no effect on the element.
2019
-
2020
- 2. Otherwise, compute |el|’s style,
2021
- treating only its <a>relevant link</a> as matching '':visited''
2022
- (and thus, not '':link'' ).
2023
- All other links must be treated as matching '':link'' .
2024
-
2025
- 3. From the styling results,
2026
- record the values of the <dfn lt="allowed :visited property">allowed :visited properties</dfn> :
2027
-
2028
- * 'color'
2029
- * 'background-color'
2030
- * the 'border-color' sub-properties
2031
- * 'outline-color'
2032
- * 'column-rule-color'
2033
- * 'fill-color'
2034
- * 'stroke-color'
2035
-
2036
- These are |el|’s <dfn lt=":visited style">:visited styles</dfn> .
2037
-
2038
- 4. If |el|’s <a>relevant link</a> is actually visited,
2039
- then for the <a>allowed :visited properties</a> ,
2040
- use |el|’s <a>:visited styles</a> for any purposes
2041
- that won't allow the document itself to tell what the style is;
2042
- in all other contexts,
2043
- use the normal, all-'':link'' , styling.
2044
- </div>
2000
+ The two states are mutually exclusive.
2045
2001
2046
2002
<div class="example">
2047
- For example, with the following common example style sheet:
2048
-
2049
- <pre class=lang-css>
2050
- :link { color: blue; }
2051
- :visited { color: purple; }
2052
- </pre>
2053
-
2054
- Visited links show up as purple only for rendering to the screen.
2055
- If the document uses JS to query the element’s style,
2056
- it will instead report ''color: blue'' ,
2057
- as if the element only matched '':link'' .
2003
+ The following selector represents links carrying class
2004
+ <code> footnote</code> and already visited:
2058
2005
2059
- Similarly, if HTML's <{canvas}> element develops an ability to render HTML to the canvas with CSS styling,
2060
- then either the links would be styled blue
2061
- (because by default, <{canvas}> gives the document the ability to inspect the results),
2062
- or the visited links will be purple,
2063
- but <{canvas}> will restrict the page's ability to inspect the pixels of the result.
2006
+ <pre> .footnote:visited </pre>
2064
2007
</div>
2065
2008
2066
- <div class=example>
2067
- The special '':visited'' behavior also means
2068
- that a single element might be styled by a mix of '':link'' and '':visited'' rules.
2069
- For example:
2070
-
2071
- <pre class=lang-css>
2072
- :link {
2073
- color: blue;
2074
- background-image: url("unvisited.png");
2075
- }
2076
- :visited {
2077
- color: purple;
2078
- background-image: url("visited.png");
2079
- }
2080
- </pre>
2081
-
2082
- With this style sheet,
2083
- a visited link will be colored purple,
2084
- but have the "unvisited.png" background,
2085
- because 'background-image' is not one of the <a>allowed :visited properties</a> ,
2086
- and so whatever value it gets from a '':visited'' style
2087
- is not recorded in the element's <a>:visited styles</a> .
2088
- </div>
2089
-
2090
- <div class=example>
2091
- Another consequence of the special '':visited'' behavior
2092
- is that some selectors that look reasonable
2093
- will never match.
2094
- For example:
2095
-
2096
- <pre class=lang-css>
2097
- :visited + span { color: red; }
2098
- </pre>
2099
-
2100
- Even tho this style sheet is applying an <a>allowed :visited property</a> to the <code> span</code> element,
2101
- the <code> span</code> ’s <a>relevant link</a> can never be its previous sibling
2102
- (it can only be the <code> span</code> or one of its ancestors).
2103
- Since the [=apply :visited styling|:visible styling algorithm=]
2104
- only checks if the element's <a>relevant link</a> is '':visited''
2105
- (and treats all other links on the page as unvisited),
2106
- this selector will never actually match anything.
2107
- </div>
2108
-
2109
- <details class=note>
2110
- <summary> Why does '':visited'' have this strange behavior and restrictions?</summary>
2111
-
2112
- Originally, '':link'' and '':visited'' did indeed work in the simple way
2113
- described at the beginning of this chapter,
2114
- like two ordinary mutually-exclusive pseudo-classes.
2115
- It was eventually discovered, however,
2116
- that this allowed pages to determine what other sites a user had visited,
2117
- by listing a bunch of links off-screen
2118
- and using JS to tell whether they were styled with '':link'' or '':visited'' .
2119
-
2120
- This was bad both for user's privacy
2121
- (for obvious reasons, sharing a user's browsing history with everyone is bad)
2122
- and for their security
2123
- (phishing attacks could, for example, tell which bank website a user visited,
2124
- and render their phishing page to match that bank specifically,
2125
- making it more likely to fool the user).
2126
-
2127
- Rendering visited links in a different style was too useful to throw away entirely,
2128
- so instead user agents developed the above algorithm
2129
- to "lie" about the style in some contexts,
2130
- but still rendering the link with '':visited'' styles normally,
2131
- without paying too much extra computation time.
2132
-
2133
- The very limited list of <a>allowed :visited properties</a>
2134
- further limits the possibility of a page figuring things out.
2135
- If '':visited'' could apply any property,
2136
- pages could still,
2137
- for example,
2138
- apply a particular 'background-image' only when a link is visited,
2139
- and then record whether that image was loaded from their server,
2140
- giving them the exact information we were trying to hide!
2141
- Similarly, any layout-affecting property,
2142
- like 'width' ,
2143
- might affect the positions of <em> other</em> elements on the page;
2144
- lying about these knock-on effects to hide the styling
2145
- would be much more expensive for the user agent.
2146
- Limiting it just a handful of properties that can only apply colors
2147
- ensures that as little information is leakable as possible.
2148
- </details>
2149
-
2150
- User agents may treat all links as unvisited at all times.
2151
- (In particular, they can offer a user preference for this,
2152
- allowing the user to decide whether the benefit of seeing when a link has been visited
2153
- is more or less important
2154
- than the possibility of that information being leaked to random pages on the internet.)
2155
-
2156
- If the user agent uses some form of "link pre-loading"
2157
- to find resource urls in a stylesheet
2158
- and begin loading them before it's known that they'll actually be used on the page,
2159
- they might find a url that would only be applied by an element matching '':visited''
2160
- (which is impossible, as '':visited'' rules can't cause any properties to apply that load images).
2161
- User agents with this behavior must ensure that either
2162
- such urls are <em> never</em> loaded (preferable),
2163
- or at least that such urls are loaded at the same time
2164
- regardless of whether a link is visited or not.
2165
-
2009
+ Since it is possible for style sheet authors to abuse the :link and :visited pseudo-classes
2010
+ to determine which sites a user has visited without the user's consent,
2011
+ UAs may treat all links as unvisited links
2012
+ or implement other measures to preserve the user's privacy
2013
+ while rendering visited and unvisited links differently.
2166
2014
2167
2015
<h3 id="the-local-link-pseudo">
2168
2016
The Local Link Pseudo-class: '':local-link''</h3>
0 commit comments