Skip to content

Commit 3b20432

Browse files
committed
Incomplete first draft of cascade layers
1 parent 58446d2 commit 3b20432

File tree

1 file changed

+230
-4
lines changed

1 file changed

+230
-4
lines changed

css-cascade-5/Overview.bs

Lines changed: 230 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -828,6 +828,7 @@ Cascade Sorting Order</h3>
828828
can set defaults that are easily overridden by the outer context,
829829
while [=important=] declarations belonging to an [=encapsulation context=]
830830
can enforce requirements that cannot be overridden by the outer context.
831+
831832
<!--
832833
<dt id='cascade-scope'>Scope
833834
<dd>
@@ -856,14 +857,34 @@ Cascade Sorting Order</h3>
856857
is to match the behavior defined in CSS Levels 1 and 2,
857858
where style attributes simply have higher specificity than any other author rules. [[CSS2]]
858859
-->
860+
861+
<dt id='style-attr'>The Style Attribute
862+
<dd>
863+
Declarations that do not belong to a style rule
864+
(such as the <a href="https://www.w3.org/TR/css-style-attr/#interpret">contents of a style attribute</a>)
865+
take precedence over declarations that do belong to a style rule.
866+
<dt id='cascade-layering'>Layers
867+
<dd>
868+
Declarations can be explicitly assigned to a [=cascade layer=].
869+
Explicit layers are listed in the document order where they are first introduced.
870+
For the purpose of this step,
871+
any declaration not assigned to an explicit layer is added to an implicit final layer.
872+
873+
When comparing declarations that belong to different layers,
874+
then for [=normal=] rules the last declaration whose [=cascade layer=] is last wins,
875+
and for [=important=] rules the declaration whose [=cascade layer=] is first wins.
876+
877+
Note: This follows the same logic used for layering [=normal=] and [=important=] [=origins=],
878+
so that ''!important'' maintains the same semantic purpose.
879+
880+
Issue(w3c/csswg-drafts#5003): Where do Layers fit in the cascade?
881+
882+
Issue(w3c/csswg-drafts#4971): How do Layers interact with ''!important''?
883+
859884
<dt id='cascade-specificity'>Specificity
860885
<dd>
861886
The <a href="https://www.w3.org/TR/selectors/#specificity">Selectors module</a> [[!SELECT]] describes how to compute the specificity of a selector.
862887
Each declaration has the same specificity as the style rule it appears in.
863-
For the purpose of this step,
864-
declarations that do not belong to a style rule
865-
(such as the <a href="https://www.w3.org/TR/css-style-attr/#interpret">contents of a style attribute</a>)
866-
are considered to have a specificity higher than any selector.
867888
The declaration with the highest specificity wins.
868889

869890
<dt id='cascade-order'>Order of Appearance
@@ -1010,6 +1031,211 @@ Important Declarations: the ''!important'' annotation</h3>
10101031
</table>
10111032
</div>
10121033

1034+
<h3 id='layering'>
1035+
Cascade Layers</h3>
1036+
1037+
In the same way that [=cascade origins=] provide a balance of power
1038+
between user and author styles,
1039+
<dfn export>Cascade Layers</dfn> provide an explicit way
1040+
to balance concerns within a single origin.
1041+
Authors can create layers to represent element defaults,
1042+
third-party libraries, themes, components, overrides, and other styling concerns --
1043+
and re-order the cascade of layers in a deterministic way,
1044+
without altering selectors or specificity within each layer,
1045+
or relying on source-order to resolve conflicts across layers.
1046+
1047+
<div class="example">
1048+
For example, the following generates an explicit ''defaults'' layer,
1049+
with lower cascade weight than any un-layered styles:
1050+
1051+
<pre class='lang-css'>
1052+
audio {
1053+
/* speceficity of 0,0,1 - implicit (final) layer */
1054+
display: flex;
1055+
}
1056+
1057+
@layer defaults {
1058+
audio[controls] {
1059+
/* speceficity of 0,1,1 - explicit "defaults" layer */
1060+
display: block;
1061+
}
1062+
}
1063+
</pre>
1064+
1065+
The un-layered declarations on the ''audio'' element take precedence
1066+
over the explicitly layered declarations on ''audio[controls]'' --
1067+
even though the un-layered styles have a lower specificity,
1068+
and come first in the source order.
1069+
</div>
1070+
1071+
<h4 id="at-layer">
1072+
Layering Styles: the ''@layer'' rule</h4>
1073+
1074+
The <dfn at-rule id="at-ruledef-layer">@layer</dfn> rule
1075+
describes an explicit [=cascade layer=],
1076+
with the option to assign style rules as either a block or an import.
1077+
The syntax is:
1078+
1079+
<pre class='prod'>
1080+
@layer [ <<layer-ident>>? [ <<url>>; | {
1081+
<<stylesheet>>
1082+
} ]? ]!
1083+
</pre>
1084+
1085+
where the optional <dfn><<layer-ident>></dfn> is a
1086+
CSS <a href="https://www.w3.org/TR/CSS21/syndata.html#value-def-identifier">identifier</a>
1087+
that either matches an existing layer name, or defines a new named layer,
1088+
the optional [<<url>>;|{<<stylesheet>>}]
1089+
either gives the URL of the style sheet to be imported into that layer,
1090+
or contains style rules to be added to the layer.
1091+
1092+
Issue(w3c/csswg-drafts#5681): Is ''@layer'' the proper way to handle layered url imports?
1093+
1094+
<h5 id="layer-identifiers" class="no-toc">
1095+
Layer Identifiers</h5>
1096+
1097+
Layer identifiers are optional,
1098+
but provide a way to apply mutliple style blocks
1099+
to a single layer.
1100+
1101+
<div class="example">
1102+
<pre class='lang-css'>
1103+
@layer default url(headings.css);
1104+
@layer default url(links.css);
1105+
1106+
@layer default {
1107+
audio[controls] {
1108+
display: block;
1109+
}
1110+
}
1111+
</pre>
1112+
</div>
1113+
1114+
This also allows authors to establish a layer order in advance,
1115+
regardless of the order styles are added to each layer.
1116+
1117+
<div class="example">
1118+
<pre class='lang-css'>
1119+
@layer default;
1120+
@layer theme;
1121+
@layer components;
1122+
1123+
@layer theme url(theme.css);
1124+
1125+
@layer default {
1126+
audio[controls] {
1127+
display: block;
1128+
}
1129+
}
1130+
</pre>
1131+
1132+
See also [[#at-layers]]
1133+
</div>
1134+
1135+
<h5 id="nested-layers" class="no-toc">
1136+
Nested Layers</h5>
1137+
1138+
When multiple layer rules are nested,
1139+
internal layer identifiers are scoped to their parent layer.
1140+
1141+
<div class="example">
1142+
In this example,
1143+
the nested "framework default" layer is distinct
1144+
from the top-level "default" layer:
1145+
1146+
<pre class='lang-css'>
1147+
@layer default {
1148+
p { max-width: 70ch; }
1149+
}
1150+
1151+
@layer framework {
1152+
@layer default {
1153+
p { margin-block: 0.75em; }
1154+
}
1155+
1156+
@layer theme {
1157+
p { color: #222; }
1158+
}
1159+
}
1160+
</pre>
1161+
1162+
The resulting layers can be represented as a tree:
1163+
1164+
1. default
1165+
2. framework
1166+
1. default
1167+
2. theme
1168+
1169+
or as a flat list with nested identifiers:
1170+
1171+
1. default
1172+
2. framework default
1173+
3. framework theme
1174+
1175+
</div>
1176+
1177+
It is not possible for nested layers
1178+
to reference a layer identifier in an outer layer-scope,
1179+
but it is possible to reference nested layers
1180+
from an outer scope,
1181+
by combining identifiers with a full stop (. U+002E) character.
1182+
1183+
Issue: What is the appropriate syntax for nested layer identifiers?
1184+
1185+
<div class="example">
1186+
<pre class='lang-css'>
1187+
@layer framework {
1188+
@layer default {
1189+
p { margin-block: 0.75em; }
1190+
}
1191+
1192+
@layer theme {
1193+
p { color: #222; }
1194+
}
1195+
}
1196+
1197+
@layer framework.theme {
1198+
/* These styles will be added to the theme layer inside the framework layer */
1199+
blockquote { color: rebeccapurple; }
1200+
}
1201+
</pre>
1202+
</div>
1203+
1204+
<h5 id="unnamed-layers" class="no-toc">
1205+
Un-Named Layers</h5>
1206+
1207+
Layers without an identifier are also added to the layer order when invoked,
1208+
but only describe a single rule-block or file import --
1209+
without any external hook for re-arranging or adding styles.
1210+
This can be used to create "private" layers
1211+
that should not be manipulated or re-ordered
1212+
by other layer rules.
1213+
1214+
<div class="example">
1215+
In the following example,
1216+
additional styles can be added to the ''default'' layer,
1217+
but not the layer containing ''framework.css'':
1218+
1219+
<pre class='lang-css'>
1220+
@layer default url(headings.css);
1221+
@layer url(framework.css);
1222+
</pre>
1223+
</div>
1224+
1225+
Issue: Should un-named layers be allowed?
1226+
1227+
<h4 id="at-layers">
1228+
Layer-Ordering Shorthand: the ''@layers'' rule</h3>
1229+
1230+
The <dfn at-rule id="at-ruledef-layers">@layers</dfn> rule
1231+
describes a list of explicit [=cascade layers=],
1232+
in order from lowest to highest priority.
1233+
Its syntax is:
1234+
1235+
<pre class='prod'>
1236+
@layers <<custom-ident>> [, <<custom-ident>>]* ;
1237+
</pre>
1238+
10131239
<h3 id="preshint">
10141240
Precedence of Non-CSS Presentational Hints</h3>
10151241

0 commit comments

Comments
 (0)