Closed xiaochengh closed 5 months ago
The CSS Working Group just discussed [css-anchor-position-1] Alternative syntax for auto position fallback
, and agreed to the following:
RESOLVED: accept proposal in the draft with details to be worked out over time
After putting our heads together, @fantasai and I have this proposal for the "details to be worked out over time":
We removed all the automatic magic of creating try options from the spec in #9362, so no fallback options are created unless explicitly.
We switched the position-fallback
property to three associated properties:
position-try-options
which is a comma-separated list of fallback options, either named or generated from the base styles by a transform procedure.
position-try-options:
none | [ <dashed-ident> | <try-tactic> ]#
<try-tactic> = flip-block || flip-inline || flip-start
(initial value: none)
The try tactics defined here mirror across the block axis, inline axis, or the start-start to end-end diagonal, respectively.
We could add "shorthand" keywords here that expand to common sets of options, such as drop-down
expanding to flip-inline, flip-block, flip-block flip-inline
, but we're leaving that for later right now.
position-try-order
which specifies how to sort/prioritize the list of options: in specified order, or by largest inset-modified containing block size
position-try-order: normal | <try-size>
<try-size> = most-width | most-height |
most-block-size | most-inline-size
(initial value: normal)
position-try-final
which specifies what to do if all of the options overflow the inset-modified containing block.
position-try-final: always || [ first | <try-size> ] | hide
(initial value: first)
By default it'll use the last try-option that worked, and only pay attention to this property if the element is being rendered for the first time. If you specify 'always', it'll instead always use the specified option when they all fail, even if it's different from the last successful option.
hide
acts similar to a strong visibility: hidden
- the element still has a laid-out box and doesn't paint or capture mouse events, but it also doesn't affect scrollable overflow of its container, and can't be overridden on children.
We changed @position-fallback
rules containing @try
blocks to @position-try
, which gives a single named style block to reference from position-try-options
:
/* old syntax */
@position-fallback --foo {
@try { top: anchor(outside); }
@try { bottom: anchor(outside); }
}
/* new syntax */
@position-try --foo-1 { top: anchor(outside); }
@position-try --foo-2 { bottom: anchor(outside); }
We added a position-try
shorthand for convenience
position-try: <'position-try-order'>? <'position-try-options'> [, <'position-try-fallback'>? ]
For example:
position-try: most-width flip-block, flip-block flip-inline, --foo, first;
This:
@position-try --foo {...}
block) in addition to the base style.This system consolidates the fallback system into a single, explicit list, which makes it a lot easier to understand what's happening. Authors who want to package up a particular list can stuff it into a CSS variable.
It also leaves open the possibility of e.g. inlining inset-area
syntax as one of the position-try-options
items, similar to the Apple proposal from last July.
Can the new syntax do this easily?
Currently, we can used:
.horizontal .tooltip {
left: anchor(50%);
top: auto;
bottom: calc(anchor(top) + 3px);
justify-self: anchor-center;
}
.vertical .tooltip {
inset: auto;
left: calc(anchor(right) + 3px);
top: calc(anchor(50%));
align-self: anchor-center;
justify-self: auto;
}
With the current syntax, align-self and justify-self need to be interchanged.
Well, note that neither of those tooltip positions are compatible with "avoiding overflow", which is the strategy used to decide whether a position is good or not. In fact, they both overflow the input's bounds, and the choice of vertical vs horizontal position seems to have nothing to do with the containing block, either.
So as far as I can tell, the question is moot - that example isn't using fallback at all.
The CSS Working Group just discussed [css-anchor-position-1] Alternative syntax for auto position fallback
, and agreed to the following:
RESOLVED: adopt `position-try-*` with addition of inset-area into pos-try-opts
Should be addressed by the current draft spec.
The current spec uses
auto
andauto-same
keywords in theanchor()
function to create automatic position fallbacks, e.g.,left: anchor(auto); right: auto
.I think this need to be reworked. Reasons:
anchor(auto)
andanchor(auto-same)
are hard to understandanchor(auto)
uses a special inset value to trigger auto fallbacks, and the generated fallbacks affect inset values only. This will no longer make sense if we allow more properties (like margins) in@position-fallback
, which I think is likely to happen (see also #9195)Proposal
Remove everything about the
auto
andauto-same
anchor side keywords, and:Add a new
position-fallback-auto
propertyA
none
value means no auto fallbacks are generated.A
flip-block
value creates a fallback style where, intuitively, all the block-axis values are flipped. Specifically:*-block-start
and*-block-end
property values swappedalign-*
properties are flipped to the other side (e.g.,align-self: start
-->align-self: end
)anchor()
function used in the block axis:inset-block-start: anchor(start)
-->inset-block-end:anchor(end)
)inset-block-start: anchor(30%)
-->inset-block-end:anchor(70%)
)The other
flip-*
values for a single axis are similar.The
flip-both
value creates 3 fallback styles: block axis flipped, inline axis flipped, then both axes flipped.The
compass
value allows creating fallback positions around the anchor (e.g., top, left, bottom, right). Specifically:flip-both
Usage in
@try
blockThe property can also be used in a
@try
block to create additional fallbacks based on a@try
block style. This part is similar to the current spec and hence omitted.Add new
same
andopposite
anchor side keywordsThe current
auto
andauto-same
keywords are also useful for non-fallback purposes. For example,inset: anchor(auto-same)
creates an inset-modified containing block that's the same as the anchor box.To support this use case, we add
same
andopposite
anchor side keywords. They are evaluated the same as the currentauto-same
andauto
, but don't create any fallbacks.Also,
same
andopposite
are not swapped inflip-*
fallbacks.Minor discussion topics
flip-both
androtate
create multiple fallbacks, maybe we want a syntax to specify the ordering?