@@ -347,12 +347,219 @@ Anchor-Based Positioning {#positioning}
347
347
========================
348
348
349
349
An [=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
+
356
563
357
564
The ''anchor()'' Function {#anchor-pos}
358
565
---------------------------------------------------
@@ -415,7 +622,7 @@ The ''anchor()'' function has three arguments:
415
622
416
623
Note: These are only usable in the [=inset properties=]
417
624
in the matching axis.
418
- For example, ''left'' is usable in 'left' , 'right' ,
625
+ For example, ''anchor()/ left'' is usable in 'left' , 'right' ,
419
626
or the logical [=inset properties=] that refer to the horizontal axis.
420
627
421
628
: <dfn>start</dfn>
@@ -426,18 +633,18 @@ The ''anchor()'' function has three arguments:
426
633
in the same axis as the [=inset property=] it's used in,
427
634
by resolving the keyword against the [=writing mode=]
428
635
of either the positioned element
429
- (for ''self-start'' and ''self-end'' )
636
+ (for ''anchor()/ self-start'' and ''anchor()/ self-end'' )
430
637
or the positioned element's containing block
431
- (for ''start'' and ''end'' ).
638
+ (for ''anchor()/ start'' and ''anchor()/ end'' ).
432
639
433
640
: <dfn><<percentage>></dfn>
434
641
: <dfn>center</dfn>
435
642
:: 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'' .
439
646
440
- ''center'' is equivalent to ''50%'' .
647
+ ''anchor()/ center'' is equivalent to ''50%'' .
441
648
442
649
* the optional <<length-percentage>> final argument is a fallback value,
443
650
specifying what the function should resolve to
@@ -687,7 +894,7 @@ for non-''justify-self/auto'' alignment values.
687
894
688
895
If the element is not [=absolutely positioned=] ,
689
896
or does not have a [=default anchor element=] ,
690
- this value behaves as ''center''
897
+ this value behaves as ''<self-position>/ center''
691
898
and has no additional effect on how [=inset properties=] resolve.
692
899
693
900
Issue: 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:
784
991
on an [=absolutely-positioned=] element.
785
992
* If its <<anchor-side>> specifies a physical keyword,
786
993
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' ,
788
995
or a logical [=inset property=] in the horizontal axis.)
789
996
* The result of determining the [=target anchor element=] is not nothing when
790
997
given the querying element as the element it's used on,
0 commit comments