Skip to content

Commit

Permalink
[css-anchor-position] Switch inset-area to the new syntax. Specify th…
Browse files Browse the repository at this point in the history
…at it modifies the containing block. #9862 #9598
  • Loading branch information
tabatkins committed Feb 6, 2024
1 parent 888736e commit 7875737
Showing 1 changed file with 106 additions and 118 deletions.
224 changes: 106 additions & 118 deletions css-anchor-position-1/Overview.bs
Expand Up @@ -363,26 +363,13 @@ The 'inset-area' Property {#inset-area}

<pre class=propdef>
Name: inset-area
Value: none | <<inset-area-span>> [ / <<inset-area-span>> ]?
Value: none | <<inset-area>>
Initial: none
Inherited: no
Applies to: positioned elements with a [=default anchor element=]
Animation type: TBD
</pre>

<pre class=prod>
<dfn>&lt;inset-area-span></dfn> =
[ start || end || center ] |
[ self-start || self-end || center ] |
[ top || bottom || center ] |
[ left || right || center ] |
[ x-start || x-end || center ] |
[ y-start || y-end || center ] |
[ x-self-start || x-self-end || center ] |
[ y-self-start || y-self-end || center ] |
all
</pre>

Most common use-cases of anchor positioning
only need to worry about
the edges of the positioned element's [=containing block=],
Expand All @@ -392,73 +379,94 @@ These lines can be thought of as defining a 3x3 grid;
by specifying what area of this [=inset-area grid=] you want the positioned element to be in.
Its syntax is:

<pre class=prod>
<dfn>&lt;inset-area></dfn> = [
[ left | center | right | center-left | center-right
| x-start | x-end | center-x-start | center-x-end
| x-self-start | x-self-end | center-x-self-start | center-x-self-end
| all ]
&&
[ top | center | bottom | center-top | center-bottom
| y-start | y-end | center-y-start | center-y-end
| y-self-start | y-self-end | center-y-self-start | center-y-self-end
| all ]
|
[ block-start | center | block-end | center-block-start | center-block-end
| self-block-start | self-block-end | center-self-block-start | center-self-block-end
| all ]
&&
[ inline-start | center | inline-end | center-inline-start | center-inline-end ]
| self-inline-start | self-inline-end | center-self-inline-start | center-self-inline-end
| all ]
|
[ start | center | end | center-start | center-end | all ]{1, 2}
|
[ self-start | center | self-end | center-self-start | center-self-end | all ]{1, 2}
]
</pre>

<dl dfn-for=inset-area dfn-type=value>
: <dfn>none</dfn>
:: The property has no effect.

: <dfn><<inset-area-span>></dfn>
:: Behaves as <css>&lt;inset-area-span> / all</css>,
filling the entire row/column of the grid
indicated by the specified value.

: <dfn><<inset-area-span>> [ / <<inset-area-span>> ]?</dfn>
: <dfn><<inset-area>></dfn>
::
If the element does not have a [=default anchor element=],
or is not an [=absolutely-positioned=] element,
this value has no effect.

Otherwise, the two spans define a rectangular region
of the [=inset-area grid=],
and have the following effects:
Otherwise, the property selects a region of the [=inset-area grid=],
and makes that the element's [=containing block=].

1. Any ''top/auto'' [=inset properties=] compute to
the appropriate value
to match the rectangular region.
2. The ''align-self/normal'' value for the [=self-alignment properties=]
behaves as either ''align-self/start'', ''align-self/end'',
or ''align-self/anchor-center'',
depending on the positioning of the region,
to give a good default alignment for the positioned element.
Note: This means that the [=inset properties=] specify offsets from the inset-area,
and some property values,
like ''max-height: 100%'',
will be relative to the inset-area as well.

Additionally, the ''align-self/normal'' value for the [=self-alignment properties=]
behaves as either ''align-self/start'', ''align-self/end'',
or ''align-self/anchor-center'',
depending on the positioning of the region,
to give a good default alignment for the positioned element.

