1# Servo's style system overview 2 3This needs to be filled more extensively. Meanwhile, you can also take a look to 4the [style doc comments][style-doc], or the [Styling 5Overview][wiki-styling-overview] in the wiki, which is a conversation between 6Boris Zbarsky and Patrick Walton about how style sharing works. 7 8<a name="selector-impl"></a> 9## Selector Implementation 10 11The style system is generic over quite a few things, in order to be shareable 12with Servo's layout system, and with [Stylo][stylo], an ambitious project that 13aims to integrate Servo's style system into Gecko. 14 15The main generic trait is [selectors' SelectorImpl][selector-impl], that has all 16the logic related to parsing pseudo-elements and other pseudo-classes appart 17from [tree-structural ones][tree-structural-pseudo-classes]. 18 19Servo [extends][selector-impl-ext] that trait in order to allow a few more 20things to be shared between Stylo and Servo. 21 22The main Servo implementation (the one that is used in regular builds) is 23[SelectorImpl][servo-selector-impl]. 24 25<a name="dom-glue"></a> 26## DOM glue 27 28In order to keep DOM, layout and style in different modules, there are a few 29traits involved. 30 31Style's [`dom` traits][style-dom-traits] (`TDocument`, `TElement`, `TNode`, 32`TRestyleDamage`) are the main "wall" between layout and style. 33 34Layout's [`wrapper`][layout-wrapper] module is the one that makes sure that 35layout traits have the required traits implemented. 36 37<a name="stylist"></a> 38## The Stylist 39 40The [`stylist`][stylist] structure is the one that holds all the selectors and 41device characteristics for a given document. 42 43The stylesheets' CSS rules are converted into [`Rule`][selectors-rule]s, and 44introduced in a [`SelectorMap`][selectors-selectormap] depending on the 45pseudo-element (see [`PerPseudoElementSelectorMap`][per-pseudo-selectormap]), 46stylesheet origin (see [`PerOriginSelectorMap`][per-origin-selectormap]), and 47priority (see the `normal` and `important` fields in 48[`PerOriginSelectorMap`][per-origin-selectormap]). 49 50This structure is effectively created once per [pipeline][docs-pipeline], in the 51LayoutThread corresponding to that pipeline. 52 53<a name="properties"></a> 54## The `properties` module 55 56The [properties module][properties-module] is a mako template where all the 57properties, computed value computation and cascading logic resides. 58 59It's a complex template with a **lot** of code, but the main function it exposes 60is the [`cascade` function][properties-cascade-fn], which performs all the 61computation. 62 63<a name="pseudo-elements"></a> 64## Pseudo-Element resolution 65 66Pseudo-elements are a tricky section of the style system. Not all 67pseudo-elements are very common, and so some of them might want to skip the 68cascade. 69 70Servo has, as of right now, five [pseudo-elements][servo-pseudo-elements]: 71 72 * [`::before`][mdn-pseudo-before] and [`::after`][mdn-pseudo-after]. 73 * [`::selection`][mdn-pseudo-selection]: This one is only partially 74 implemented, and only works for text inputs and textareas as of right now. 75 * `::-servo-details-summary`: This pseudo-element represents the `<summary>` of 76 a `<details>` element. 77 * `::-servo-details-content`: This pseudo-element represents the contents of 78 a `<details>` element. 79 80Both `::-servo-details-*` pseudo-elements are private (i.e. they are only parsed 81from User-Agent stylesheets). 82 83Servo has three different ways of cascading a pseudo-element, which are defined 84in [`PseudoElementCascadeType`][pseudo-cascade-type]: 85 86<a name="pe-cascading-eager"></a> 87### "Eager" cascading 88 89This mode computes the computed values of a given node's pseudo-element over the 90first pass of the style system. 91 92This is used for all public pseudo-elements, and is, as of right now, **the only 93way a public pseudo-element should be cascaded** (the explanation for this is 94below). 95 96<a name="pe-cascading-precomputed"></a> 97### "Precomputed" cascading 98 99Or, better said, no cascading at all. A pseudo-element marked as such is not 100cascaded. 101 102The only rules that apply to the styles of that pseudo-element are universal 103rules (rules with a `*|*` selector), and they are applied directly over the 104element's style if present. 105 106`::-servo-details-content` is an example of this kind of pseudo-element, all the 107rules in the UA stylesheet with the selector `*|*::-servo-details-content` (and 108only those) are evaluated over the element's style (except the `display` value, 109that is overwritten by layout). 110 111This should be the **preferred type for private pseudo-elements** (although some 112of them might need selectors, see below). 113 114<a name="pe-cascading-lazy"></a> 115### "Lazy" cascading 116 117Lazy cascading allows to compute pseudo-element styles lazily, that is, just 118when needed. 119 120Currently (for Servo, not that much for stylo), **selectors supported for this 121kind of pseudo-elements are only a subset of selectors that can be matched on 122the layout tree, which does not hold all data from the DOM tree**. 123 124This subset includes tags and attribute selectors, enough for making 125`::-servo-details-summary` a lazy pseudo-element (that only needs to know 126if it is in an `open` details element or not). 127 128Since no other selectors would apply to it, **this is (at least for now) not an 129acceptable type for public pseudo-elements, but should be considered for private 130pseudo-elements**. 131 132#### Not found what you were looking for? 133 134Feel free to ping @SimonSapin, @mbrubeck or @emilio on irc, and please mention 135that you didn't find it here so it can be added :) 136 137[style-doc]: http://doc.servo.org/style/index.html 138[wiki-styling-overview]: https://github.com/servo/servo/wiki/Styling-overview 139[stylo]: https://public.etherpad-mozilla.org/p/stylo 140[selector-impl]: http://doc.servo.org/selectors/parser/trait.SelectorImpl.html 141[selector-impl-ext]: http://doc.servo.org/style/selector_parser/trait.SelectorImplExt.html 142[servo-selector-impl]: http://doc.servo.org/style/servo_selector_parser/struct.SelectorImpl.html 143[tree-structural-pseudo-classes]: https://www.w3.org/TR/selectors4/#structural-pseudos 144[style-dom-traits]: http://doc.servo.org/style/dom/index.html 145[layout-wrapper]: http://doc.servo.org/layout/wrapper/index.html 146[pseudo-cascade-type]: http://doc.servo.org/style/selector_parser/enum.PseudoElementCascadeType.html 147[servo-pseudo-elements]: http://doc.servo.org/style/selector_parser/enum.PseudoElement.html 148[mdn-pseudo-before]: https://developer.mozilla.org/en/docs/Web/CSS/::before 149[mdn-pseudo-after]: https://developer.mozilla.org/en/docs/Web/CSS/::after 150[mdn-pseudo-selection]: https://developer.mozilla.org/en/docs/Web/CSS/::selection 151[stylist]: http://doc.servo.org/style/stylist/struct.Stylist.html 152[selectors-selectormap]: http://doc.servo.org/selectors/matching/struct.SelectorMap.html 153[selectors-rule]: http://doc.servo.org/selectors/matching/struct.Rule.html 154[per-pseudo-selectormap]: http://doc.servo.org/style/stylist/struct.PerPseudoElementSelectorMap.html 155[per-origin-selectormap]: http://doc.servo.org/style/stylist/struct.PerOriginSelectorMap.html 156[docs-pipeline]: https://github.com/servo/servo/blob/master/docs/glossary.md#pipeline 157[properties-module]: http://doc.servo.org/style/properties/index.html 158[properties-cascade-fn]: http://doc.servo.org/style/properties/fn.cascade.html 159