In this example, we define an anchor element and an anchor-positioned element, then create four named custom position try fallback options. These options are applied to the positioned element to ensure its contents are always visible no matter where the anchor element is within the viewport.
HTML
We include two <div>
elements that will become an anchor and an anchor-positioned element:
<div class="anchor">⚓︎</div>
<div class="infobox">
<p>This is an information box.</p>
</div>
CSS
We first style the <body>
element to be very large, so that we can scroll the anchor and the positioned element around in the viewport, both horizontally and vertically:
body {
width: 1500px;
height: 500px;
}
The anchor is given an anchor-name
and has a position
value of absolute
set on it. We then position it somewhere near the center of the initial <body>
rendering using top
and left
values:
.anchor {
anchor-name: --myAnchor;
position: absolute;
top: 100px;
left: 350px;
}
Next, we use the @position-try
at-rule to define four custom position options, with descriptive <dashed-ident>
names to identify them and describe their purpose. Each one places the positioned element in a specific position around the anchor element and gives it an appropriate 10px
margin between the positioned element and its anchor. The positioning is handled in a variety of ways, to demonstrate the different techniques available:
- The first and last position options use a
position-area
. - The second position option uses
top
with an anchor()
value and justify-self: anchor-center
to center the positioned element on the anchor in the inline direction. - The third position option uses
left
with an anchor()
value, wrapped inside a calc()
function that adds 10px
of spacing (rather than creating the spacing with margin
like the other options do). It then uses align-self: anchor-center
to center the positioned element on the anchor in the block direction.
Finally, the left and right position options are given a narrower width
@position-try --custom-left {
position-area: left;
width: 100px;
margin: 0 10px 0 0;
}
@position-try --custom-bottom {
top: anchor(bottom);
justify-self: anchor-center;
margin: 10px 0 0 0;
position-area: none;
}
@position-try --custom-right {
left: calc(anchor(right) + 10px);
align-self: anchor-center;
width: 100px;
position-area: none;
}
@position-try --custom-bottom-right {
position-area: bottom right;
margin: 10px 0 0 10px;
}
The infobox is given fixed positioning, a position-anchor
property that references the anchor's anchor-name
to associate the two together, and it is tethered to the anchor's top edge using an position-area
. We also give it a fixed width
and some bottom margin
. The custom position options are then referenced in the position-try-fallbacks
property to prevent the positioned element from overflowing, or being scrolled out of view, when the anchor gets near the edge of the viewport.
.infobox {
position: fixed;
position-anchor: --myAnchor;
position-area: top;
width: 200px;
margin: 0 0 10px 0;
position-try-fallbacks:
--custom-left, --custom-bottom,
--custom-right, --custom-bottom-right;
}
Result
Scroll the page and notice the change in the positioned element's placement as the anchor nears the different edges of the viewport. This is due to different fallback position options being applied.
Let's talk through how these position options work:
- First of all, note that our default position is defined by
position-area: top
. When the infobox isn't overflowing the page in any direction, the infobox sits above the anchor, and the position try fallback options set in the position-try-fallbacks
property are ignored. Also note that the infobox has a fixed width and bottom margin set. These values will change as different position try fallback options are applied. - If the infobox starts to overflow, the browser first tries the
--custom-left
position. This moves the infobox to the left of the anchor using position-area: left
, adjusts the margin to suit, and also gives the infobox a different width. - Next, the browser tries the
--custom-bottom
position. This moves the infobox to the bottom of the anchor using top
and justify-self
instead of a position-area
, and sets an appropriate margin. It doesn't include a width
descriptor, so the infobox returns to its default width of 200px
set by the width
property. - The browser next tries the
--custom-right
position. This works much the same as the --custom-left
position, with the same width
descriptor value applied. However, we are using left
and align-self
to place the positioned element instead of a position-area
. And we are wrapping the left
value in a calc()
function inside which we are adding 10px
to create spacing, instead of using margin
. - If none of the other try fallback options succeed in stopping the positioned element from overflowing, the browser tries the
--custom-bottom-right
position as a last resort. This places the positioned element to the bottom-right of the anchor using position-area: bottom right
.
When a position option is applied, its values override the initial values set on the positioned element. For example, the width
initially set on the positioned element is 200px
, but when the --custom-right
position option is applied, its width is set to 100px
.
In some cases, we need to set values inside the custom position options to turn off the initial values. The --custom-bottom
and --custom-right
options use inset property and *-self: anchor-center
values to place the positioned element, therefore we remove the previously-set position-area
value in each case by setting position-area: none
. If we didn't do this, the initially set position-area: top
value would still take effect and interfere with the other positioning information.