Skip to content

Commit 8d381d8

Browse files
committed
[css-anchor-positioning] Separate out 'figure out the side' from 'generate fallbacks automatically' for the auto keywords. #8582
1 parent 9f39808 commit 8d381d8

File tree

1 file changed

+145
-75
lines changed

1 file changed

+145
-75
lines changed

css-anchor-position-1/Overview.bs

Lines changed: 145 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -540,101 +540,86 @@ This has two effects:
540540
for ''auto-same'',
541541
or the opposite side,
542542
for ''auto'').
543+
544+
That is, ''top: anchor(auto);'' is equivalent to ''top: anchor(bottom);'',
545+
while ''left: anchor(auto-same);'' is equivalent to ''left: anchor(left);'',
546+
etc.
543547
* If the element has ''position-fallback: none'',
548+
and the opposite [=inset property=] is ''top/auto'',
544549
it automatically gains a [=position fallback list=]
545550
that will flip it to the opposite side of the [=anchor element=]
546551
if necessary.
552+
See [[#fallback-automatic]] for details.
547553

548-
[=Automatic anchor positioning=] is only active
549-
if the opposite [=inset property=] is ''top/auto''.
550-
(For example, if an element had ''top: anchor(auto);'',
551-
it would have to also have ''bottom: auto;''.)
552-
If this is not the case,
553-
the ''anchor()'' function represents an [=invalid anchor function=],
554-
and the element does not use [=automatic anchor positioning=] in that axis.
555-
556-
When using [=automatic anchor positioning=],
557-
the ''anchor()/auto'' <<anchor-side>>
558-
behaves as the opposite side of the property it's used in.
559-
That is, when used in ''top: anchor(auto);'',
560-
it's equivalent to ''top: anchor(bottom);'';
561-
when used in ''bottom: anchor(auto);'',
562-
it's equivalent to ''bottom: anchor(top);'';
563-
etc.
564-
The ''anchor()/auto-same'' <<anchor-side>>
565-
behaves as the property it's used in:
566-
''top: anchor(auto-same);''
567-
is equivalent to ''top: anchor(top);'',
568-
etc.
569-
570-
Additionally,
571-
if the element has ''position-fallback: none'',
572-
[=automatic anchor positioning=] causes the element
573-
to gain a [=position fallback list=]
574-
consisting of two entries:
554+
<div class=example>
555+
For example, to position and size an element
556+
to exactly cover the target element:
575557

576-
* one containing all the base-style properties on the element
577-
that are valid to use in ''@try'' rules,
578-
with ''anchor()/auto''/''auto-same'' keywords
579-
resolved to their appropriate side.
580-
* one containing the same,
581-
but with the [=inset properties=] in each axis swapped,
582-
and the ''anchor()/auto''/''auto-same'' keywords
583-
resolved to the opposite sides as well.
558+
<pre class=lang-css>
559+
.cover {
560+
inset: anchor(auto-same);
561+
}
562+
</pre>
584563

585-
Note: If the element has a non-none 'position-fallback',
586-
these extra entries aren't added.
587-
Since the [=position fallback list=] styles
588-
override the "base" styles immediately,
589-
this will <em>usually</em> mean you wouldn't see a "base" ''anchor(auto)''
590-
show up in the final styles at all,
591-
but if that does happen
592-
(it's specified in a property
593-
that isn't overriden by anything in the [=position fallback list=]),
594-
the only effect of the ''anchor()/auto''/''auto-same''
595-
is to resolve to the appropriate side keyword.
564+
is equivalent to
565+
566+
<pre class=lang-css>
567+
.cover {
568+
top: anchor(top);
569+
right: anchor(right);
570+
bottom: anchor(bottom);
571+
left: anchor(left);
572+
}
573+
</pre>
574+
</div>
596575

597576
<div class=example>
598-
For example, the following code using [=automatic anchor positioning=]:
577+
When the opposite axis is ''top/auto'',
578+
the element automatically gains fallback behavior.
579+
For example:
599580

600-
<pre highlight=css>
601-
.foo {
602-
position: absolute;
603-
top: calc(.5em + anchor(--foo auto));
581+
<pre class=lang-css>
582+
.tooltip {
583+
position: fixed;
584+
anchor-default: --target;
585+
top: auto; /* initial value */
586+
bottom: calc(anchor(auto) + .3em);
604587
}
605588
</pre>
606589

607-
is equivalent to the following more verbose and explicit code:
590+
With the above code,
591+
the tooltip will default to positioning its bottom edge
592+
slightly away from the top edge of its anchor element,
593+
hovering just above it;
594+
but if that would make it overflow the top edge of the screen
595+
(aka the top of its [=inset-modified containing block=],
596+
which is the viewport in this case),
597+
it will automatically flip to the opposite side,
598+
as if you'd instead specified:
608599

609-
<pre highlight=css>
610-
.foo {
611-
position: absolute;
612-
position-fallback: --flip;
600+
<pre class=lang-css>
601+
.tooltip {
602+
position: fixed;
603+
position-fallback: --top-then-bottom;
604+
anchor-default: --target;
613605
}
614-
@position-fallback --flip {
606+
@position-fallback --top-then-bottom {
615607
@try {
616-
top: calc(.5em + anchor(--foo bottom));
617-
bottom: auto;
608+
top: auto;
609+
bottom: calc(anchor(top) + .3em);
618610
}
619611
@try {
620-
top: auto;
621-
bottom: calc(.5em + anchor(--foo top));
612+
top: calc(anchor(bottom) + .3em);
613+
bottom: auto;
622614
}
623615
}
624616
</pre>
625-
</div>
626617

627-
If the element uses [=automatic anchor positioning=] in both axises,
628-
it instead adds three entries to the [=position fallback list=]:
629-
one reversing just the block axis,
630-
one reversing just the inline axis,
631-
and finally one reversing both axises at once.
632-
633-
''anchor()/auto'' and ''anchor()/auto-same'' used <em>in</em> a ''@try'' rule
634-
cause the rule to insert multiple (2 or 4) sets of entries
635-
into the [=position fallback list=],
636-
as specified above,
637-
if they would validly trigger [=automatic anchor positioning=].
618+
If both axises trigger this behavior,
619+
it effectively gains four fallbacks,
620+
trying each combination of specified and opposing anchors
621+
to find one that won't trigger overflow.
622+
</div>
638623

639624

640625

@@ -734,8 +719,6 @@ only if all the following conditions are true:
734719
it's being used in an [=inset property=] in that axis.
735720
(For example, ''left'' can only be used in 'left', 'right',
736721
or a logical [=inset property=] in the horizontal axis.)
737-
* If its <<anchor-side>> keyword is ''auto'' or ''auto-same'',
738-
the opposite [=inset property=] is ''top/auto''.
739722
* There is a [=target anchor element=]
740723
for the element it's used on,
741724
and the <<anchor-element>> value specified in the function.
@@ -1107,6 +1090,93 @@ This limit must be <em>at least</em> five.
11071090
</pre>
11081091
</div>
11091092

1093+
Fallback and Automatic Positioning {#fallback-automatic}
1094+
----------------------------------
1095+
1096+
When an element uses an ''anchor()'' function
1097+
with an ''auto'' or ''auto-same'' <<anchor-side>> argument
1098+
in an [=inset property=],
1099+
and the opposite [=inset property=] is ''top/auto'',
1100+
the element is said to be trying to use <dfn>automatic anchor fallbacks</dfn>
1101+
in that axis.
1102+
1103+
If the element has ''position-fallback: none'',
1104+
and is trying to use [=automatic anchor fallbacks=] in one axis,
1105+
it automatically generates a [=position fallback list=]
1106+
consisting of two entries:
1107+
1108+
* the first entry contains all the base-style properties on the element
1109+
that are valid to use in ''@try'' rules,
1110+
with ''anchor()/auto''/''auto-same'' keywords
1111+
resolved to their appropriate side.
1112+
* one containing the same,
1113+
but with the [=inset properties=] in the affected axis swapped
1114+
(resolving the ''auto''/''auto-same'' keywords accordingly).
1115+
1116+
If the element uses [=automatic anchor positioning=] in both axises,
1117+
it instead adds four entries to the [=position fallback list=]:
1118+
one specifying the base styles, as above,
1119+
then one reversing just the block axis,
1120+
followed by one reversing just the inline axis,
1121+
followed by one reversing both axises at once.
1122+
1123+
Note: If the element has a non-none 'position-fallback',
1124+
these automatic fallbacks aren't generated.
1125+
Since the [=position fallback list=] styles
1126+
override the "base" styles immediately,
1127+
this will <em>usually</em> mean you wouldn't see a "base" ''anchor(auto)''
1128+
show up in the final styles at all,
1129+
but if that does happen
1130+
(it's specified in a property
1131+
that isn't overriden by anything in the [=position fallback list=]),
1132+
the only effect of the ''anchor()/auto''/''auto-same''
1133+
is to resolve to the appropriate side keyword.
1134+
1135+
[=Automatic anchor fallback=] can also be used as a shorthand
1136+
in ''@try'' blocks.
1137+
1138+
If applying an entry in the element's [=position fallback list=]
1139+
would cause the resulting styles
1140+
to satisfy the conditions of [=automatic anchor fallbacks=],
1141+
and the relevant ''anchor()'' function comes from a ''@try'' block
1142+
(rather than from the base styles),
1143+
then that entry of the [=position fallback list=]
1144+
must instead be treated as 2 or 4 consecutive entries,
1145+
generated as above.
1146+
1147+
(Otherwise, the ''auto'' or ''auto-same'' keywords
1148+
just resolve to the appropriate side,
1149+
with no additional effects.)
1150+
1151+
<div class=example>
1152+
For example, the following ''@position-fallback'' rule:
1153+
1154+
<pre class=lang-css>
1155+
@position-fallback --compact {
1156+
@try {
1157+
top: anchor(auto);
1158+
bottom: auto;
1159+
}
1160+
}
1161+
</pre>
1162+
1163+
is equivalent to the following longer, more explicit rule:
1164+
1165+
<pre class=lang-css>
1166+
@position-fallback --expanded {
1167+
@try {
1168+
top: anchor(bottom);
1169+
bottom: auto;
1170+
}
1171+
@try {
1172+
top: auto;
1173+
bottom: anchor(top);
1174+
}
1175+
}
1176+
</pre>
1177+
</div>
1178+
1179+
11101180
Security Considerations {#sec}
11111181
=======================
11121182

0 commit comments

Comments
 (0)