See [[#resolving-spans]] for details on both of these effects.
If the two <<inset-area-span>>s do not define a valid region,
this property is invalid.

Also, any ''top/auto'' [=inset properties=] resolve to ''0''.
</dl>


<h4 id=resolving-spans>
Resolving <<inset-area-span>>s</h4>

The <dfn export>inset-area grid</dfn> is conceptually a 3x3 grid,
The <dfn export>inset-area grid</dfn> is a 3x3 grid,
composed of four grid lines in each axis.
In order:

* the start edge of the element's [=containing block=]
(aka the position referred to by ''top: 0px;''
or whatever [=inset property=] corresponds to
the start side of the containing block)
* the start edge of the element's pre-modification [=containing block=],
or the ''anchor-start()'' edge of the [=default anchor element=]
if that is more [=start=]-ward
* the ''anchor(start)'' edge of the [=default anchor element=]
* the ''anchor(end)'' edge of the [=default anchor element=]
* the end edge of the element's [=containing block=]
(aka the position referred to by ''bottom: 0px'',
or whatever [=inset property=] is opposite the first one)
* the end edge of the element's pre-modification [=containing block=],
or the ''anchor-start()'' edge fo the [=default anchor element=]
if that is more [=end=]-ward.

Each <<inset-area-span>> specifies 1-3 regions in a given axis of that grid:
the "start" region between the first two of those grid lines;
the "center" region between the center two;
and/or the "end region" between the last two.

<dl dfn-type=value dfn-for="inset-area, <inset-area-span>">
: <dfn>all</dfn>
:: All three regions of that axis,
spanning the entire breadth of the containing block.
An <<inset-area>> selects a region of this grid
by specifying the rows and columns the region occupies,
with each of the two keywords specifying one of them:

<dl dfn-type=value dfn-for="inset-area, <inset-area>">
: <dfn>start</dfn>, <dfn>end</dfn>, <dfn>self-start</dfn>, <dfn>self-end</dfn>
: <dfn>top</dfn>, <dfn>bottom</dfn>, <dfn>left</dfn>, <dfn>right</dfn>
: <dfn>y-start</dfn>, <dfn>y-end</dfn>, <dfn>y-self-start</dfn>, <dfn>y-self-end</dfn>
: <dfn>x-start</dfn>, <dfn>x-end</dfn>, <dfn>x-self-start</dfn>, <dfn>x-self-end</dfn>
: <dfn>block-start</dfn>, <dfn>block-end</dfn>, <dfn>block-self-start</dfn>, <dfn>block-self-end</dfn>
: <dfn>inline-start</dfn>, <dfn>inline-end</dfn>, <dfn>inline-self-start</dfn>, <dfn>inline-self-end</dfn>
: <dfn>center</dfn>
:: Any single keyword refers just to that region in the axis.
:: The single corresponding row or column,
depending on which axis this keyword is specifying.

Like in ''anchor()'',
the plain logical keywords
Expand All @@ -467,99 +475,79 @@ and/or the "end region" between the last two.
The ''inset-area/x-start''/etc determine their direction in the same way,
but in the specified physical axis.

The "self" logical keyword
The "self" logical keywords
(''inset-area/self-start'', ''inset-area/x-self-end'', etc)
are identical,
but refer to the element's own writing mode.

: two keywords
:: Refers to the area spanned by the two indicated regions.
: <dfn>center-start</dfn>, <dfn>center-end</dfn>
: <dfn>center-top</dfn>, <dfn>center-bottom</dfn>
: <dfn>center-y-start</dfn>, <dfn>center-y-end</dfn>
: <dfn>center-x-start</dfn>, <dfn>center-x-end</dfn>
: <dfn>center-block-start</dfn>, <dfn>center-block-end</dfn>
: <dfn>center-inline-start</dfn>, <dfn>center-inline-end</dfn>
:: Two rows or columns,
depending on which axis this keyword is specifying:
the center row/column,
and the row/column corresponding to the other half of the keyword
as per the single-track keywords.

(For example, ''center-top'' spans the first two rows--
the center row and the top row.)

(For example, ''top center'' spans the first two regions,
but ''top bottom'' spans all three.)

: three keywords
:: Refers to all three regions in the axis,
identical to ''inset-area/all''
: <dfn>all</dfn>
:: All three rows or columns,
depending on which axis this keyword is specifying.
</dl>

Two spans referring to different axises
thus define a rectangular region of the [=inset-area grid=].
To determine the axises of two spans:

* If a span include a keyword that implies a physical axis
(''inset-area/top'', ''inset-area/x-start'', etc),
that's its axis.
* If both of the spans include a physical keyword,
they must refer to different axises.
If not, then the two spans do not define a valid region.
* If one of the spans include a physical keyword,
and the other doesn't
(it only includes ambiguous keywords,
like ''inset-area/center'' or ''inset-area/start''),
then the other span's axis is perpendicular to the physical one.
* If neither span includes a physical keyword,
the first refers to the [=block axis=]
of the [=containing block=],
and the second to the [=inline axis=].

If the spans define a valid region,
they cause ''top/auto'' values for the [=inset properties=]
to compute to values that will align the [=inset-modified containing block=]
with the boundary of the defined region
on that side.

Each span also implies a default alignment,
Some keywords are ambiguous about what axis they refer to:
''inset-area/center'', ''inset-area/all'',
and the ''inset-area/start''/etc keywords that don't specify the block or inline axis explicitly.
If the other keyword is unambiguous about its axis,
then the ambiguous keyword is referring to the opposite axis.
(For example, in ''block-start center'',
the ''inset-area/center'' keyword is referring to the inline axis.)
If both keywords are ambiguous, however,
then the first refers to the block axis of the element's [=containing block=],
and the second to the inline axis.
(For example, ''all start'' is equivalent to ''all inline-start''.)

If only a single keyword is given,
it behaves as if the second keyword is ''inset-area/all''
if the given keyword is unambigous about its axis;
otherwise, it behaves as if the given keyword was repeated.
(For example, ''inset-area/top'' is equivalent to ''top all'',
but ''inset-area/center'' is equivalent to ''center center''.)

<hr>

The <<inset-area>> also implies a default [=self-alignment=],
which will be used if the [=self-alignment property=] on the element
is ''align-self/normal'':

* If the span includes the center region,
* If the inset area includes the center region in an axis
the default alignment in that axis is ''align-self/anchor-center''.
* Otherwise, it's the opposite of the region it specifies:
if it's specifying the "start" region,
if it's specifying the "start" region of its axis,
the default alignment in that axis is ''align-self/end''; etc.

<div class=example>
For example, assuming an English-equivalent writing mode (horizontal-tb, ltr),
then the spans ''start center / top'' resolve to
then the value ''center-x-start top'' resolves to
the "start" region of the vertical axis,
and the "start" and "center" regions of the horizontal axis,
which will compute the [=inset properties=] to:

<pre highlight=css>
/* "auto" computes to */
top: 0px;
bottom: anchor(start);
left: 0px;
right: anchor(end);

/* "normal" behaves as */
align-self: end;
justify-self: anchor-center;
</pre>

In other words, its [=inset-modified containing block=]
will be the pink region in the below diagram,
and the positioned element
will be centered against the top edge of the anchor.
so the default alignments will be ''align-self: end;'' and ''justify-self: anchor-center;''

<figure>
<img src="images/inset-area-example.png" width=400>
<figcaption>
An example of ''inset-area: start center / top'' positioning.
An example of ''inset-area: center-x-start top'' positioning.
</figcaption>
</div>

Note: While the [=default anchor element=] can actually be positioned
outside of the positioned element's [=containing block=],
for the purpose of 'inset-area'&apos;s effects
it's considered to be within the block,
so the grid lines always have the described order.
That is, even if the anchor is entirely below the containing block,
a ''inset-area/bottom'' span will still cause the element to behave as
''top: anchor(end); bottom: 0px; align-content: start;'';
the rules for handling over-constrained [=inset properties=]
will resolve the contradiction.
Note: When the [=default anchor element=]
is partially or completely outside of the pre-modified [=containing block=],
some of the [=inset-area grid's=] rows or columns can be zero-sized.


<!-- Big Text: anchor()
Expand Down Expand Up @@ -1222,7 +1210,7 @@ this property determines which [=position option=] to use.
keeping its position reasonably stable.
With ''always'' specified, however,
it will instead use the specified strategy
to select the "fallback" [=position overflow=],
to select the "fallback" [=position option=],
regardless of what was previously successful.

: <dfn>hide</dfn>
Expand Down

0 comments on commit 7875737

Please sign in to comment.