Experiment: Animating CSS position-area with View Transitions

CSS Anchor Positioning is a powerful tool, but one of the things that you cannot do natively (yet) is animating the position-area property. This blog post introduces a technique to animate position-area changes using View Transitions.


This content originally appeared on Bram.us and was authored by Bramus!

Recording of the demo.

~

CSS Anchor Positioning is a powerful tool, but one of the things that you cannot do natively (yet) is animating the position-area property. This blog post introduces a technique to animate position-area changes using View Transitions.

~

🌟 This post is about CSS Anchor Positioning. If you are not familiar with the basics of it, check out this 30-min talk of mine to get up to speed.

~

The problem

When the browser chooses one of the position-try-fallbacks to apply to an anchored element, the position-area’s Computed Value changes to that chosen fallback. This change is abrupt and in response the anchored element simply jumps from the old position-area to the new position-area. This change can’t be animated using CSS because position-area is discretely animatable (or rather: it’s currently defined as “TBD”, see w3c/csswg-drafts#13577), so the value just flips midway the transition.

.tooltip {
	position: fixed;
	position-area: block-start;
	position-try-fallbacks: flip-block;
	transition: position-area 0.2s ease; /* This doesn’t do anything visually … */
}

~

The technique

Back in 2024 I explored a technique to automatically trigger a View Transition whenever a CSS property changes. For this I relied on @bramus/style-observer which is a StyleObserver that allows you to respond to Computed Value changes in JavaScript. In the StyleObserver’s callback, I reset the targeted element to the previously recorded value, and then start a View Transition to the new value of that property.

For Anchor Positioning specifically, it’s sufficient to monitor the position-area property, as its Computed Value changes whenever a new position-try-fallback gets applied. To make sure that the View Transition is started from the previously recorded position-area, the position-try must be unset temporarily at the start of the View Transition. Therefore, that property also needs to be monitored.

import StyleObserver, { ReturnFormat, NotificationMode } from "@bramus/style-observer";

const $element = document.querySelector('.tooltip');

let isBusy = false;
const styleObserver = new StyleObserver((mutations) => {
	// Prevent double runs
	if (isBusy) return;
	isBusy = true;

	const positionArea = mutations['position-area'];
		
	// No change, do nothing
	if (!positionArea.previousValue || !positionArea.changed) {
		isBusy = false;
		return;
	}
		
	// Move the element back its old location
	// This is done by forcing the old recorded positionArea
	// but most importantly by also unsetting the `position-try`
	$element.style.positionTry = 'none';
	$element.style.positionArea = positionArea.previousValue;

	// Restore the new positions
	const t = document.startViewTransition(() => {
		$element.style.positionTry = '';
		$element.style.positionArea = '';
	});

	isBusy = false;
},
{
	properties: ['position-area', 'position-anchor', 'position-try'],
	returnFormat: ReturnFormat.OBJECT,
	notificationMode: NotificationMode.ALL,
});

styleObserver.observe($element);

Here is a live demo that is using this technique:

See the Pen CSS Anchor Positioning: Animating `position-area` with View Transitions, powered by @bramus/style-observer by Bramus (@bramus) on CodePen.

Scroll the page up and down to trigger a different position-area on the positioned element.

~

Known Issues

Unfortunately there are some issues with the technique:

  1. The code does not work in Firefox.

    I initially thought this was because of position-area being underspecified in the spec – it’s animation type is currently specced as “TBD” – and that Firefox therefore did not mark the property as being Discretely Animatable. A look at Stylo’s source code tells me it is defined as a discretely animatable property so so that’s not the problem.

    Digging into the code of my StyleObserver, I see it only picks up the initially applied value of position-area but no subsequent changes, even though a getComputedStyle() indicates that the value did change. I think there is a bug on Firefox’s end in which it does not trigger a transition when the value changes as the result of a position-try-fallback being chosen.

    I have filed w3c/csswg-drafts#13577 at the CSSWG to fix the spec, and https://bugzilla.mozilla.org/show_bug.cgi?id=2020592 with Firefox to get the bug sorted on their end.

  2. Chrome is affected by a 1-frame glitch due to the ambiguously defined timing of transitionrun. w3c/csswg-drafts#11665 is concerned with this.

  3. In Safari, the transitionrun that tracks position-area keeps firing over and over once it has detected a change. This is fixed in Safari Technology Preview.

  4. While the View Transition is running, the positioned and anchored elements can feel a bit out-of-sync. This is because of how View Transitions deal with scroll: during a scroll, VTs retarget the end transform of the ::view-transition-group() pseudos, which makes them be subjected to the animation-duration instead of changing instantly. In w3c/csswg-drafts#10197 I am throwing around ideas to get this fixed.

All these issues are fixable over time, but I would say that the 1-frame glitch in Chrome is preventing this from being something that is really usable right now.

Also note that the anchor in the demo does not change aspect ratio when a new position-area gets set. If yours does, you’ll need this code by Jake.

~

🔥 Like what you see? Want to stay in the loop? Here's how:

I can also be found on 𝕏 Twitter and 🐘 Mastodon but only post there sporadically.


This content originally appeared on Bram.us and was authored by Bramus!


Print Share Comment Cite Upload Translate Updates
APA

Bramus! | Sciencx (2026-03-02T22:19:20+00:00) Experiment: Animating CSS position-area with View Transitions. Retrieved from https://www.scien.cx/2026/03/02/experiment-animating-css-position-area-with-view-transitions/

MLA
" » Experiment: Animating CSS position-area with View Transitions." Bramus! | Sciencx - Monday March 2, 2026, https://www.scien.cx/2026/03/02/experiment-animating-css-position-area-with-view-transitions/
HARVARD
Bramus! | Sciencx Monday March 2, 2026 » Experiment: Animating CSS position-area with View Transitions., viewed ,<https://www.scien.cx/2026/03/02/experiment-animating-css-position-area-with-view-transitions/>
VANCOUVER
Bramus! | Sciencx - » Experiment: Animating CSS position-area with View Transitions. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2026/03/02/experiment-animating-css-position-area-with-view-transitions/
CHICAGO
" » Experiment: Animating CSS position-area with View Transitions." Bramus! | Sciencx - Accessed . https://www.scien.cx/2026/03/02/experiment-animating-css-position-area-with-view-transitions/
IEEE
" » Experiment: Animating CSS position-area with View Transitions." Bramus! | Sciencx [Online]. Available: https://www.scien.cx/2026/03/02/experiment-animating-css-position-area-with-view-transitions/. [Accessed: ]
rf:citation
» Experiment: Animating CSS position-area with View Transitions | Bramus! | Sciencx | https://www.scien.cx/2026/03/02/experiment-animating-css-position-area-with-view-transitions/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.