@@ -1055,6 +1055,97 @@ aren't visible to anything outside of the [=mixin body=].
1055
1055
and the ''.warning'' rule would not be able to use them.
1056
1056
</div>
1057
1057
1058
+ Note as well that [=scoped environment variables=] do not have an element context,
1059
+ so they can't fully resolve values that require an element context,
1060
+ like ''em'' lengths or ''var()'' functions,
1061
+ at definition time.
1062
+ Instead, they'll be resolved at each point they're used,
1063
+ similar to an unregistered [=custom property=] .
1064
+
1065
+ <div class=example>
1066
+ For example, this mixin applies a size to an element, its parent, and its children.
1067
+ If an ''em'' length is used, all of these might be different values:
1068
+
1069
+ <xmp highlight=css>
1070
+ @mixin --triple-border(--size <length> ) {
1071
+ &, :has(&), & > * {
1072
+ border-width: env(--size);
1073
+ }
1074
+ }
1075
+ section {
1076
+ font-size: 16px;
1077
+ }
1078
+ section > h1 {
1079
+ font-size: 30px;
1080
+ @apply --triple-border(.5em);
1081
+ }
1082
+ section > h1 > small {
1083
+ font-size: 20px;
1084
+ }
1085
+ </xmp>
1086
+
1087
+ In this example,
1088
+ despite them all being set with the same ''env(--size)'' value,
1089
+ the `section` element has a border of ''8px'' ,
1090
+ the `h1` element has a border of ''15px'' ,
1091
+ and the `small` element has a border of ''10px'' .
1092
+
1093
+ There are some ways to work around this, if desired.
1094
+ For example, the value can be stored in a [=registered custom property=]
1095
+ with the appropriate type,
1096
+ so it resolves on one element and then inherits as the absolute value,
1097
+ or passed through a [=custom function=] with a typed argument.
1098
+
1099
+ <xmp highlight=css>
1100
+ @function --as-length(--arg <length> ) { result: var(--arg); }
1101
+ @mixin --triple-border(--size <length> ) {
1102
+ :has(&) {
1103
+ --triple-border-size: --as-length(env(--size));
1104
+ }
1105
+ &, :has(&), & > * {
1106
+ border-width: var(--triple-border-size);
1107
+ }
1108
+ }
1109
+ section {
1110
+ font-size: 16px;
1111
+ }
1112
+ section > h1 {
1113
+ font-size: 30px;
1114
+ @apply --triple-border(.5em);
1115
+ }
1116
+ section > h1 > small {
1117
+ font-size: 20px;
1118
+ }
1119
+ </xmp>
1120
+
1121
+ In the above code, the [=mixin parameter=]
1122
+ is set to a [=custom property=] on the parent element,
1123
+ where it's forced to resolve as a length
1124
+ due to being passed through the [=custom function=] .
1125
+ All the styles then use that [=custom property=]
1126
+ (via ''var()'' )
1127
+ rather than the [=mixin parameter=]
1128
+ (via ''env()'' ),
1129
+ so they all share the same already-resolved value.
1130
+
1131
+ (Note that this value is resolved on the parent element
1132
+ the [=custom property=] is defined on,
1133
+ becoming ''8px'' ,
1134
+ rather than resolving against the element the [=mixin=] is called on,
1135
+ which would give ''15px'' .
1136
+ That's an unavoidable limitation of this situation.)
1137
+ </div>
1138
+
1139
+ Issue: Do we want to try and figure out a way to have a mixin parameter
1140
+ "remember" what element it was called on,
1141
+ so it can resolve against that element consistently,
1142
+ rather than require these workarounds?
1143
+ I think that's inherently cyclic, tho--
1144
+ imagine an ''em'' length used to set 'font-size' on a parent element.
1145
+
1146
+
1147
+
1148
+
1058
1149
<!-- Big Text: @contents
1059
1150
1060
1151
████▌ ███▌ ███▌ █ █▌ █████▌ █████▌ █ █▌ █████▌ ███▌
@@ -1292,6 +1383,43 @@ as that's a meaningful value that an ''env()'' could resolve to,
1292
1383
I guess?
1293
1384
1294
1385
1386
+ <h4 id='dependent-envs'>
1387
+ Element-Dependent Values</h4>
1388
+
1389
+ A [=scoped environment variable=] can be defined
1390
+ (both explicitly, and implicitly via [=mixin=] parameters)
1391
+ that require knowledge about the element the style is being applied to,
1392
+ but ''env()'' can be used in locations that don't have an element context.
1393
+
1394
+ <div class=example>
1395
+ For example, in this trivial example
1396
+ an ''em'' value is passed to a mixin,
1397
+ but the argument is then used in the ''@media'' rule inside the mixin.
1398
+
1399
+ <pre highlight=css>
1400
+ @mixin --smaller(--size <length> : 800px, @contents) {
1401
+ @media (width <= env(--size)) {
1402
+ @contents;
1403
+ }
1404
+ }
1405
+ h1 {
1406
+ @apply --smaller {
1407
+ margin: 1em 0;
1408
+ }
1409
+ }
1410
+ </pre>
1411
+ </div>
1412
+
1413
+ When this situation occurs,
1414
+ if the value of the ''env()'' can be evaluated in its subsitution context at all,
1415
+ it evaluates according to the normal rules for that context.
1416
+ (For example, in a ''@media'' , ''em'' values resolve against the initial font size,
1417
+ rather than the font size of any particular element.)
1418
+
1419
+ If the value would be invalid in its substitution context,
1420
+ it's instead replaced with the [=guaranteed-invalid value=] .
1421
+ (For example, ''var()'' isn't allowed in a ''@media'' .)
1422
+
1295
1423
1296
1424
1297
1425
0 commit comments