- From: L. David Baron <[email protected]>
- Date: Sun, 26 Oct 2008 15:10:02 -0700
- To: [email protected]
To follow up on the group's discussion of the ::selection pseudo-element at the face-to-face last week (ISSUE-67, see http://www.w3.org/Style/CSS/Tracker/issues/67 ). We discussed a number of possibilities and rejected some of them due to various requirements brought up. I'd like to try to go thrtough these requirements a little more carefully and evaluate potential solutions. The requirements that I see are: (1) The appearance of a piece of text when it is selected should not vary depending on the root container of the selection. (Root container is a term defined in DOM Level 2 Traversal and Range, meaning the nearest common ancestor of the boundary points of the range.) (2) The system's default selection style should be representable in terms of CSS selectors (although we may not currently have properties for all aspects of the style), in the UA style sheet. (I'd note that we'd previously considered only one selector for this requirement, "*::selection". However, it's possible that we could use "*:root::selection" instead.) (3) Author styles should override the system's default selection style. (4) The background color and foreground (text) color of the selection style should always cover/override the background and foreground that apply when the text is not selected. Also, a very nice to have (almost a requirement), given the current css3-selectors spec: (5) Authors should be able to change the selection style within a specific element. (Because of (1), such changes apply to any selected content inside that element, whether or not the element is an ancestor of the root container of the selection.) If they can do so, such a change should apply to all of the descendants of that element. Based on these requirements, I can draw the following conclusions: Given the following styles, markup and selection ("<<" to ">>"): p::selection { background: yellow; color: black; } span { background: red; } <p>This <<has <span>the</span> selection>> in it.</p> we want the yellow background to be visible inside the span (on top of the red background), from (4). This means that the ::selection pseudo-element must be innermost (i.e., the text "the" is wrapped in the selection pseudo-element which is in turn inside the span), even for background-* (which are non-inherited properties). Making the ::selection pseudo-element innermost also helps satisfy (1). If we want to in turn satisfy (5), which would require that given the styles: p::selection { background: purple; } span::selection { background: blue; } the background of a selected span inside a paragraph is blue, we need some mechanism for saying that span::selection overrides p::selection. I can see two possibilities: * nesting of ::selection pseudo-elements * a cascade to create a single ::selection pseudo-element, where the rules matching all elements cascade according to normal CSS cascading order and according to tree depth If we choose nesting of ::selection pseudo-elements, then we run into the problem that the rules: p::selection { background: purple; } ::selection { background: blue; } would cause the selection on any element inside the p to be blue. However, we could still represent the default selection as :root::selection rather than as ::selection, although this seems less intuitive to me. Alternatively, if we choose a cascade to determine the styles of a single pseudo-element, we would probably want p::selection to override ::selection on a descendant (in other words, we would make tree depth a weaker criterion in the sort than specificity, but stronger than style sheet order). However, that might be somewhat non-intuitive when comparing other, more specific, selectors (p#notice::selection vs. span::selection). Yet another approach would be to make tree depth the strongest criterion in the cascade. This might be simpler to implement since it would allow more direct use of existing CSS cascade code (build the lists of rules for all elements in the tree according to normal CSS cascade rules, and then concatenate them). However, this approach has the same problem that nesting has, in that the default style would have to be expressed as :root::selection, and a ::selection rule would override p::selection on any elements inside of p. I would note that one other major difference between the cascade approach and the nesting approach is the handling of background colors with an alpha component between 0 and 1. In the nesting approach, the alpha components nest (and thus get more opaque) or potentially draw on top of a non-alpha selection background color. In the cascading approach, only one background color would be used. To summarize, I see three options: A) nested ::selection pseudo elements (one for each ancestor in tree) - introduces fewest new concepts to CSS model - handles *::selection badly - handles background colors with alpha badly (though perhaps depending on requirements) B) single ::selection pseudo element, cascaded by (tree depth, weight/origin, specificity, order) - handles *::selection badly C) single ::selection pseudo element, cascaded by (weight/origin, specificity, tree depth, order) - introduces most new concepts to CSS model In all cases, a ::selection pseudo-element would never contain any real elements; they would always be split at any boundaries and created as the innermost position. I believe all three of these approaches meet requirements (1)-(5). However, I haven't yet considered the effect of declaring the 'outline' property on ::selection pseudo-elements, which might make an outermost rather than an innermost pseudo-element desirable, assuming that supporting 'outline' on ::selection is really a requirement. I believe Ian has some pretty detailed tests for ::selection somewhere; I haven't yet looked into what they require (or, for that matter, found them, since I'm writing this offline). -David -- L. David Baron http://dbaron.org/ Mozilla Corporation http://www.mozilla.com/
Received on Monday, 27 October 2008 01:21:50 UTC