2 | Title: Constructable Stylesheet Objects 3 | Shortname: construct-stylesheets 4 | Level: 1 5 | Status: DREAM 6 | ED: http://tabatkins.github.io/specs/construct-stylesheets/ 7 | Editor: Tab Atkins Jr., Google, http://xanthir.com/contact/ 8 | Abstract: This draft defines additions to CSSOM to make StyleSheet objects directly constructable, along with methods and APIs to make it easier to deal with stylesheets in the context of custom elements and similar. It also defines constructors for CSSRule objects. 9 | Ignored Terms: ShadowRoot, create a medialist object, add a css style sheet, document css style sheets 10 | Warning: replaced by https://w3c.github.io/csswg-drafts/cssom/#dom-cssstylesheet-cssstylesheet 11 |12 | 13 |
14 | spec:dom; type:interface; text:Document 15 |16 | 17 | Adding Stylesheets In Script {#adding-stylesheets} 18 | ================================= 19 | 20 |
21 | [Constructor(DOMString text, optional CSSStyleSheetInit options)] 22 | partial interface CSSStyleSheet { 23 | }; 24 | 25 | dictionary CSSStyleSheetInit { 26 | (MediaList or DOMString) media = ""; 27 | DOMString title = ""; 28 | boolean alternate = false; 29 | boolean disabled = false; 30 | }; 31 | 32 | interface TreeScope { 33 | attribute StyleSheetList moreStyleSheets; 34 | }; 35 | Document implements TreeScope; 36 | ShadowRoot implements TreeScope; 37 |38 | 39 |
null
,
46 | no parent CSS style sheet,
47 | no owner node,
48 | no owner CSS rule,
49 | and a title set to the {{CSSStyleSheetInit/title}} attribute of options.
50 | Set sheet’s origin-clean flag.
51 | 2. If the {{CSSStyleSheetInit/media}} attribute of options is a string,
52 | create a MediaList object from the string
53 | and assign it as sheet’s media.
54 | Otherwise, assign the value of the attribute as sheet’s media.
55 | 3. If the {{CSSStyleSheetInit/alternate}} attribute of options is true,
56 | set sheet’s alternate flag.
57 | 4. If the {{CSSStyleSheetInit/disabled}} attribute of options is true,
58 | set sheet’s disabled flag.
59 | 5. Parse a stylesheet from {{text}}.
60 | If it returned a list of rules,
61 | assign the list as sheet’s CSS rules;
62 | otherwise,
63 | set sheet’s CSS rules to an empty list.
64 | 6. Return sheet.
65 |
66 | document.styleSheets
,
74 | similar to how document.fonts
mixes OM-created and manually-created fonts?
75 | Big difference is that ordering matters here,
76 | which makes dealing with the invariants much more annoying.
77 | (What happens if you manually add a sheet between two <link> sheets,
78 | then insert another <link> in the document between them?
79 | Does it go before or after your manually-added one?
80 | Or do we just make it illegal to manually add a sheet before an automatic sheet?)
81 | document.styleSheets
,
110 | and allow you to insert constructed stylesheets into it.
111 | Or maybe add an .origin
attribute to CSSStyleSheet, defaulting to "author"?
112 |
113 | Maybe it only applies to the context you're in and descendant contexts?
114 | Need to investigate;
115 | probably bad to let a component apply automatic styles to the outer page via this mechanism.
116 | 3 | Shortname: css-extensions 4 | Level: 1 5 | Status: UD 6 | Group: CSSWG 7 | Work Status: exploring 8 | ED: http://tabatkins.github.io/specs/css-aliases/ 9 | Editor: Tab Atkins, Google, http://xanthir.com/contact/ 10 | Abstract: This specification defines methods for authors to extend and enhance various CSS features. 11 |12 | 13 |
14 | spec:css-values-4; type:dfn; text:identifier 15 |16 | 17 |
@custom-selector = @custom-selector <55 | 56 | This defines a custom selector which is written as a pseudo-class with the given <> < > ;
64 | @custom-selector :--heading h1, h2, h3, h4, h5, h6; 65 | 66 | :--heading { /* styles for all headings */ } 67 | :--heading + p { /* more styles */ } 68 | /* etc */ 69 |70 |
82 | <script> 83 | CSS.customSelector.set("_foo", 84 | {"predicate": function(el){...}, 85 | "matches": "a"}); 86 | </script> 87 |88 | 89 | "matches" is an optional selector specifying what subset of elements the custom selector is valid for. 90 | The selector is automatically false for elements that don't match, 91 | and the predicate isn't called. 92 | 93 | By default, the predicate is called whenever there's a mutation in an element that matches the "matches" selector, 94 | or one of its descendants. 95 | 96 | You should be able to suppress the auto-calling, 97 | and be able to trigger the predicate to run manually. 98 | That way you can use mutation listeners manually to only call the predicate when necessary. 99 | 100 | We should probably offer some sugar for filtering the list of mutations that trigger the predicate to be called. 101 | Maybe just a list of attributes that you'll be caring about? And/or tagnames? 102 | 103 | Maybe let the pseudo-class also accept an argument, 104 | and pass it (as a serialized string) as a second argument to the predicate. 105 | '':_foo'' would pass
null
,
106 | while '':_foo()'' would pass ""
.
107 | 113 | Fill in. 114 | 115 |
.customSupports
map?
153 | I suspect that individual cases will have their own useful contextual information,
154 | so it's better to specialize each instance of custom functions.
155 |
156 | How much can we do in pure CSS?
157 | Being able to substitute values depending on MQs or support queries would be useful.
158 | To get *real* use out of it, though, I suspect we'd need fuller support for conditionals,
159 | likely in the form of SASS's ''@if'' or something similar.
160 | 189 | CSS.customCombinator.set("--child", function(el) { 190 | return el.children; 191 | }); 192 |193 | 194 | Then ''div /--child/ span'' would be identical to ''div > span''. 195 | 196 | If we generalize a selector with a custom combinator to ''A /--custom/ B'', 197 | then the UA would automatically call the --custom function 198 | whenever new elements match ''A''. 199 | If elements stop matching ''A'', 200 | it won't bother; 201 | it'll just drop them from the result. 202 | 203 | Alternately, the function could take a list of elements 204 | (all the elements matching ''A'') 205 | and return a new list of elements. 206 | This would be a bit more complicated for the author, 207 | but would allow more variety in the types of combinators that could be defined, 208 | as you could define things that depend on the entire set of matched elements. 209 | For example, you could define ''A /nth 1/ B'' 210 | to give only the first element from the set of ''A'' matches. 211 | 212 | (Maybe we allow both variants, 213 | since the per-element one is easier to optimize and program against, 214 | but the per-set one allows some useful stuff.) 215 | 216 | Similarly to custom pseudo-classes, 217 | we'd allow arguments, 218 | with them parsed eagerly per-instance 219 | and passed to the combinator function. 220 | 221 | If we do the per-element combinator function, 222 | we could potentially cache the results, 223 | so that it never needs to be called again for the same element. 224 | Possibly have a flag that turns off this behavior, 225 | so that you're guaranteed to be called again. 226 |
2 | Title: CSS Anchor Positioning 3 | Shortname: css-anchor-position 4 | Level: 1 5 | Status: w3c/UD 6 | Group: csswg 7 | Work Status: exploring 8 | URL: http://tabatkins.github.io/specs/css-anchor-position 9 | Editor: Tab Atkins-Bittner, Google, http://xanthir.com/contact/, w3cid 42199 10 | Abstract: This specification defines 'anchor positioning', where a positioned element can size and position itself relative to one or more "anchor elements" elsewhere on the page. 11 | Warning: replaced by https://drafts.csswg.org/css-anchor-position-1/ 12 |13 | -------------------------------------------------------------------------------- /css-apply-rule/index.bs: -------------------------------------------------------------------------------- 1 |
2 | Title: CSS @apply Rule 3 | Shortname: css-apply-rule 4 | Level: 1 5 | Status: UD 6 | Group: CSSWG 7 | Work Status: abandoned 8 | URL: http://tabatkins.github.io/specs/css-apply-rule 9 | Editor: Tab Atkins-Bittner, Google, http://xanthir.com/contact/ 10 | Editor: Shane Stephens, Google, shanestephens@google.com 11 | Abstract: This specification defines the ''@apply'' rule, which allows an author to store a set of properties in a named variable, then reference them in other style rules. 12 | Ignored Terms: SyntaxError 13 | Warning: custom 14 | Custom Warning Title: Abandoned 15 | Custom Warning Text: This specification has been abandoned, due to being generally a bad idea. The reasoning is explained in this blog post. It is not expected to be revived. 16 |17 | 18 |
19 | spec:css-conditional-3; type:interface; text:CSSGroupingRule 20 |21 | 22 | Introduction {#intro} 23 | ===================== 24 | 25 | CSS custom properties enable authors to define reusable values, 26 | give them names, 27 | then invoke them throughout the stylesheet. 28 | This makes it easy to keep a page's theme consistent when changes are made, 29 | because the theming values are defined in a central place. 30 | 31 | But custom properties can hold more than just values-- 32 | they can also be used to hold sets of declarations. 33 | The ''@apply'' rule takes these sets of declarations and inlines them in another style rule, 34 | serving a purpose analogous to what the ''var()'' function does for individual values. 35 | 36 |
68 | :root { 69 | --toolbar-theme: { 70 | background-color: hsl(120, 70%, 95%); 71 | border-radius: 4px; 72 | border: 1px solid var(--theme-color late); 73 | }; 74 | --toolbar-title-theme: { 75 | color: green; 76 | }; 77 | } 78 | 79 | .toolbar { 80 | @apply --toolbar-theme; 81 | } 82 | .toolbar > .title { 83 | @apply --toolbar-title-theme; 84 | } 85 |86 | 87 | Then, we can override the theme for toolbars inside of "warning" elements: 88 | 89 |
90 | .warning { 91 | --toolbar-title-theme: { 92 | color: red; 93 | font-weight: bold; 94 | }; 95 | } 96 |97 | 98 | We don't have to worry about the internal structure of the toolbars, 99 | or precisely what internal elements use the styles. 100 | Simply overriding the custom property will automatically do the right thing. 101 |
110 | .foo { 111 | color: red; 112 | background: white; 113 | } 114 | #bar { 115 | color: blue; 116 | } 117 |118 | 119 | The ''#bar'' rule will win due to having a higher specificity, 120 | so its ''color:blue'' rule will apply to the element, 121 | but the ''background:white'' rule from the ''.foo'' rule also applies, 122 | since the ''#bar'' rule did not override 'background'. 123 | 124 | However, if these were instead defined as custom property sets: 125 | 126 |
127 | .foo { 128 | --my-theme: { 129 | color: red; 130 | background: white; 131 | }; 132 | } 133 | #bar { 134 | --my-theme: { 135 | color: blue; 136 | }; 137 | } 138 |139 | 140 | Then when an element uses the '--my-theme' custom property set, 141 | it will receive only the ''color:blue'' declaration. 142 | The ''background:white'' declaration from the ''.foo'' rule is ignored completely, 143 | as its rule lost the specificity battle. 144 |
174 | @apply = @apply <176 | 177 | The ''@apply'' rule is only valid inside of a style rule. 178 | Using it outside of a style rule, 179 | or inside any other rule, 180 | is invalid and causes the ''@apply'' to be ignored. 181 | 182 |> ; 175 |
186 | .foo { 187 | color: blue; 188 | @apply --foo-styles; 189 | } 190 |191 | 192 | Here's several invalid example of ''@apply'' usage: 193 | 194 |
195 | .foo { 196 | color: blue; 197 | } 198 | 199 | @apply --top-level-is-invalid; 200 |201 | 202 |
203 | @keyframes foo { 204 | from { color: red; } 205 | to { color: blue; } 206 | @apply --this-is-not-a-style-rule; 207 | } 208 |209 |
.childRules
attribute,
217 | and the properties in the custom property set will not be visible in any way.
218 |
219 | If the custom property that the ''@apply'' rule references
220 | does not define a valid custom property set,
221 | the ''@apply'' rule is treated, for the purposes of the cascade, as if it were replaced with nothing.
222 | It is not invalid, however.
223 | (For example, it is not dropped from the CSSOM.)
224 |
225 | Processing ''@apply'' Rules {#processing}
226 | =========================================
227 |
228 | To process ''@apply'' rules:
229 |
230 | 1. Inherit as normal.
231 | 2. Do var() substitution into custom properties only.
232 | 3. Do @apply substitution.
233 | 4. Re-do var() substitutions based on new property info.
234 |
235 |
236 |
237 |
238 | CSSOM {#cssom}
239 | ==============
240 |
241 | 242 | interface CSSApplyRule : CSSRule { 243 | attribute DOMString referencedProperty; 244 | }; 245 |246 | 247 |
2 | Title: CSS Cascade Control 3 | Shortname: css-cascade-control 4 | Level: 1 5 | Status: UD 6 | Group: CSSWG 7 | Work Status: exploring 8 | URL: https://tabatkins.github.io/specs/css-cascade-control/ 9 | Editor: Tab Atkins-Bittner 10 | Abstract: A proposal to improve the handling of list-value and set-valued properties when one wants to alter them in multiple independent ways, without overriding each other or having to explicitly handle all combinations. 11 |12 | 13 | Introduction {#intro} 14 | ===================== 15 | 16 | A number of CSS properties are list-valued (background, transition, etc) or set-valued (will-change, etc). 17 | These can be difficult to manage in an application written by several authors 18 | (or partially styled by indepedent libraries), 19 | or even when there's only a single author 20 | that just wants to style an element in multiple independent ways. 21 | 22 | For example, 23 | a particular class might do some 'transform' work, 24 | and thus want to set ''will-change: transform'', 25 | while another class does some 'opacity' changes, 26 | and thus wants to set ''will-change: opacity''. 27 | Done naively, if these two classes get set at the same time, 28 | one will win over the other, 29 | and 'will-change' will only reflect one of the values. 30 | 31 | Currently, the only way to get around this is to explicitly handle the collision, 32 | manually applying ''will-change: transform, opacity'' when the element matches both classes. 33 | This sort of explicit collision-handling is unmaintainable, 34 | and can quickly grow out of control if more cases are added, 35 | as each one increases the number of combinations to be handled combinatorially. 36 | (A third class means you need to explicitly handle the 1+2, 1+3, 2+3, and 1+2+3 cases. 37 | A fourth class means handling 11 different combinations!) 38 | 39 | In this spec we propose a few possible mechanisms to handle these situations more elegantly. 40 | 41 | Cascade Declarations 42 | ==================== 43 | 44 | During the cascade process, 45 | multiple declarations of the same property on a given element 46 | are sorted in specificity order 47 | to produce the output of the cascade, 48 | and then only the last value 49 | (the one with highest specificity) 50 | is actually used as the value of that property on the element. 51 | 52 | A cascade modifier is a modifier on a property name 53 | that makes the property's value depend partially on the 54 | previous cascaded value: 55 | the value for that property that comes before the current value 56 | (that is, is lower specificity) 57 | in the output of the cascade. 58 | 59 | For any set-valued property with a name 'set-prop', 60 | the following cascade modifiers exist: 61 | 62 | : set-prop+ 63 | :: Represents the union of its value with the previous cascaded value. 64 | : set-prop- 65 | :: Represents the difference of the previous cascaded value with its value. 66 | (That is, the previous cascaded value, 67 | minus the current values.) 68 | : set-prop{} 69 | :: Represents the intersection its value with the previous cascaded value. 70 | 71 | Issue: This involves defining the "unit" of each set-valued property 72 | (for example, in 'will-change' each keyword is a "unit"), 73 | and ensuring that all of them have a "null" value 74 | (like ''will-change/none''). 75 | 76 | For any list-valued property with a name 'list-prop', 77 | the following cascade modifiers exist: 78 | 79 | : list-prop+ 80 | :: Represents the current value appended to the end of the previous cascaded value. 81 | : +list-prop 82 | :: Represents the current value prepended to the start of the previous cascade value. 83 | 84 | Issue: The "unit" of list-valued properties are much easier to define; 85 | for all but some legacy properties like 'counter-reset', 86 | it's just splitting on commas. 87 | 88 |
97 | .foo { 98 | box-shadow+: 2px 2px; 99 | } 100 | .foo { 101 | box-shadow+: blue; 102 | } 103 |104 | 105 | As each property is still interpreted as a property, 106 | the first is interpreted the same as ''box-shadow: 2px 2px;'' 107 | (specifying a single drop-shadow set to ''currentcolor''), 108 | while the second is simply invalid. 109 |
122 | div { 123 | background-image: url(base.jpg); 124 | } 125 | div.foo { 126 | +background-image: url(one.jpg); 127 | } 128 | div.foo.bar { 129 | +background-image: url(two.jpg); 130 | } 131 |132 | 133 | This does *not* override the ''one.jpg'' with ''two.jpg''; 134 | for an element matching all three rules, 135 | it produces an equivalent effect to ''background-image: url(two.jpg), url(one.jpg), url(base.jpg);''. 136 | 137 | In other words, so long as the element matches the ''div.foo'' rule, 138 | the value will contain ''url(one.jpg)''. 139 | 140 | (You can override the entire thing 141 | with a higher-specificity declaration 142 | that doesn't use a cascade modifier, 143 | but that overrides the ''base.jpg'' too. 144 | There's no way to directly override just 145 | one of the modified declarations.) 146 |
157 | div { 158 | background-image: url(base.jpg); 159 | +background-image: var(--upper-background) !important; 160 | } 161 | div.foo { 162 | --upper-background: url(one.jpg); 163 | } 164 | div.foo.bar { 165 | --upper-background: url(two.jpg); 166 | } 167 |168 |
177 | div { 178 | background-image: var(--upper-background, none), url(base.jpg); 179 | } 180 | div.foo { 181 | --upper-background: url(one.jpg); 182 | } 183 | div.foo.bar { 184 | --upper-background: url(two.jpg); 185 | } 186 |187 | 188 | While this works in simple situations, 189 | it's less useful as more things interact. 190 | It requires that 'background-image' never be disturbed; 191 | if anything else attempts to set background-image, 192 | it'll wipe out the variable use. 193 | The cascade modifier approach, 194 | on the other hand, 195 | maintains the images set by the variables 196 | even if other code sets the 'background-image' property. 197 |
2 | Title: CSS 'content-size' Property 3 | Shortname: css-content-size 4 | Level: 1 5 | Status: UD 6 | Group: CSSWG 7 | Work Status: exploring 8 | URL: http://example.com/url-this-spec-will-live-at 9 | Editor: Tab Atkins-Bittner, Google 10 | Abstract: This specification defines the 'content-size' property, 11 | which, in conjunction with [=size containment=], 12 | defines a 'default size' for the contents of an element. 13 | 14 |15 | 16 |
17 | type:property; spec: css-sizing-3; 18 | text: min-height; 19 | text: min-width; 20 |21 | 22 | Introduction {#intro} 23 | ===================== 24 | 25 | When [=size containment=] is applied to an element, 26 | it lays out as if it were completely empty, 27 | ignoring any child content it might have. 28 | This directive lets the layout engine "scope" sizing-related layout changes; 29 | the UA knows, for 100% certain, 30 | that no changes in the contents of the element 31 | will have any effect on the element's own size, 32 | and so the UA can immediately skip redoing layout for the element or its ancestors 33 | without having to rely on heuristics. 34 | 35 | However, making the element completely empty isn't always desirable; 36 | it can allow the element to shrink down to zero size. 37 | Setting an explicit 'width'/'height' (or 'min-width'/'min-height') on the element can prevent this, 38 | but that can have its own possibly unwanted implications on layout, 39 | making it act differently than an ordinary element with children would in the same situation. 40 | 41 | The 'content-size' property, 42 | when set on an element with [=size containment=], 43 | causes the element to pretend to have a single, fixed-size child of the specified size, 44 | rather than pretending to be completely empty. 45 | This accomplishes the same "hiding" of layout dirtying that [=size containment=] normally does, 46 | but allows the author to provide a more useful "default size" for the element, 47 | and avoid accidentally letting the element shrink down to a useless size. 48 | 49 | 50 | The 'content-size' Property {#content-size} 51 | =========================================== 52 | 53 |
54 | Name: content-size 55 | Value: none | <61 | 62 | The 'content-size' property specifies whether a container with [=size containment=] 63 | should pretend to be empty for layout purposes, 64 | or pretend to have a single child of the specified size. 65 | Its values are: 66 | 67 |>{1,2} 56 | Initial: none 57 | Applies To: elements with [=size containment=] 58 | Inherited: no 59 | Computed Value: the specified keyword, or a pair of absolutized < >s 60 |
2 | Title: CSS Extend Rule 3 | Abstract: This module defines the ''@extend'' rule, which allows elements to act as if they matched other selectors. 4 | This makes it easier to "subclass" styling in a page, 5 | when some new type of element should act like an existing element, 6 | but with tweaks. 7 | Editor: Tab Atkins, Google, http://xanthir.com 8 | ED: https://tabatkins.github.io/specs/css-extend-rule/ 9 | Status: DREAM 10 | Shortname: extend-rule 11 | Level: 1 12 | Ignored Terms: getelementsbytagname() 13 |14 | 15 |
16 | spec: selectors-4; type: selector; text: :active 17 |18 | 19 | Introduction {#intro} 20 | ===================== 21 | 22 | Sometimes, when designing a page, 23 | an author might create some styles for a given type of element, 24 | such as "error" messages. 25 | Later, they might realize they need to create a "subclass" of the first type, 26 | such as a "serious error" message, 27 | which is styled the same way as "error", 28 | but with a few tweaks to make it more distinctive. 29 | Currently, CSS does not have a good way to handle this. 30 | 31 | If the author has control over the HTML, 32 | they can declare that every element with a class of "serious-error" 33 | must also have a class of "error". 34 | This, however, is error-prone-- 35 | it's easy to forget to add the "error" class to an element, 36 | causing confusing styling issues, 37 | and any scripting that creates or manipulates error elements 38 | has to know to maintain the states properly 39 | (for example, any time they remove the "error" class, 40 | they have to remember to check for and remove "serious-error" as well). 41 | 42 | Alternately, this can be handled in the CSS-- 43 | every time a style rule contains a ''.error'' selector, 44 | the selector can be duplicated with ''.serious-error'' replacing it. 45 | This, too, is error-prone: 46 | it's easy for typos or inattention to cause the duplicated selectors to drift apart, 47 | and it's easy, when adding new ''.error'' rules, 48 | to forget to duplicate the selector. 49 | 50 | The ''@extend'' rule, defined in this specification, 51 | fixes this common issue. 52 | It allows an author to declare that certain elements, 53 | such as everything matching ''.serious-error'', 54 | must act as if they had the necessary features to match another selector, 55 | such as ''.error''. 56 | 57 |
61 | .error { 62 | color: red; 63 | border: thick dotted red; 64 | } 65 | 66 | .serious-error { 67 | @extend .error; 68 | font-weight: bold; 69 | } 70 |71 | 72 | Now an element like
<div class=serious-error>
will have red text and border,
73 | just like elements with class=error
,
74 | but will also use bold text.
75 | class=error
or class=serious-error
to elements as appropriate,
79 | and write simple CSS,
80 | creating style rules that just mention ''.error'' or ''.serious-error'',
81 | secure in the knowledge that the former rules will also apply to serious errors.
82 |
83 | The ''@extend'' Rule {#extend-rule}
84 | ===================================
85 |
86 | The @extend rule declares
87 | that a matched element must act as if it had the necessary qualities to match another specified selector.
88 | Its syntax is:
89 |
90 | @extend <91 | 92 | The ''@extend'' rule is only allowed inside of style rules. 93 | In any other context, an ''@extend'' rule is invalid. 94 | An ''@extend'' rule modifies the way that selector matching works 95 | for the elements matched by the style rule the ''@extend'' selector is inside of, 96 | known as the extended elements for that rule. 97 | 98 | The argument to ''@extend'' is the extension selector. 99 | The rule's extended elements must, 100 | for the purpose of determining if selectors match them, 101 | act as if they had the necessary features/state/etc to match the extension selector, 102 | in addition to their pre-existing features/state/etc. 103 | 104 |>;
108 | .serious-error { 109 | @extend .error; 110 | } 111 |112 | 113 | All elements matching the ''.serious-error'' selector 114 | must act as if they also had an "error" class 115 | for the purpose of matching selectors, 116 | regardless of what their actual set of classes is. 117 |
134 | .error { 135 | color: red; 136 | } 137 | 138 | @media (width > 600px) { 139 | .serious-error { 140 | @extend .error; 141 | font-weight: bold; 142 | } 143 | 144 | .error { 145 | width: 100%; 146 | } 147 | } 148 |149 | 150 | Then the ''.serious-error'' elements only act as if they have an
error
class
151 | when the page's width is greater than ''600px''.
152 | 159 | .my-button { 160 | @extend button; 161 | } 162 |163 | 164 | Any elements with
class=my-button
receive the same styling as actual button elements,
165 | as if they had a tagname of 170 | .perma-pressed-button { 171 | @extend .button:active; 172 | } 173 |174 | 175 | Any ''.perma-pressed'' elements are styled as if they were '':active'', 176 | so that any styling applied to "pressed" buttons via '':active'' rules applies to them as well. 177 |
186 | .red-text { color: red; } 187 | .blue-text { color: blue; } 188 | 189 | #sidebar { @extend .red-text; } 190 | div { @extend .blue-text; } 191 |192 | 193 | A naive author looking at the code and wondering how a
<div id=sidebar>
element would be styled
194 | might assume that it gets red text,
195 | as an ID selector is used to ''@extend'' the ''.red-text'' class,
196 | versus a much less specific tagname selector.
197 | However, this is wrong--
198 | the element gets blue text,
199 | as the ''.red-text'' and ''.blue-text'' rules have equal specificity,
200 | and the ''.blue-text'' rule appears later in the stylesheet.
201 | The specificity of the rules that caused the element to match ''.red-text'' or ''.blue-text'' are irrelevant here.
202 |
203 | While this may in some cases be confusing,
204 | it can also be a great benefit in some cases.
205 | For example,
206 | an author can define a lot of styles with simple, one-class (or one placeholder selector) rules,
207 | effectively ignoring specificity entirely,
208 | then apply them via longer, much more specific selectors,
209 | using ''@extend'' to invoke the behavior of the simpler rules.
210 | This can allow an author to avoid many of the specificity problems of using IDs in rules, for example.
211 | 229 | .error { 230 | color: red; 231 | } 232 | 233 | .serious-error { 234 | @extend .error; 235 | font-weight: bold; 236 | } 237 | 238 | .super-serious-error { 239 | @extend .serious-error; 240 | animation: flashing 1s infinite; 241 | } 242 |243 | 244 | is equivalent to the following code without ''@extend'': 245 | 246 |
247 | .error, .serious-error, .super-serious-error { 248 | color: red; 249 | } 250 | 251 | .serious-error, .super-serious-error { 252 | font-weight: bold; 253 | } 254 | 255 | .super-serious-error { 256 | animation: flashing 1s infinite; 257 | } 258 |259 |
278 | .media-block { 279 | overflow: auto; 280 | } 281 | .media-block > img { 282 | float: left; 283 | } 284 | ... 285 | 286 | .image-post { 287 | @extend .media-block; 288 | ... /* additional styles to tweak the display */ 289 | } 290 |291 |
class=media-block
--
298 | but this isn't obvious from the code.
299 | It's easy for later maintainers of the file to accidentally use ''.media-block'' directly on an element,
300 | and modify it for their own uses
301 | (after all, if they search the codebase, they'll find no elements on the page using it!),
302 | perhaps accidentally breaking elements using it in ''@extend''.
303 |
304 | To avoid situations like this,
305 | and make it more clear that one is developing a "generic"/"functional"/"structural" set of styles,
306 | the placeholder selector can be used.
307 | Its syntax is similar to a class selector,
308 | but is prefixed by a ''%'' (U+0025 PERCENT SIGN)
309 | rather than a period.
310 |
311 | 315 | %media-block { 316 | overflow: auto; 317 | } 318 | %media-block > img { 319 | float: left; 320 | } 321 | ... 322 | 323 | .image-post { 324 | @extend %media-block; 325 | } 326 |327 |
2 | Title: CSS Filter Rule 3 | Shortname: css-filter-rule 4 | Level: 1 5 | Status: UD 6 | Group: CSSWG 7 | Work Status: exploring 8 | URL: http://tabatkins.github.io/specs/css-filter-rule/ 9 | Editor: Tab Atkins-Bittner, Google, http://xanthir.com/contact/ 10 | Abstract: The CSS 'filter' property allows an author to apply a number of useful visual filters to an element. Unfortunately, CSS only provides a few built-in filters for direct use; for anything more advanced, an author has to write an SVG document to define a <{filter}> element and then reference it via URL. This specification defines the ''@filter'' rule, which allows complex filters to be defined in a CSS stylesheet, avoiding the need to write a separate document in a different language. 11 |12 | 13 | Introduction {#intro} 14 | ===================== 15 | 16 | This spec is a very rough draft. I'm not gonna try for precise wording here; you'll get the gist. Details can be nailed down when we take this seriously. 17 | 18 | Defining Complex Filters in CSS: the ''@filter'' rule {#filter-rule} 19 | ==================================================================== 20 | 21 | The syntax of an ''@filter'' rule is: 22 | 23 |
24 | @filter = @filter <26 | 27 | The ''@filter'' rule accepts a handful of descriptors, 28 | described in later subsections, 29 | but is mostly filled by other filter primitive rules, 30 | such as ''@blend''. 31 | The presense of unknown descriptors, 32 | or at-rules other than filter primitive rules, 33 | are invalid and cause those descriptors/rules to be ignored, 34 | but do not make the ''@filter'' rule invalid. 35 | 36 | Note: Equivalents of filterUnits and primitiveUnits are intentionally not included. 37 | The *Units properties are a weird SVG-ism caused by the fact that they only have two units - integers and percentages. 38 | CSS doesn't need this. 39 | 40 | Filter Errors {#filter-errors} 41 | ------------------------------ 42 | 43 | Some mistakes in defining a ''@filter'' rule or its contents can cause a filter error. 44 | When a ''@filter'' rule or its contents cause a filter error, 45 | the ''@filter'' rule represents the null filter, 46 | regardless of what else it specifies. 47 | 48 | The null filter has no effect-- 49 | its output is exactly equivalent to its input. 50 | 51 | Referring to ''@filter'' Rules {#refs} 52 | -------------------------------------- 53 | 54 | Issue: I'm currently requiring filter names to be <> { < > } 25 |
62 | Name: position 63 | For: @filter 64 | Value: <67 | 68 |> 65 | Initial: -10% -10% 66 |
69 | Name: size 70 | For: @filter 71 | Value: <<'background-size'>> 72 | Initial: 120% 120% 73 |74 | 75 | Controlling the Resolution of a Filter: the '@filter/resolution' descriptor {#filter-resolution} 76 | ----------------------------------------------------------------------------------------------- 77 | 78 |
79 | Name: resolution 80 | For: @filter 81 | Value: auto | <84 | 85 | 86 | Using Variable References in ''@filter'' Descriptors {#vars} 87 | ============================================================ 88 | 89 | All of the at-rules defined in this specification allow variable references 90 | (the ''var()'' function) 91 | in their descriptors, 92 | in addition to whatever else their syntax states. 93 | During parsing, these are interpreted identically to the use of ''var()'' in CSS properties-- 94 | they "turn off" syntax validation during parsing, 95 | reverting the descriptor to containing an arbitrary token stream. 96 | 97 | Variables are substituted at time-of-use, 98 | based on the values of custom properties on the element referencing the ''@filter'' rule. 99 | 100 | Note: Thus, a single ''@filter'' rule can have its variables filled in with multiple different values, 101 | if it's referenced by multiple different elements. 102 | Each reference is a separate "instance" for this purpose. 103 | 104 | Note: This should also work for ''@apply'' in the same way. 105 | Need to generalize/define the concept of "variable reference" to include that. 106 | 107 | 108 | Filter Primitive Rules {#filter-primitive} 109 | ========================================== 110 | 111 | The filter primitive rules are a set of at-rules that define the behavior of a filter. 112 | They're only valid within the top-level of an ''@filter'' rule; 113 | if found anywhere else, they're invalid and must be ignored. 114 | 115 | Common Descriptors {#common} 116 | ---------------------------- 117 | 118 | All filter primitive rules accept the following descriptors, 119 | and interpret them in the same way: 120 | 121 |>{1,2} 82 | Initial: auto 83 |
122 | Name: position 123 | For: @blend 124 | Value: <127 | 128 |> 125 | Initial: -10% -10% 126 |
129 | Name: size 130 | For: @blend 131 | Value: <<'background-size'>> 132 | Initial: 120% 120% 133 |134 | 135 | These two are interpreted the same as for ''@filter''. 136 | 137 |
138 | Name: in 139 | For: @blend 140 | Value: auto | source-graphic | source-alpha | background-image | background-alpha | fill-paint | stroke-paint | <143 | 144 | The 'in' descriptor specifies what the input to the filter is. 145 | Values are defined as follows: 146 | 147 |> 141 | Initial: auto 142 |
168 | Name: result 169 | For: @blend 170 | Value: none | <173 | 174 | The 'result' descriptor gives the output of a filter primitive rule a name, 175 | so it can be referred to by later filter primitive rules in the same ''@filter'' rule. 176 | 177 | Note: In most common cases it is not necessary to specify this, 178 | as the value of one filter primitive rule 179 | is fed directly into the following filter primitive rule by default. 180 | 181 | Compositing Two Images: the ''@blend'' filter primitive rule {#at-blend} 182 | ======================================================================== 183 | 184 | The @blend rule composites two inputs together into a single output. 185 | 186 |> 171 | Initial: none 172 |
187 | Name: in2 188 | For: @blend 189 | Value: <<'in'>> 190 | Initial: auto 191 |192 | 193 | The ''@blend'' rule requires two inputs. 194 | The '@blend/in2' descriptor specifies the second input. 195 | 196 |
197 | Name: mode 198 | For: @blend 199 | Value: normal | multiply | screen | darken | lighten 200 | Initial: normal 201 |202 | 203 | The '@blend/mode' descriptor specifies how the two inputs are to be blended together. 204 | The values are defined in the SVG spec. 205 | -------------------------------------------------------------------------------- /css-font-display/index.bs: -------------------------------------------------------------------------------- 1 |
2 | Title: CSS Font Display Controls Module Level 1 3 | Status: UD 4 | Group: CSSWG 5 | Work Status: abandoned 6 | Shortname: css-font-display 7 | Level: 1 8 | Editor: Tab Atkins, Google, http://xanthir.com 9 | Editor: Kenji Baheux, Google 10 | Abstract: This spec introduces a new ''@font-face'' descriptor for controlling how a downloadable font renders before it is fully loaded. It's intended that this spec be merged into the Fonts spec, likely Fonts Level 4. 11 | ED: https://tabatkins.github.io/specs/css-font-display/ 12 | Warning: replaced by https://drafts.csswg.org/css-fonts-4/#font-display-desc 13 |14 | 15 | Introduction {#intro} 16 | ===================== 17 | 18 | When using downloadable webfonts via ''@font-face'', 19 | the user agent needs to know what to do while the font is actively loading. 20 | Most web browsers have adopted some form of timeout: 21 | 22 |
Browser 26 | | Timeout 27 | | Fallback 28 | | Swap 29 | |
---|---|---|---|
Chrome 35+ 32 | | 3 seconds 33 | | yes 34 | | yes 35 | |
Opera 37 | | 3 seconds 38 | | yes 39 | | yes 40 | |
Firefox 42 | | 3 seconds 43 | | yes 44 | | yes 45 | |
Internet Explorer 47 | | 0 seconds 48 | | yes 49 | | yes 50 | |
Safari 52 | | 3 seconds 53 | | yes 54 | | yes 55 | |
146 | Name: font-display 147 | Value: auto | block | swap | fallback | optional 148 | Initial: auto 149 | For: @font-face 150 |151 | 152 | Note: For all of these values, 153 | user agents may use slightly different durations, 154 | or more sophisticated behaviors that can't be directly expressed in the 'font-display' syntax, 155 | in order to provide more useful behavior for their users. 156 | They may also provide the ability for users to override author-chosen behavior 157 | with something more desirable; 158 | for example, forcing all fonts to have a ''0s'' block period. 159 | 160 |
291 | Name: font-display 292 | Value: auto | block | swap | fallback | optional 293 | Initial: auto 294 | For: @font-feature-values 295 |296 | 297 |
3 | Status: ED 4 | Shortname: css-nesting 5 | Level: 1 6 | ED: http://tabatkins.github.io/specs/css-nesting/ 7 | Editor: Tab Atkins, Google, http://xanthir.com/contact/ 8 | Abstract: This module introduces the ability to nest one style rule inside another, with the selector of the child rule relative to the selector of the parent rule. This increases the modularity and maintainability of CSS stylesheets. 9 | Link Defaults: css-color-4 (property) color 10 | Warning: replaced by https://www.w3.org/TR/css-nesting-1/ 11 |12 | 13 |
42 | table.colortable td { 43 | text-align:center; 44 | } 45 | table.colortable td.c { 46 | text-transform:uppercase; 47 | } 48 | table.colortable td:first-child, table.colortable td:first-child+td { 49 | border:1px solid black; 50 | } 51 | table.colortable th { 52 | text-align:center; 53 | background:black; 54 | color:white; 55 | } 56 |57 |
63 | table.colortable { 64 | & td { 65 | text-align:center; 66 | &.c { text-transform:uppercase } 67 | &:first-child, &:first-child + td { border:1px solid black } 68 | } 69 | & th { 70 | text-align:center; 71 | background:black; 72 | color:white; 73 | } 74 | } 75 |76 |
105 | a, b { 106 | & c { color: blue; } 107 | } 108 |109 | 110 | is equivalent to 111 | 112 |
113 | :matches(a, b) c { color: blue; } 114 |115 |
125 | #a, .b { 126 | & c { color: blue; } 127 | } 128 |129 | 130 | Then in a DOM structure like 131 | 132 |
133 | <div id=a> 134 | <c>foo</c> 135 | </div> 136 |137 | 138 | the ''&'' selector has specificity [1,0,0] 139 | because it matches due to the ''#a'' selector, 140 | giving the entire ''color: blue'' rule a specificity of [1,0,1]. 141 |
199 | .foo { 200 | color: blue; 201 | & > .bar { color: red; } 202 | } 203 | /* equivalent to 204 | .foo { color: blue; } 205 | .foo > .bar { color: red; } 206 | */ 207 | 208 | .foo { 209 | color: blue; 210 | &.bar { color: red; } 211 | } 212 | /* equivalent to 213 | .foo { color: blue; } 214 | .foo.bar { color: red; } 215 | */ 216 | 217 | .foo, .bar { 218 | color: blue; 219 | & + .baz, &.qux { color: red; } 220 | } 221 | /* equivalent to 222 | .foo, .bar { color: blue; } 223 | :matches(.foo, .bar) + .baz, 224 | :matches(.foo, .bar).qux { color: red; } 225 | */ 226 |227 | 228 | But the following are invalid: 229 | 230 |
231 | .foo { 232 | color: red; 233 | .bar { color: blue; } 234 | } 235 | /* Invalid because there's no nesting selector */ 236 | 237 | .foo { 238 | color: red; 239 | .bar & { color:blue; } 240 | } 241 | /* Invalid because & isn't in the first compound selector */ 242 | 243 | .foo { 244 | color: red; 245 | &.bar, .baz { color: blue; } 246 | } 247 | /* Invalid because the second selector in the list doesn't 248 | contain a nesting selector. */ 249 |250 |
283 | @nest = @nest <285 | 286 | The ''@nest'' rule functions identically to a style rule: 287 | it starts with a selector, 288 | and contains declarations that apply to the elements the selector matches. 289 | The only difference is that the selector used in a ''@nest'' rule 290 | must be nest-containing, 291 | which means it contains a nesting selector in it somewhere. 292 | A list of selectors is nest-containing if all of its individual complex selectors 293 | are nest-containing. 294 | 295 |> { < > } 284 |
299 | .foo { 300 | color: red; 301 | @nest & > .bar { 302 | color: blue; 303 | } 304 | } 305 | /* equivalent to 306 | .foo { color: red; } 307 | .foo > .bar { color: blue; } 308 | */ 309 | 310 | .foo { 311 | color: red; 312 | @nest .parent & { 313 | color: blue; 314 | } 315 | } 316 | /* equivalent to 317 | .foo { color: red; } 318 | .parent .foo { color: blue; } 319 | */ 320 | 321 | .foo { 322 | color: red; 323 | @nest :not(&) { 324 | color: blue; 325 | } 326 | } 327 | /* equivalent to 328 | .foo { color: red; } 329 | :not(.foo) { color: blue; } 330 | */ 331 |332 | 333 | But the following are invalid: 334 | 335 |
336 | .foo { 337 | color: red; 338 | @nest .bar { 339 | color: blue; 340 | } 341 | } 342 | /* Invalid because there's no nesting selector */ 343 | 344 | .foo { 345 | color: red; 346 | @nest & .bar, .baz { 347 | color: blue; 348 | } 349 | } 350 | /* Invalid because not all selectors in the list 351 | contain a nesting selector */ 352 |353 | 354 | Mixing Nesting Rules and Declarations {#mixing} 355 | ----------------------------------------------- 356 | 357 | A style rule can have any number of nested style rules inside of it, 358 | of either type, 359 | intermixed with any number of declarations, 360 | in any order. 361 | 362 | The relative ordering of nested style rules and other declarations is important; 363 | it's possible for a given style rule and a nested style rule within it to match the same element, 364 | and if the specificity of the two rules is otherwise equivalent, 365 | the relative order in the stylesheet of the applicable declarations 366 | determines which declaration "wins" the cascade. 367 | 368 | 369 | CSS Object Model Modifications {#cssom} 370 | ======================================= 371 | 372 |
2 | Title: CSS Shadow Parts 3 | Shortname: css-shadow-parts 4 | Level: 1 5 | Group: CSSWG 6 | Status: UD 7 | Work Status: exploring 8 | URL: http://tabatkins.github.io/specs/css-shadow-parts/ 9 | Editor: Tab Atkins-Bittner, Google, http://xanthir.com/contact/ 10 | Abstract: This specification defines the ''::part()'' and ''::theme()'' pseudo-elements on shadow hosts, allowing shadow hosts to selectively expose chosen elements from their shadow tree to the outside page for styling purposes. 11 | Warning: replaced by https://drafts.csswg.org/css-shadow-parts/ 12 |13 | 14 |
15 | spec:selectors-4; 16 | type:selector; text::hover 17 | type:dfn; text:live profile 18 | type:dfn; text:structural pseudo-class 19 | spec:dom; type:dfn; for:/; text:shadow root 20 |21 | 22 | Introduction {#intro} 23 | ===================== 24 | 25 | Issue: This spec is intentionally a rough sketch at the moment. 26 | It should contain all the details necessary to evaluate the proposal, 27 | but is intentionally avoiding precise algorithms at the moment, 28 | to aid in easy comprehension 29 | and to, hopefully, discourage implementation from this sketch. 30 | 31 | Shadow DOM allows authors to separate their page into "components", 32 | subtrees of markup whose details are only relevant to the component itself, 33 | not the outside page. 34 | This reduces the chance of a style meant for one part of the page 35 | accidentally over-applying and making a different part of the page look wrong. 36 | However, this styling barrier also makes it harder for a page to interact with its components 37 | when it actually wants to do so. 38 | 39 | This specification defines the ''::part()'' and ''::theme()'' pseudo-elements, 40 | which allow an author to style specific, purposely exposed elements in a shadow tree 41 | from the outside page's context. 42 | In combination with custom properties, 43 | which let the outside page pass particular values 44 | (such as theme colors) 45 | into the component for it to do with as it will, 46 | these pseudo-elements allow components and the outside page 47 | to interact in safe, powerful ways, 48 | maintaining encapsulation 49 | without surrending all control. 50 | 51 | Motivation {#motivation} 52 | ------------------------ 53 | 54 | For obvious reasons, 55 | it's valuable to let the outside page style the internals of a shadow tree, 56 | at least in some limited ways. 57 | (The ubiquity of UA-specific pseudo-elements for the various input elements shows this.) 58 | 59 | The previous proposed method for doing so, 60 | the >>> combinator, 61 | turned out to be too powerful for its own good; 62 | it exposed too much of a component's internal structure to scrutiny, 63 | defeating some of the encapsulation benefits that using Shadow DOM brings. 64 | For this, 65 | and other performance-related reasons, 66 | the >>> combinator was eventually removed from the live profile. 67 | 68 | This left us with using custom properties as the only way to style into a shadow tree: 69 | the component would advertise that it uses certain custom properties to style its internals, 70 | and the outer page could then set those properties as it wished on the shadow host, 71 | letting inheritance push the values down to where they were needed. 72 | This works very well for many simple theming use-cases. 73 | 74 | However, there are some cases where this falls down. 75 | If a component wishes to allow arbitrary styling of something in its shadow tree, 76 | the only way to do so is to define hundreds of custom properties 77 | (one per CSS property they wish to allow control of), 78 | which is obviously ridiculous 79 | for both usability and performance reasons. 80 | The situation is compounded if authors wish to style the component differently 81 | based on pseudo-classes like '':hover''; 82 | the component needs to duplicate the custom properties used 83 | for each pseudo-class 84 | (and each combination, 85 | like '':hover:focus'', 86 | resulting in a combinatorial explosion). 87 | This makes the usability and performance problems even worse. 88 | 89 | We introduce ''::part()'' to handle this case much more elegantly and performantly. 90 | Rather than bundling everything into custom property names, 91 | the functionality lives in selectors and style rule syntax, 92 | like it's meant to. 93 | This is far more usable for both component authors 94 | and component users, 95 | should have much better performance, 96 | and allows for better encapsulation/API surface. 97 | 98 | Another interesting facet of using custom properties, 99 | however, 100 | is that inheritance doesn't stop at the first shadow tree. 101 | Unless explicitly blocked, 102 | a custom property inherits down thru nested trees, 103 | allowing authors to style deeply nested components 104 | as easily as they style directly-visible ones. 105 | The same considerations apply to this case, 106 | so we introduce ''::theme()'' to handle this. 107 | 108 | It's important to note that ''::part()'' and ''::theme()'' 109 | offer absolutely zero new theoretical power. 110 | They are not a rehash of the ''>>>'' combinator, 111 | they're simply a more convenient and consistent syntax 112 | for something authors can already do with custom properties. 113 | By separating out the explicitly "published" parts of an element 114 | (the shadow part map 115 | from the sub-parts that it merely happens to contain 116 | (the shadow theme map, 117 | it also helps with encapsulation, 118 | as authors can use ''::part()'' without fear of accidental over-styling. 119 | 120 | 121 | Exposing a Shadow Element: the <{html-global/part}> attribute {#part-attr} 122 | ============================================================= 123 | 124 | Any element in a shadow tree can have a part attribute. 125 | This is used to expose the element outside the shadow tree, 126 | and to "forward" sub-parts of the element 127 | (if it has its own shadow tree) 128 | to outside the shadow tree. 129 | 130 | The part attribute is parsed as a comma-separated list of part mappings. 131 | Each part mapping is one of: 132 | 133 |
ident
135 | :: Adds «[ ident → el ]» to the shadow root's shadow part map.
136 |
137 | : ident1 => ident2
138 | :: If el is a shadow host,
139 | and it's shadow root's shadow part map |partMap| [=map/contains=] ident1,
140 | then this adds «[ ident2 → |partMap|[ident1] ]» to the shadow root's shadow part map.
141 |
142 | : * => prefix*
143 | :: If el is a shadow host,
144 | then [=map/for each=] |ident| → |subEl| in el's shadow root's shadow part map,
145 | «[ prefix + |ident| → |subEl| ]» is added to the shadow root's shadow part map.
146 |
147 | : anything else
148 | :: Ignored for error-recovery / future compat.
149 | 181 | ::part() = ::part( <184 | 185 | The ''::part()'' pseudo-element only matches anything 186 | when the originating element is a shadow host. 187 | If the originating element's shadow root's shadow part map 188 | [=map/contains=] the specified <> ) 182 | ::theme() = ::theme( < > ) 183 |
part="label"
),
197 | you can select it with
198 | ''#the-button::part(label)''.
199 | part="label"
211 | anywhere in the entire document,
212 | no matter how deeply nested into shadow trees they are.
213 | <x-panel>
's internal confirm button had used something like
237 | part="confirm-button, * => confirm-*"
238 | to forward the button's internal parts up into the panel's own shadow part map,
239 | then a selector like
240 | ''x-panel::part(confirm-label)''
241 | would select just the one button's label,
242 | ignoring any other labels.
243 | 2 | Title: CSS Stacking Context Module Level 1 3 | Shortname: css-stacking-context 4 | Level: 1 5 | Status: UD 6 | Group: csswg 7 | ED: https://drafts.csswg.org/css-stacking-context/ 8 | Work Status: exploring 9 | Editor: Tab Atkins-Bittner, Google, http://xanthir.com/contact/, w3cid 42199 10 | Abstract: This module defines the painting model for CSS. 11 |12 | 13 | 30 | 31 |
32 | spec: css-backgrounds-3; type:dfn; 33 | text: background painting area 34 | text: background positioning area 35 | spec:css-break-4; type:dfn; text:fragment 36 |37 | 38 | Introduction {#intro} 39 | ===================== 40 | 41 | This section is not normative. 42 | 43 | Elements on a page can have many overlapping parts. 44 | This specification defines the precise order 45 | that every part of an element 46 | and the surrounding page 47 | is painted, 48 | so that things render above (or below) other things 49 | in a well-defined way. 50 | 51 | Painting Order {#order} 52 | ======================= 53 | 54 | The rendering structure of a document consists of 55 | a [=root canvas=], 56 | a [=document layer=] 57 | and any number of additional [=rendering layers=], 58 | and within each layer, 59 | a [=/list=] of one or more [=trees=] of [=CSS/boxes=] generated by [=CSS/elements=]. 60 | 61 | A canvas is a theoretically-infinite 2D field of color. 62 | The root canvas is the [=CSS/canvas=] 63 | upon which all of the document's content is rendered. 64 | Layers, and elements that generate stacking contexts, 65 | first render onto temporary [=CSS/canvases=] 66 | before being composited onto an ancestor canvas 67 | (ending with the [=root canvas=] for the document). 68 | 69 | A rendering layer 70 | is an ordered list of [=boxes=], 71 | where each layer is rendered fully atop all previous layers, 72 | and fully below all following layers. 73 | Within the layer, 74 | [=boxes=] and their descendants 75 | can potentially interweave their rendering with each other. 76 | The document layer is the layer 77 | containing the principal box of the document's root element; 78 | it is below all other [=rendering layers=]. 79 | 80 | In the following algorithms, 81 | a given box or fragment is only painted once, 82 | by whatever step attempts to paint it first. 83 | (This allows the algorithm to be written much simply, 84 | without elaborate guards to check against double-painting.) 85 | 86 | Issue: This is meant to be a reproduction and elaboration 87 | of the CSS2 "Elaborate Description of Stacking Contexts" algorithm, 88 | modified to account for where filter/clipping/compositing can happen, 89 | the existence of top layers, 90 | and the newer element/box/fragment hierarchy. 91 | Non-editorial changes beyond the above 92 | are unintentional and probably bugs. 93 | 94 | 95 |
2 | Title: CSS Sticky Scrollbars 3 | Shortname: css-sticky-scrollbars 4 | Level: 1 5 | Status: UD 6 | Group: CSSWG 7 | Work Status: abandoned 8 | ED: http://tabatkins.github.io/css-sticky-scrollbars/ 9 | Editor: Tab Atkins, Google, http://xanthir.com/contact 10 | Abstract: Scrollbars that "stick" to an edge! 11 | Warning: replaced by https://drafts.csswg.org/css-scroll-snap/ 12 |13 | 14 |
15 | spec: css-scroll-snap; type: dfn; 16 | text: scroll snap area 17 | text: snap 18 |19 | 20 | This Spec Has Been Superseded {#intro} 21 | ====================================== 22 | 23 | This spec has been superseded by other CSS technology. 24 | In particular, to implement a chatroom 25 | that "sticks" the scrollbar to the bottom of the scroller when you're near the bottom, 26 | staying there if you add new messages to the bottom, 27 | but not messing with your scroll position when you're scrolled elsewhere in the history, 28 | just use [[css-scroll-snap-1]]: 29 | 30 |
31 | .message-container { 32 | scroll-snap-type: proximity; 33 | } 34 | .message-container::after { 35 | content: ""; 36 | height: 0; 37 | overflow: hidden; 38 | display: block; 39 | scroll-snap-align: end; 40 | } 41 |42 | 43 | This creates a single scroll snap area in the message container, 44 | aligned with the very bottom of the container. 45 | If you scroll "near" the bottom, you'll snap to it; 46 | if you add more content to the message container 47 | (thus pushing the ::after further down), 48 | it'll automatically re-snap to it 49 | (because scroll containers have to re-snap to the same scroll snap area if it still exists); 50 | if you are scrolled somewhere else in the history, 51 | it won't do anything at all. 52 | 53 | The use-case of "stable scrolling", 54 | where you want "whatever you're currently looking at" to stay on the screen 55 | when things are added/removed/resized higher up in the scroll container, 56 | is handled by the Scroll Anchoring proposal 57 | currently making its way thru the standards process. 58 | -------------------------------------------------------------------------------- /css-toggle-states/index.bs: -------------------------------------------------------------------------------- 1 |
2 | Title: CSS Toggle States 3 | Group: CSSWG 4 | Status: UD 5 | Work Status: exploring 6 | ED: http://tabatkins.github.io/specs/css-toggle-states/Overview.html 7 | Shortname: css-toggle-states 8 | Level: 1 9 | Editor: Tab Atkins Jr., Google, http://xanthir.com/contact 10 | Abstract: This specification defines a way to associate a toggleable state with an element which can be used in Selectors to select an element, and declarative ways to set and modify the state on the element. 11 | Ignored Terms:14 | 15 |, , 12 | Warning: replaced by http://tabatkins.github.io/css-toggle/ 13 |
16 | spec:selectors-4; type:selector; 17 | text::checked 18 | text::active 19 | text::hover 20 |21 | 22 |
<input type=checkbox>
has a "checked" state
30 | which toggles between true and false when the user activates the element,
31 | and which is selected by the '':checked'' pseudoclass.
32 |
33 | 37 | <ul class='ingredients'> 38 | <li><label><input type=checkbox><span>1 banana</span></label> 39 | <li><label><input type=checkbox><span>1 cup blueberries</span></label> 40 | ... 41 | </ul> 42 | <style> 43 | input[type='checkbox'] { 44 | display: none; 45 | } 46 | input[type='checkbox']:checked + span { 47 | color: silver; 48 | text-decoration: line-through; 49 | } 50 | </style> 51 |52 | 53 | In this markup, 54 | one can cross out ingredients as they're used in the recipe 55 | by simply clicking on them. 56 |
<input type=radio>
element.
63 | This state can be manipulated by activating the element or other specified elements,
64 | or by other user interactions.
65 |
66 |
67 | 71 | Name: toggle-states 72 | Value: none | <81 | 82 |> [cycle | sticky]? 73 | Initial: none 74 | Applies to: all elements 75 | Inherited: no 76 | Percentages: n/a 77 | Media: interactive 78 | Computed value: as specified 79 | Animatable: no 80 |
83 | Name: toggle-initial 84 | Value: <93 | 94 | The 'toggle-states' property controls whether an element has toggleable state or not. 95 | 96 |> 85 | Initial: 0 86 | Applies to: all elements 87 | Inherited: no 88 | Percentages: n/a 89 | Media: interactive 90 | Computed value: as specified 91 | Animatable: no 92 |
127 | <ul class='ingredients'> 128 | <li>1 banana 129 | <li>1 cup blueberries 130 | ... 131 | </ul> 132 | <style> 133 | li { 134 | toggle-states: 2; 135 | } 136 | li:checked { 137 | color: silver; 138 | text-decoration: line-through; 139 | } 140 | </style> 141 |142 | 143 | The effect is identical to what was specified in the Introduction example, 144 | except the markup is much simpler and more semantic. 145 |
158 | Name: toggle-group 159 | Value: none | <168 | 169 | By default, each toggleable element's toggle state is independent; 170 | incrementing one has no effect an any other. 171 | The 'toggle-group' property allows elements to link their toggle states together 172 | by declaring them to be part of a named toggle group, 173 | such that only one can have a non-zero toggle state at a time, 174 | similar to HTML's> 160 | Initial: none 161 | Applies to: all elements 162 | Inherited: no 163 | Percentages: n/a 164 | Media: interactive 165 | Computed value: as specified 166 | Animatable: no 167 |
<input type=radio>
element.
175 | Each [=toggle group=] on a page is identified by a unique <197 | .tab { 198 | toggle-states: 2 sticky; 199 | toggle-group: "tabs"; 200 | toggle-share: select(attr(for idref)); 201 | } 202 | .panel { 203 | toggle-states: 2 sticky; 204 | toggle-group: "panels"; 205 | } 206 | .tab:checked { 207 | /* styling for the active tab */ 208 | } 209 | .panel:not(:checked) { 210 | display: none; 211 | } 212 |213 | 214 | Clicking on any tab will increment its toggle state from 0 to 1 215 | (and the ''sticky'' keyword will keep it at 1 if activated multiple times), 216 | while resetting the rest of the tabs' toggle states to 0. 217 | The same happens to the panels, 218 | using the 'toggle-share' property defined in a later section. 219 | The active tab and panel are styled and shown differently than the other tabs and panels. 220 |
223 | The name is global to the page. 224 | Should we have a way to specify more implicit groups? 225 | Maybe a ''parent'' keyword, 226 | or a way to scope names to a subtree? 227 | 228 | 229 |
233 | Name: toggle-share 234 | Value: none | <243 | 244 | By default, activating an element only increments its own toggle state. 245 | The 'toggle-share' property allows an element to additionally increment the toggle state of another element. 246 | 247 |> 235 | Initial: none 236 | Applies to: all elements 237 | Inherited: no 238 | Percentages: n/a 239 | Media: interactive 240 | Computed value: as specified 241 | Animatable: no 242 |
<label>
element,
270 | but not identical.
271 | 'toggle-share' causes the activation to be shared,
272 | rather than transferred like <label>
does.
273 | Additionally, this sharing only affects the toggle state,
274 | while <label
more strongly transfers the concept of "activating",
275 | affecting things such as click events and the '':hover'' pseudo-class.
276 |
277 |
278 | 302 | #foo { 303 | toggle-states: 2; 304 | toggle-initial: 1; 305 | } 306 | #foo:checked { 307 | toggle-states: none; 308 | } 309 |310 |
2 | Title: CSS When/Else Rules 3 | Shortname: css-when-else 4 | Level: 1 5 | Status: UD 6 | Group: CSSWG 7 | Work Status: exploring 8 | URL: https://tabatkins.github.io/specs/css-when-else/ 9 | Editor: Tab Atkins-Bittner 10 | Abstract: A proposal to extend the concept of CSS conditional rules to arbitrary when/else chains, and supporing this, a proposal to unify the disparate conditional rules into a single grammar. 11 | Ignored Terms:13 | 14 |12 |
15 | spec: css-conditional-3 16 | type: dfn; text: conditional group rule 17 |18 | 19 | Introduction {#intro} 20 | ===================== 21 | 22 | Writing complex media queries or supports queries is difficult, 23 | particularly when you want to do Thing A in one circumstance, 24 | Thing B in another circumstance, 25 | and Thing C otherwise. 26 | This requires carefully crafting your conditional rules to exclude anything matching the other rules, 27 | while also making sure you're not accidentally over-excluding things and leaving some situations unmatched. 28 | 29 | This spec proposes two things to fix this problem. 30 | First, it proposes an ''@when'' rule, 31 | which generalizes the concept of a conditional rule. 32 | Anything you can express in an existing conditional rule 33 | can be expressed in ''@when'', 34 | it just has to be wrapped in an appropriate function 35 | to declare what kind of condition it is. 36 | This allow authors to easily combine multiple types of queries, 37 | such as media queries and supports queries, 38 | in a single boolean expression. 39 | Without this, 40 | authors must rely on nesting separate conditional rules, 41 | which is harder to read and write, 42 | presupposes the conditions are to be conjoined with the "and" boolean relation 43 | (with no easy way to indicate anything else), 44 | and restricts their utility in the proposed conditional rule chains. 45 | 46 | Second, it proposes the introduction of ''@else'' rules, 47 | which follow conditional rules 48 | and automatically qualify their conditions as you'd expect, 49 | such that at most one rule in an conditional rule chain is chosen as active. 50 | 51 | Generalized Conditional Rules: the ''@when'' rule {#when-rule} 52 | ========================================================== 53 | 54 | The @when at-rule is a conditional group rule 55 | that generalizes the individual conditional group rules 56 | such as ''@media'' and ''@supports''. 57 | It is defined as: 58 | 59 |
60 | @when <64 | 65 | Where <> { 61 | < > 62 | } 63 |
75 | media() = media( [ <78 | 79 | A ''media()'' or ''supports()'' function is associated the boolean result 80 | that its contained condition is associated with. 81 | 82 | Chained Conditionals: the ''@else'' rule {#else-rule} 83 | ===================================================== 84 | 85 | Usually, conditional group rules are independent; 86 | each one has a separate condition 87 | evaluated without direct reference to any other rule, 88 | and decides whether or not to apply its contained rules 89 | based solely on its condition. 90 | 91 | This is fine for simple conditions, 92 | but makes it difficult to write a collection of conditionals that are meant to be mutually exclusive; 93 | authors have to very carefully craft their conditions to not activate when the other rules are meant to, 94 | and make sure the collection of conditionals don't accidentally all exclude some situation 95 | which is then left unstyled. 96 | 97 | The @else rule is a conditional group rule 98 | used to form conditional rule chains, 99 | which allow multiple conditional rules to be provided 100 | and guarantee that at most one of them will evaluate their condition as true. 101 | It is defined as: 102 | 103 |> | < > | < > ] ) 76 | supports() = supports( < > ) 77 |
104 | @else <108 | 109 | ''@else'' is interpreted identically to ''@when''. 110 | If its <>? { 105 | < > 106 | } 107 |
138 | @when media(width >= 400px) and media(pointer: fine) and supports(display: flex) { 139 | /* A */ 140 | } @else supports(caret-color: pink) and supports(background: double-rainbow()) { 141 | /* B */ 142 | } @else { 143 | /* C */ 144 | } 145 |146 | 147 | Exactly one of the preceding rules will be chosen, 148 | even tho the second rule 149 | doesn't exclude large widths, fine points, or flexbox support, 150 | and the last rule 151 | doesn't specify anything at all. 152 | 153 | To achieve the same result without conditional rule chains, 154 | you'd need to write: 155 | 156 |
157 | @media (width >= 400px) and (pointer: fine) { 158 | @supports (display: flex) { 159 | /* A */ 160 | } 161 | @supports not (display: flex) { 162 | @supports (caret-color: pink) and (background: double-rainbow()) { 163 | /* B */ 164 | } 165 | @supports not ((caret-color: pink) and (background: double-rainbow())) { 166 | /* C */ 167 | } 168 | } 169 | } 170 | @media not ((width >= 400px) and (pointer: fine)) { 171 | @supports (caret-color: pink) and (background: double-rainbow()) { 172 | /* B */ 173 | } 174 | @supports not ((caret-color: pink) and (background: double-rainbow())) { 175 | /* C */ 176 | } 177 | } 178 |179 | 180 | This is simultaneously impossible to read, 181 | requires significant duplication of both conditions and contents, 182 | and is very difficult to write correctly 183 | (I wrote it wrong twice while producing this example). 184 | If the conditions got any more complicated 185 | (which is not unusual in real-world content), 186 | the example would get significantly worse. 187 |
2 | Title: CSS Will Change Module Level 1 3 | Shortname: css-will-change 4 | Level: 1 5 | Status: ED 6 | Group: CSSWG 7 | Work Status: exploring 8 | ED: http://tabatkins.github.io/specs/css-will-change/ 9 | Abstract: This document defines the 'will-change' property, which allows an author to inform the UA ahead of time of what kinds of changes they are likely to make to an element. This allows the UA to optimize how they handle the element ahead of time, performing potentially-expensive work preparing for an animation before the animation actually begins. 10 | Editor: Tab Atkins Jr., Google Inc., http://xanthir.com/contact/ 11 | Warning: replaced by http://dev.w3.org/csswg/css-will-change/ 12 |13 | 14 |
42 | Name: will-change 43 | Value: auto | <51 | 52 |># 44 | Initial: auto 45 | Applies to: all elements 46 | Inherited: no 47 | Percentages: n/a 48 | Media: all 49 | Computed value: specified value 50 |
<animateable-feature> = scroll-position | contents | <53 | 54 | The 'will-change' property provides a rendering hint to the user agent, 55 | stating what kinds of changes the author expects to perform on the element. 56 | This allows the user agent to perform ahead-of-time any optimizations necessary for rendering those changes smoothly, 57 | avoiding “jank” when the author does begin changing or animating that feature. 58 | 59 | Values have the following meanings: 60 | 61 |>
5 | I don't feel like duplicating this information between the README and the index page, 6 | so if you want to know the list of specs in this repository, 7 | look at the README. 8 |
9 | xoxo, Tab 10 | -------------------------------------------------------------------------------- /layout-transitions/index.bs: -------------------------------------------------------------------------------- 1 |
2 | Title: Layout Transition Primitives 3 | Status: UD 4 | Group: CSSWG 5 | Work Status: exploring 6 | ED: http://tabatkins.github.io/specs/layout-transitions/ 7 | Shortname: layout-transitions 8 | Level: 1 9 | Editor: Shane Stephens, Google, shanestephens@google.com 10 | Editor: Tab Atkins Jr., Google, http://xanthir.com/contact/ 11 | Abstract: Primitive JavaScript operations to enable layout transition effects. 12 | Default Highlight: javascript 13 | Ignored Terms: absolutely positioned 14 | Warning: replaced by https://tabatkins.github.io/specs/css-shared-element-transitions 15 |16 | 17 |
18 | spec:css-images-4; type:function; text:element() 19 |20 | 21 |
myDiv
from an initial laid out position to a new position:
60 |
61 | 62 | myDiv.suspendPainting(); 63 | CSS.elementSources.myDivSnapshot = myDiv.snapshot(); 64 | var div = document.createElement('div'); 65 | div.style.position = 'absolute'; 66 | div.style.left = myDiv.offsetLeft + 'px'; 67 | // ... 68 | div.style.backgroundImage = 'element(myDivSnapshot)'; 69 | document.body.appendChild(div); 70 | // perform layout 71 | div.animate({left: myDiv.offsetLeft, ... }, 1).source.onEnd(function() { 72 | myDiv.resumePainting(); 73 | div.remove(); 74 | }); 75 |76 |
87 | container.suspendPainting(); 88 | CSS.elementSources.afterDivSnapshot = afterDiv.snapshot(); 89 | // .. create and insert snapshot element (see previous example) 90 | container.appendBefore(afterDiv, newDiv); 91 | var bounds = newDiv.recastElement(); 92 | new ParGroup([ 93 | bounds.animate([{height: 0}, {height: bounds.height}], 1), 94 | div.animate({top: afterDiv.top}, 1) 95 | ]).source.onEnd(function() { 96 | myDiv.resumePainting(); 97 | div.remove(); 98 | }); 99 |100 |
109 | myDiv.suspendPainting(); 110 | CSS.elementSources.before = myDiv.snapshot(); 111 | // .. create and insert snapshot element (see previous example) 112 | // perform layout 113 | CSS.elementSources.after = myDiv.snapshot(); 114 | div.style.transition = 'background-image 1s'; 115 | div.style.backgroundImage = 'element(after)'; 116 | setTimeout(function() { 117 | myDiv.resumePainting(); 118 | div.remove(); 119 | }, 1000); 120 |121 |
undefined
.
218 |
219 | OpaqueImageSnapshot
objectundefined
.
286 | 289 | Is there any way for a snapshot to fail? 290 | Deleting the element before it's rendered? 291 | 292 |
ElementBounds
Object2 | Title: The QRCODE Image Format 3 | Shortname: qrcode 4 | Level: 1 5 | Status: DREAM 6 | Repository: tabatkins/specs 7 | URL: https://tabatkins.github.io/specs/qrcode/ 8 | Editor: Tab Atkins-Bittner, https://xanthir.com 9 | Abstract: The "QR Code", invented in the 1990s, has emerged in recent years as the clear winner of the "encode small but complex data, especially URLs, for phones to read" format wars. All phone OSes have built-in ways to read them, and to generate them, but that generation capability isn't exposed to websites. 10 | Abstract: 11 | Abstract: This specification defines a new image type, `image/qrcode`, which represents the data in a QR code in a declarative, compact manner which is easily readable and hand-writable. Browser and other rendering agents that understand this format are expected to automatically generate a QR code image representing the data in the resource. 12 | Complain About: accidental-2119 yes, missing-example-ids yes 13 | Markup Shorthands: markdown yes, css no 14 |15 | 16 | Introduction {#intro} 17 | ===================== 18 | 19 | Representing relatively small amounts of data in a machine-readable format 20 | has been important for decades. 21 | The humble UPC barcode format, 22 | for instance, 23 | allows storing numeric values 24 | up to ten decimal digits. 25 | 26 | As time has passed, tho, we've required larger amounts of data to be represented 27 | (even if the amounts are still modest; a few kilobytes at most), 28 | and better error correction 29 | (UPC barcodes can correct for *one* wrong digit, but no more). 30 | Many approaches have been proposed and even adopted in various industries, 31 | but the QR Code, 32 | first invented in Japan in the 90s for labeling parts in semi-automated factories, 33 | has emerged as the clear leader in overall usage across the world in recent years. 34 | 35 | While QR Code images are very usable in practice, 36 | they're difficult to *create*; 37 | beyond the ordinary difficulties of creating any image file programmatically, 38 | the QR format is non-trivial to follow, 39 | and the error-correction parts of the format are complex. 40 | However, all the devices a user can expect to *see* a QR Code 41 | have access to libraries for creating them. 42 | 43 | This specification defines a new QRCODE image format, 44 | and its associated MIME type `image/qrcode`, 45 | which represents the content of a QR code 46 | in a simple, human-readable, hand-authorable format. 47 | User agents, such as browsers, that recieve QRCODE images 48 | are expected to render them as QR codes. 49 | 50 | Notes {#notes} 51 | =============== 52 | 53 | Parameters of a QR code: 54 | * "version": a number between 1 and 40, dictating the overall size in pixels/"modules". The eventual size of the QR code is
version * 4 + 17
modules, plus additional margin space around the code (typically, at least one module in width).
55 | * error-correction level: what level of error correction is applied to the payload, dictating how much of the code can be lost/obscured/misread without corrupting the code itself. Four values, corresponding to "low" (7% recoverable loss), "medium" (14%), "quartile" (25%), or "high" (30%).
56 | * mask type: to help avoid large black or white "fields" in the code that make it harder to read or recognize, some of the data pixels can be inverted. There are 8 mask types, dictating which pixels are inverted and should be read as their opposite value.
57 | * encoding type: how to interpret the bits in the payload. Three commonly-used value: "numeric", "alphanumeric", and "bytes".
58 | * Numeric is the digits 0-9.
59 | * Alphanumeric is 0-9, A-Z (uppercase only), and some punctuation. Aka a subset of ASCII.
60 | * Bytes has been defined by specs as two different byte-based character encodings. In practice, treating it as UTF-8 seems to be modern practice and is widely recognized by scanners (possibly heuristically).
61 |
62 | Additional params I need to introduce:
63 |
64 | * module size: a number of CSS pixels dictating the side length of a module.
65 | * image size: a number of CSS pixels dictating the overall image size (which dictates the module size).
66 | * using both module and image size would just ignore one of them, I guess. Maybe use the larger one.
67 | * margin?: a CSS pixel size for the safe area around the code
68 |
69 | Image Format {#format}
70 | ============
71 |
72 | Every QRCODE image must begin with the bytes
73 | `51 52 43 4f 44 45 7b`
74 | (spelling "`QRCODE{`" in ASCII).
75 | Following that are zero or more non-`7d` bytes
76 | (the parameter bytes),
77 | followed by a `7d` byte ("}" in ASCII),
78 | optionally followed by `0d 0a` bytes (CR and NL in ASCII),
79 | followed by zero or more bytes with any value
80 | (the payload bytes).
81 |
82 | A QRCODE image that does not follow this byte format is [=invalid=].
83 |
84 | QRCODE{}https://example.com
,
87 | which will be rendered as QR Code image
88 | containing a link to example.com
.
89 |
90 | Alternately, the link could be rendered on a separate line for readability,
91 | like:
92 |
93 | 94 | QRCODE{} 95 | https://example.com 96 |97 | 98 | This is particular useful if several parameters are provided, 99 | like: 100 | 101 |
102 | QRCODE{version=5;error=low;mask=3;modulesize=5;margin=2} 103 | https://example.com 104 |105 |
2 | Title: SVG Parameters 3 | Shortname: svg-params 4 | Level: 1 5 | Status: UD 6 | Group: CSSWG 7 | Work Status: exploring 8 | URL: https://tabatkins.github.io/specs/svg-parameters/ 9 | Editor: Tab Atkins-Bittner, Google, http://xanthir.com/contact/ 10 | Abstract: This introduces "parameters" to SVG, which are a method of setting CSS custom properties in an external SVG document via the fragment on the referencing URL. This allows easy reuse of "templated" SVG images, which can be adapted to a site's theme color, etc. easily, without having to modify the source SVG. 11 | Ignored Terms: css value definition syntax 12 |13 | 14 |
15 | spec:selectors-4; type:selector; text::hover 16 | spec:html; type:element 17 | text: iframe 18 | text: a 19 | spec:fill-stroke-3; type:property; text:fill 20 |21 | 22 | Introduction {#intro} 23 | ===================== 24 | 25 | SVG is stylable with CSS, 26 | and when used inline in HTML, 27 | this capability can be very useful. 28 | For example, an SVG icon can take on a different color based on whether the user is hovering it or not, 29 | just by appling a '':hover'' rule to it that changes the 'fill' property. 30 | 31 | When the SVG is referenced in a way that doesn't allow selectors or CSS inheritance from the outer page to apply to it 32 | (such as embedding it via <{img}> or <{iframe}> in HTML), 33 | though, this functionality is lost. 34 | The only way to change the display of such "external" SVG images 35 | is to produce several of them, 36 | and change which image you're referencing. 37 | This incurs delay on the page as a new resource is downloaded, 38 | and disallows dynamic effects like CSS Transitions. 39 | 40 | SVG Parameters are a way to set CSS custom properties on an "external" SVG image, 41 | by passing them through a special fragment scheme on the URL. 42 | This gives a limited, but powerful, subset of the customizability that "inline" SVG images have 43 | to "external" SVG images. 44 | 45 | Setting an SVG Parameter {#setting} 46 | =================================== 47 | 48 | To "set" an SVG Parameter, 49 | a special "fragment identifier" must be used in the fragment of the URL used to reference. 50 | Several examples of existing "fragment identifiers" for SVG documents can be found in the SVG 1.1 specification. 51 | 52 | The syntax of an SVG parameter fragment identifier is: 53 | 54 |
param( <55 | 56 | (using the CSS value definition syntax). 57 | 58 |> < > )
http://example.com/image.svg#param(--text-color%20blue)
”.
61 | http://example.com/image.svg#param(--text-color%20blue)param(--bg-color%20white)
”.
71 | param() = param( <100 | 101 | Note: You may recognize this as identical to the syntax of the param() fragment identifer. 102 | 103 | Similarly to the param() fragment identifier, 104 | the ''param()'' <> < > )
117 | .foo { 118 | background-image: url("http://example.com/image.svg" param(--color var(--primary-color))); 119 | } 120 |121 |
136 | <svg> 137 | <g style="fill: var(--color);"> 138 | <path d="..." /> 139 | </g> 140 | </svg> 141 |142 |
158 | :root { 159 | --color2: var(--color, blue); 160 | } 161 |162 | 163 | In this example, if ''--color'' is provided via an SVG parameter, 164 | ''--color2'' will receive its value. 165 | If not, it will recieve the default ''blue'' value. 166 | In either case, ''--color2'' can be used in the SVG image's stylesheet unconditionally, 167 | secure in the knowledge that it will always have a value. 168 | 3. In a future level of the Custom Properties specification [[CSS-VARIABLES]], 169 | some "parent's value" functionality will be available to make the previous suggestion more usable: 170 | 171 |
172 | :root { 173 | --color: var(parent --color, blue); 174 | } 175 |176 | 177 | (This is an example syntax, and is not yet final.) 178 | 179 | By invoking the value of the --color property on the parent 180 | (which, on the root element, refers to the initial value), 181 | an author can avoid self-reference loops while retaining the same custom property name. 182 |
2 | Title: Unit Problems 3 | Shortname: unit-problems 4 | Status: LS 5 | URL: https://tabatkins.github.com/specs/unit-problems/ 6 | Editor: Tab Atkins-Bittner 7 | Abstract: An exploration of the problem with Houdini's Typed OM unit treatment, and a solution therein. 8 | Markup Shorthands: markdown yes 9 |10 | 11 | Introduction {#intro} 12 | ===================== 13 | 14 | The current [[css-typed-om-1]] approach to unitted valued is incoherent and inextensible. 15 | There are three distinct object "shapes" employed right now, 16 | and we're only handling two "types" of units - lengths and angles. 17 | The inconsistency makes it difficult for authors to predict how to interact with unitted values, 18 | and limits our ability to innovate in the future. 19 | The overall approach means we have to invent a large number of different interfaces 20 | to handle all the different types of unitted values CSS has, 21 | and completely fails to handle the planned addition 22 | of custom unit types. 23 | 24 | Inconsistency {#inconsistency} 25 | ------------------------------ 26 | 27 | We're currently using three different "shapes" for unitted value objects: 28 | 29 | 1. "Simple" lengths (corresponding to values like `5px` or `2em`) 30 | have a {value, unit} structure. 31 | 32 | 2. "Complex" lengths (corresponding to a `calc()` expressions) 33 | have a {px, pc, in, em, vw, ...} structure, 34 | where each field is an independent entry in the sum-of-values 35 | that makes up the calc(). 36 | 37 | 3. "Simple" angles have a {deg, rad, grad, turn} structure, 38 | where each field is linked; 39 | they all reflect a hidden internal value, 40 | so you can write to any field 41 | and then read the equivalent value in a different unit 42 | from another field. 43 | (Such as `x.deg = 180; print(x.turn) // .5`.) 44 | 45 | 46 | Explosion of Types {#type-explosion} 47 | ------------------------------------ 48 | 49 | While <
112 | interface CSSDimension { 113 | CSSDimension add(CSSDimension value); 114 | CSSDimension subtract(CSSDimension value); 115 | CSSDimension multiply(double value); 116 | CSSDimension divide(double value); 117 | static CSSDimension from(DOMString cssText); 118 | static CSSDimension from(double value, DOMString type); 119 | CSSDimension to(DOMString type); 120 | }; 121 | 122 | interface CSSSimpleDimension : CSSDimension { 123 | attribute double value; 124 | attribute DOMString type; 125 | }; 126 | 127 | interface CSSCalcLength : CSSDimension { 128 | attribute double? px; 129 | attribute double? percent; 130 | // ... 131 | static CSSDimension from(optional CSSCalcLengthDictionary dictionary); 132 | }; 133 | 134 | interface CSSCalcAngle : CSSDimension { 135 | attribute double deg; 136 | attribute double rad; 137 | attribute double grad; 138 | attribute double turn; 139 | static CSSDimension from(optional CSSCalcAngleDictionary dictionary); 140 | }; 141 | 142 | // same for <time> and <frequency>, 143 | // the only other types allowed in calc() currently 144 |145 | 146 | *All* unitted values share the {{CSSSimpleDimension}} interface. 147 | 148 | Arithmetic on {{CSSDimension}} values 149 | throws if the value types aren't compatible 150 | (just like, today, they'd throw if you passed a {{CSSAngleValue}} 151 | to {{CSSLengthValue/add()}}). 152 | Otherwise, it returns the appropriate {{CSSCalc*}} subclass. 153 | 154 | The new {{CSSDimension/to()}} method converts from one unit to another. 155 | It throws if the types aren't convertible 156 | (such as `px` to `deg`, but also `px` to `em`), 157 | or if the object is a {{CSSCalc*}} 158 | and some of its non-zero specified values aren't convertible 159 | (so `CSSCalcLength({px:5, in:1}).to("px")` is fine, 160 | but `CSSCalcLength({px:5, em:1}).to("px")` throws). 161 | Otherwise, 162 | it returns a new {{CSSSimpleDimension}} with the specified unit. 163 | 164 | Consistency {#consistency} 165 | -------------------------- 166 | 167 | All unitted values now use the same interface structure. 168 | You don't need to remember whether something is a <