Skip to main
Article
A hand with painted nails placing a white square of paper into a 9 by 9 grid.

Better Anchor Positioning with position-area

It’s not just a shorthand for anchor()

position-area might be my favorite part of the CSS Anchor Positioning spec, with a ton of features packed in to make things just… work. But there’s no magic here, just a few key parts that work well.

The examples in this article are best viewed in a Chromium browser, version 131 or later.

Initially, position-area seems like nothing more than a shorthand. Just replace top: anchor(bottom); left: anchor(right) with position-area: bottom right and it works.

Or go even further, and replace that with position-area: end.

See the Pen position-area containing block by @jamessw on CodePen.

The idea behind position-area is that in most cases, you want your positioned element to be touching a specific corner or edge of the anchor. position-area creates a grid around the anchor, and lets you place your positioned element within that grid.

Anchor-tool.com is a fantastic tool for exploring the different values for positioning an element within that grid.

A screenshot of anchor-tool.com, demonstrating an element positioned with position-area: top span-left.

But position-area is more than a shorthand for anchor(), introducing some behaviors that may be surprising.

One of the key differences between using anchor() and position-area is that position-area creates a new containing block for the positioned element.

If you are using anchor(), the positioned element’s containing block works like normal. For a fixed position element, it will usually be the viewport. For an absolute positioned element, it will usually be the closest ancestor that has a position besides static. The anchor() function then resolves to a length that positions the element as specified, within that containing block.

position-area creates a containing block that does not map to an element. Instead, it is defined by the relationship between the anchor and the anchor’s containing block.

This containing block is generated by the grid area that you select using position-area. For instance, with position-area: top left, the new containing block starts at the top left corner of the anchor’s containing block and extends to the top left corner of the anchor itself.

A 9-space grid, like a tic-tac-toe board, with an Anchor in the center square, and a square within the top left square for a new containing block.

Note that the element we’re positioning doesn’t have to fill this entire area, but we’re choosing the container that we want to position our element inside of.

Using position-area also handles some defaults so that the positioned element is placed near to the anchor, within its new containing block.

First, any inset properties like top or inline-start that don’t have values set on the positioned element resolve to 0. This makes the containing block fill the entirety of its grid area.

Then, align-self and justify-self are used to position the element close to the anchor, by setting the alignment away from the specified grid area and towards the non-specified grid area. If the grid area is center or span-all, then the value is anchor-center.

Together, that means that position-area: top right is equivalent to the following declaration using anchor().

.positioned-element {
  bottom: anchor(top);
  left: anchor(right);
  top: 0;
  right: 0;
  justify-self: start;
  align-self: end;
}

See the Pen position-area positioning by @jamessw on CodePen.

As a side effect of being an absolutely positioned element with justify-self or align-self set, your positioned element will have the behavior of smartly shifting to stay within its original content block.

If, after applying padding and margins, your positioned element would overflow the newly created containing block but would fit inside its original container block, it will get shifted to prevent overflow.

In this example, the targets are all positioned with position-area: center. The top and bottom targets are shifted toward the center because they would otherwise overflow their original containing block, which is the div with the dashed border. They are shifted just enough to be flush with their containing block.

See the Pen position-area self alignment - absolute positioning by @jamessw on CodePen.

Note that in this example, the targets are position: absolute. If instead the targets are position: fixed, the targets do not overflow their original containing block (the viewport) and so no shifting happens.

See the Pen position-area self alignment - fixed position by @jamessw on CodePen.

You can opt in to this behavior with anchor() by setting a value for all of top, right, bottom, and left, and setting a value for justify-self and align-self. But position-area is much more terse.

One of the ways we observe a containing block is that percentages are resolved in relation to the containing block. This means that padding: 5% on an element positioned using position-area will have a padding of 5% of the size of the containing block – the section of the grid that was selected.

See the Pen position-area containing block by @jamessw on CodePen.

In this case, the padding on the element positioned with anchor() is much larger, since its containing block is the viewport, not the grid area created by position-area.

position-area is available in Chromium browsers. It was initially called inset-area, but was renamed in the Chromium 129 release.

The Anchor Positioning Polyfill does not yet support position-area. This article was written as part of our exploration into the spec, and if you would like to sponsor further development, please get in touch!

If you found this article helpful, please sponsor our work! Deep dives like this take time and energy, and we want to keep them coming!

You can also hire us to develop the Anchor Positioning polyfill or another OSS language/tool you rely on. Our client work also helps fund our educational work like this article, so get in touch with us if you have any web development needs.

Open Source Sponsors

Current Sponsors

A huge thank you to the individuals and organizations sponsoring OddBird’s open source work!

Blue-Footed Boobies

Open Collective Avatar for benface

Common Loons

Open Collective Avatar for ScheppOpen Collective Avatar for ThijsOpen Collective Avatar for AnonymousOpen Collective Avatar for Nicolas ChevobbeOpen Collective Avatar for Paul van BuurenOpen Collective Avatar for William KillerudOpen Collective Avatar for Nikita DubkoOpen Collective Avatar for Outline GbROpen Collective Avatar for Mat MarquisOpen Collective Avatar for JohannesOpen Collective Avatar for Eric PortisOpen Collective Avatar for Roman KomarovOpen Collective Avatar for Pascal DuezOpen Collective Avatar for Tyson GachOpen Collective Avatar for MayankOpen Collective Avatar for thanks.devOpen Collective Avatar for Syntax

Sponsor OddBird’s OSS Work

We love contributing back to the languages & tools that developers rely on, from CSS & Sass to browser polyfills and Python. Help us keep that work sustainable and focused on developer needs!

Recent Articles

  1. A case of letterpress type with arrows pointing outward and a cursor hand overlaid
    Article post type

    Reimagining Fluid Typography

    Are we responding to the right inputs?

    For many years, it has been ‘best practice’ to use relative units (especially em and rem) for sizing text. That’s great! But after playing around with my user preferences, I think we can improve on the common approaches.

    see all Article posts
  2. A weathered small boat in the fog, with ropes going into the water, hopefully leading to an anchor.
    Article post type

    Here’s Why Your Anchor Positioning Isn’t Working

    How to find an anchor element

    It is frustrating to track down why an anchor isn’t being found. I’ve found a simple way that should work in most cases. If that doesn’t work, step through the checklist, and then dive in to get a better understanding of how Anchor Positioning works.

    see all Article posts
  3. A symmetrical knot with thick rope lying on weathered wood.
    Article post type

    Anchor Positioning Is Disruptive

    New layouts will be possible

    The more I play with it, the more convinced I am that anchor positioning is going to unlock some surprising new layouts.

    see all Article posts