@@ -1982,187 +1982,35 @@ The Hyperlink Pseudo-class: '':any-link''</h3>
19821982<h3 id="link">
19831983The Link History Pseudo-classes: '':link'' and '':visited''</h3>
19841984
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
19931992 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
19951994 been visited by the user.
1995+ </ul>
19961996
19971997 After some amount of time, user agents may choose to return a
19981998 visited link to the (unvisited) '':link'' state.
19991999
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.
20452001
20462002 <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:
20582005
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>
20642007 </div>
20652008
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.
21662014
21672015<h3 id="the-local-link-pseudo">
21682016The Local Link Pseudo-class: '':local-link''</h3>
0 commit comments