@@ -347,12 +347,219 @@ Anchor-Based Positioning {#positioning}
347347========================
348348
349349An [=absolutely-positioned=] element
350- can use the <dfn>anchor()</dfn> function
351- in its [=inset properties=]
352- to refer to the position of one or more [=anchor elements=] .
353- The ''anchor()'' function resolves to a <<length>> ,
354- exactly what is needed to position the given inset edge
355- to the specified position on the [=anchor element=] .
350+ can position itself relative to one or more [=anchor elements=] on the page.
351+
352+ The 'inset-area' function offers a convenient grid-based concept
353+ for positioning relative to the [=default anchor element=] ;
354+ for more complex positioning or positioning relative to multiple elements,
355+ the ''anchor()'' function can be used in the [=inset properties=]
356+ to explicitly refer to edges of an [=anchor element=] .
357+
358+ The 'inset-area' Property {#inset-area}
359+ ---------------------------------------
360+
361+ <pre class=propdef>
362+ Name : inset-area
363+ Value : none | <inset-area-span> [ / <inset-area-span> ]?
364+ Initial : none
365+ Inherited : no
366+ Applies to : positioned elements with a [=default anchor element=]
367+ Animation type : TBD
368+ </pre>
369+
370+ <pre class=prod>
371+ <dfn><inset-area-span></dfn> =
372+ [ top || bottom || center ] |
373+ [ left || right || center ] |
374+ [ x-start || x-end || center ] |
375+ [ y-start || y-end || center ] |
376+ [ start || end || center ] |
377+ [ self-start || self-end || center ] |
378+ all
379+ </pre>
380+
381+ Most common use-cases of anchor positioning
382+ only need to worry about
383+ the edges of the positioned element's [=containing block=] ,
384+ and the edges of the [=default anchor element=] .
385+ These lines can be thought of as defining a 3x3 grid;
386+ 'inset-area' lets you easily set up the positioned element's [=inset properties=]
387+ by specifying what area of this [=inset-area grid=] you want the positioned element to be in.
388+ Its syntax is:
389+
390+ <dl dfn-for=inset-area dfn-type=value>
391+ : <dfn>none</dfn>
392+ :: The property has no effect.
393+
394+ : <dfn><<inset-area-span>></dfn>
395+ :: Behaves as <css> <inset-area-span> / all</css> ,
396+ filling the entire row/column of the grid
397+ indicated by the specified value.
398+
399+ : <dfn><<inset-area-span>> [ / <<inset-area-span>> ]?</dfn>
400+ ::
401+ If the element does not have a [=default anchor element=] ,
402+ or is not an [=absolutely-positioned=] element,
403+ this value has no effect.
404+
405+ Otherwise, the two spans define a rectangular region
406+ of the [=inset-area grid=] ,
407+ and have the following effects:
408+
409+ 1. Any ''top/auto'' [=inset properties=] compute to
410+ the appropriate value
411+ to match the rectangular region.
412+ 2. The ''align-self/normal'' value for the [=self-alignment properties=]
413+ behaves as either ''align-self/start'' , ''align-self/end'' ,
414+ or ''align-self/anchor-center'' ,
415+ depending on the positioning of the region,
416+ to give a good default alignment for the positioned element.
417+
418+ See [[#resolving-spans]] for details on both of these effects.
419+ If the two <<inset-area-span>> s do not define a valid region,
420+ this property is invalid.
421+ </dl>
422+
423+
424+ <h3 id=resolving-spans>
425+ Resolving <<inset-area-span>>s</h3>
426+
427+ The <dfn export>inset-area grid</dfn> is conceptually a 3x3 grid,
428+ composed of four grid lines in each axis.
429+ In order:
430+
431+ * the start edge of the element's [=containing block=]
432+ (aka the position referred to by ''top: 0px;''
433+ or whatever [=inset property=] corresponds to
434+ the start side fo the containing block)
435+ * the ''anchor(start)'' edge of the [=default anchor element=]
436+ * the ''anchor(end)'' edge of the [=default anchor element=]
437+ * the end edge of the element's [=containing block=]
438+ (aka the position referred to by ''bottom: 0px'' ,
439+ or whatever [=inset property=] is opposite the first one)
440+
441+ Each <<inset-area-span>> specifies 1-3 regions in a given axis of that grid:
442+ the "start" region between the first two of those grid lines;
443+ the "center" region between the center two;
444+ or the "end region" between the last two.
445+
446+ <dl dfn-type=value dfn-for="inset-area, <inset-area-span> ">
447+ : <dfn>all</dfn>
448+ :: All three regions of that axis,
449+ spanning the entire breadth of the containing block.
450+
451+ : <dfn>start</dfn>
452+ : <dfn>end</dfn>
453+ : <dfn>self-start</dfn>
454+ : <dfn>self-end</dfn>
455+ : <dfn>center</dfn>
456+ : <dfn>top</dfn>
457+ : <dfn>bottom</dfn>
458+ : <dfn>y-start</dfn>
459+ : <dfn>y-end</dfn>
460+ : <dfn>left</dfn>
461+ : <dfn>right</dfn>
462+ : <dfn>x-start</dfn>
463+ : <dfn>x-end</dfn>
464+ :: Any single keyword refers just to that region in the axis.
465+
466+ Like in ''anchor()'' ,
467+ ''inset-area/start'' and ''inset-area/end''
468+ refer to the writing mode of the element's [=containing block=] ,
469+ while ''inset-area/self-start'' and ''inset-area/self-end''
470+ refer to the element's own writing mode.
471+
472+ : two keywords
473+ :: Refers to the area spanned by the two indicated regions.
474+
475+ (For example, ''top center'' spans the first two regions,
476+ but ''top bottom'' spans all three.)
477+
478+ : three keywords
479+ :: Refers to all three regions in the axis,
480+ identical to ''inset-area/all''
481+ </dl>
482+
483+ Two spans referring to different axises
484+ thus define a rectangular region of the [=inset-area grid=] .
485+
486+ To determine the axises of two spans:
487+
488+ * If a span include a keyword that implies a physical axis
489+ (''inset-area/top'' , ''inset-area/x-start'' , etc),
490+ that's its axis.
491+ * If both of the spans include a physical keyword,
492+ they must refer to different axises.
493+ If not, then the two spans do not define a valid region.
494+ * If one of the spans include a physical keyword,
495+ and the other doesn't
496+ (it only includes ambiguous keywords,
497+ like ''inset-area/center'' or ''inset-area/start'' ),
498+ then the other span's axis is perpendicular to the physical one.
499+ * If neither span includes a physical keyword,
500+ the first refers to the [=block axis=]
501+ of the [=containing block=] ,
502+ and the second to the [=inline axis=] .
503+
504+ If the spans define a valid region,
505+ they cause ''top/auto'' values for the [=inset properties=]
506+ to compute to values that will align the [=inset-modified containing block=]
507+ with the boundary of the defined region
508+ on that side.
509+
510+ Each span also implies a default alignment,
511+ which will be used if the [=self-alignment property=] on the element
512+ is ''align-self/normal'' :
513+
514+ * If the span includes the center region,
515+ the default alignment in that axis is ''align-self/anchor-center'' .
516+ * Otherwise, it's the opposite of the region it specifies:
517+ if it's specifying the "start" region,
518+ the default alignment in that axis is ''align-self/end'' ; etc.
519+
520+ <div class=example>
521+ For example, assuming an English-equivalent writing mode (horizontal-tb, ltr),
522+ then the spans ''start center / top'' resolve to
523+ the "start" region of the vertical axis,
524+ and the "start" and "center" regions of the horizontal axis,
525+ which will compute the [=inset properties=] to:
526+
527+ <pre highlight=css>
528+ /* "auto" computes to: */
529+ top: 0px;
530+ bottom: anchor(start);
531+ left: 0px;
532+ right: anchor(end);
533+ /* "normal" behaves as: */
534+ align-self: end;
535+ justify-self: anchor-center;
536+ </pre>
537+
538+ In other words, its [=inset-modified containing block=]
539+ will be the pink region in the below diagram,
540+ and the positioned element
541+ will be centered against the top edge of the anchor.
542+
543+ <figure>
544+ <img src="images/inset-area-example.png" width=400>
545+ <figcaption>
546+ An example of ''inset-area: start center / top'' positioning.
547+ </figcaption>
548+ </div>
549+
550+ Note: While the [=default anchor element=] can actually be positioned
551+ outside of the positioned element's [=containing block=] ,
552+ for the purpose of 'inset-area' 's effects
553+ it's considered to be within the block,
554+ so the grid lines always have the described order.
555+ That is, even if the anchor is entirely below the containing block,
556+ a ''inset-area/bottom'' span will still cause the element to behave as
557+ ''top: anchor(end); bottom: 0px; align-content: start;'' ;
558+ the rules for handling over-constrained [=inset properties=]
559+ will resolve the contradiction.
560+
561+
562+
356563
357564The ''anchor()'' Function {#anchor-pos}
358565---------------------------------------------------
@@ -415,7 +622,7 @@ The ''anchor()'' function has three arguments:
415622
416623 Note: These are only usable in the [=inset properties=]
417624 in the matching axis.
418- For example, ''left'' is usable in 'left' , 'right' ,
625+ For example, ''anchor()/ left'' is usable in 'left' , 'right' ,
419626 or the logical [=inset properties=] that refer to the horizontal axis.
420627
421628 : <dfn>start</dfn>
@@ -426,18 +633,18 @@ The ''anchor()'' function has three arguments:
426633 in the same axis as the [=inset property=] it's used in,
427634 by resolving the keyword against the [=writing mode=]
428635 of either the positioned element
429- (for ''self-start'' and ''self-end'' )
636+ (for ''anchor()/ self-start'' and ''anchor()/ self-end'' )
430637 or the positioned element's containing block
431- (for ''start'' and ''end'' ).
638+ (for ''anchor()/ start'' and ''anchor()/ end'' ).
432639
433640 : <dfn><<percentage>></dfn>
434641 : <dfn>center</dfn>
435642 :: Refers to a position
436- a corresponding percentage between the ''start'' and ''end'' sides,
437- with ''0%'' being equivalent to ''start''
438- and ''100%'' being equivalent to ''end'' .
643+ a corresponding percentage between the ''anchor()/ start'' and ''anchor()/ end'' sides,
644+ with ''0%'' being equivalent to ''anchor()/ start''
645+ and ''100%'' being equivalent to ''anchor()/ end'' .
439646
440- ''center'' is equivalent to ''50%'' .
647+ ''anchor()/ center'' is equivalent to ''50%'' .
441648
442649* the optional <<length-percentage>> final argument is a fallback value,
443650 specifying what the function should resolve to
@@ -687,7 +894,7 @@ for non-''justify-self/auto'' alignment values.
687894
688895If the element is not [=absolutely positioned=] ,
689896or does not have a [=default anchor element=] ,
690- this value behaves as ''center''
897+ this value behaves as ''<self-position>/ center''
691898and has no additional effect on how [=inset properties=] resolve.
692899
693900Issue: Do we want to hook the "try to stay in the IMCB" behavior to safe vs unsafe?
@@ -784,7 +991,7 @@ only if all the following conditions are true:
784991 on an [=absolutely-positioned=] element.
785992* If its <<anchor-side>> specifies a physical keyword,
786993 it's being used in an [=inset property=] in that axis.
787- (For example, ''left'' can only be used in 'left' , 'right' ,
994+ (For example, ''anchor()/ left'' can only be used in 'left' , 'right' ,
788995 or a logical [=inset property=] in the horizontal axis.)
789996* The result of determining the [=target anchor element=] is not nothing when
790997 given the querying element as the element it's used on,
0 commit comments