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.
CSS Working Group updates from July
Over the last month, the CSS Working Group has determined we can loosen containment restrictions for query containers, and agreed on a syntax for special-case support queries (like support for the gap property in a flex context, or support for align-content in a block flow context).
For more, you can access CSS Working Group meeting minutes on the W3C mailing list archive. That’s also a good place to see the agenda for upcoming meetings. Regular meetings happen every Wednesday, with the agenda generally sent one day in advance. This post highlights updates from:
This is part of a series providing updates around my work on the CSS Working Group.
These contributions take a lot of time and effort. If you’re interested in supporting our open-source CSS work, consider becoming a GitHub sponsor, or contributing to our Open Collective.
Container Queries have officially moved
out of the CSS Containment Module, and into
CSS Conditional Rules Module (Level 5).
This is the same specification module
that defines the @media
and @supports
rules.
Both levels 4 and 5 are currently written as ‘diff specs’ –
only showing changes from the previous level,
rather than the entire specification.
Level 4
defined the @supports selector()
selector-support feature query,
and is already a
Candidate Recommendation:
By publishing a Candidate Recommendation, a working group is expressing that it considers the specification complete and that it has resolved all known issues.
It’s a bit strange to me
that it would still be treated as a ‘diff’,
with the generic
/css-conditional/
url
still pointing at level 3 –
but these things happen.
The spec process is not always simple and linear.
Just to make this web of CSS modules even more confusing: media queries also have a distinct Media Queries module. That module defines what media features can be queried, while the Conditional Rules module only defines the at-rule we use inside CSS stylesheets.
Media Queries Module Level 5 defines a number of user preference media features, which have been around for a while now:
prefers-reduced-motion
prefers-reduced-transparency
prefers-reduced-data
prefers-contrast
prefers-color-scheme
forced-colors
One of those queries is not like the others,
and you can tell the difference from the name.
The forced-colors
setting
is the only one enforced by browsers –
all the others are ignorable.
If we (as authors) never query the user preference
for ‘reduced motion’,
it will have no effect on our site.
Users can generally change these preferences at either the operating system level, or inside their browser – depending on the OS, browser, and setting in question. But at this point, there’s no way for users to change their preference for a specific website, and save that change across multiple visits. We can work around that by individually providing (for example) light/dark toggles, and then saving the choice to local storage or a cookie. But returning visitors will still see a flash of their global preference on page-load, before our JavaScript kicks in.
Wouldn’t it be nice
to have a way for users
to change their preference site-by-site,
and have browsers remember their preference?
That’s what the proposed
Web Preferences API
would do.
This proposal gives us access
to update a domain-specific setting
for any prefers-*
query, for any user,
and have the browser remember that setting
when they return.
That proposal has been underway for some time, but last month it was adopted by the CSS Working Group, and will be added to Media Queries Module Level 5.
Part of the reason
for moving Container Queries
out of the Containment spec
is a drive to relax the relationship
between these features.
Containment is essential for
making size queries possible –
but the existing breakdown of containment types
defined for the contain
property
is not a perfect match for what we need.
Our initial specification
relied on applying size
(or inline-size
),
layout
, and style
containment
to all size-query containers.
All three of those are necessary precautions
to avoid looping behavior,
where changes inside a query could impact
the results of the query.
However, over time we’ve found
that only some style
and layout
containments
are strictly required.
If we don’t need as many restrictions
on a container,
we should remove the ones that aren’t necessary.
Back in March we resolved that
anchor names are not blocked by style
or layout
containment.
I immediately opened an issue
pointing out that this situation is
not specific to anchor positioning,
and we should consider allowing all positioned elements
to escape layout
containment –
and therefore escape containers.
Ian Kilpatrick (a Blink engineer)
followed up by proposing we
no longer apply full layout
containment to query-containers,
and only apply an independent formatting context.
Two weeks ago, presumably as a celebration of my birthday, the Working Group resolved to make this change.
Moving forward,
that means it still won’t be possible
to use subgrid
across a container boundary,
but it will be possible to do things like:
baseline
alignment across containersabsolute
and fixed
positioned elements
to escape their containerI hope we can continue to relax the impacts of containment on container queries over time. At this point, we might not see major changes to existing features – but we might find more situations like anchor position where a new feature should not strictly follow containment rules applied by query containers.
There’s been a long-standing issue
with how to handle @support
queries
for features that may be partly implemented
in one or more browser.
The most notable case was
browsers extending the gap
property
from being grid-specific (2017)
to being supported in flexbox as well.
Firefox implemented that change late in 2018,
Chrome/Edge rolled it out in mid-2020,
but Safari didn’t add flexbox gap support
until early 2021.
For several years,
all the browsers were reporting support
for the gap
property,
but only one browser had full support
in all the relevant layout modes.
This is the result of an essential design principle
of the @supports
rule:
browsers should not have to maintain a list
of supported features.
That’s been attempted in the past,
but the lists would be to long to maintain well,
and quickly get out of date.
Instead, when a browser parser encounters the @supports
rule,
it tries to parse the contents of the query:
true
false
unknown
(I’ve written about unknown support before)We can query for @supports (gap: 1em)
,
and any browser that understands gap: 1em
as a valid CSS declaration will claim support.
But there’s no way to check
that the declaration does what we want in all cases.
This situation has come up again recently, with browsers adding support for box alignment in block and absolute positioning contexts. As Michelle Barker mentions in her post:
One thing that concerns me, is that this seems to fall into that tricky area where it becomes impossible to test for browser support and provide fallbacks using a feature query – much like
gap
when it was implemented for flexbox. Asalign-content
is well-supported for Grid and flexbox, the feature query doesn’t help us here.
Back in January, browsers agreed to maintain a short list of these situations, and provide named queries in specific cases. To make this work, it has to be a tool we resort to rarely, in a way that is coordinated across all the major browser engines.
The recent update here
is that we’ve agreed on a syntax –
@supports named-feature(<keyword>)
–
and our first feature keyword:
align-content-on-display-block
.
Once browsers implement this,
you will be able to test:
@supports (align-content: center) {
/* browsers that support align-content ANYWHERE */
}
@supports named-feature(align-content-on-display-block) {
/* only browsers that support align-content in block layout */
}
If you skim through the minutes from our July meetings you will also find a number of updates related to the CSS ‘masonry’ proposals.
WebKit and Chrome have two competing visions for how masonry layout ought to work in CSS. WebKit wants masonry to be part of grid layout, and Chrome wants to keep them distinct. The former leads to grid properties that behave slightly different in different situations, while the latter means duplicating a number of properties that would otherwise be identical.
I don’t have strong feelings about this, or strong use-cases for masonry – but for a second there, it seemed like a hot debate. Both teams posted the competing proposals, people ran surveys on social media to get developer feedback, and then… nothing.
So what’s happening?
You might remember, a similar thing happened last year with two different proposals for anchor positioning. Rather than choosing one or the other, there was an attempt to merge the best of both. That took some time, but the resulting feature is much more powerful and usable than either of the initial proposals. The work paid off.
In this case, we can’t fully have it both ways. Masonry will either be part of grid layout, or it will have to be separate. But in many ways, we’re taking the same approach: Chrome is opening issues to show where their masonry might conflict with existing grid features, and WebKit is looking for ways to minimize those conflicts. Depending how those conflicts are resolved, we’ll have a much better sense if the masonry-in-grid approach is viable or not.
And then we will (hopefully) not be debating how the feature works, but only how it is ‘spelled’ in CSS syntax. Maybe kicking that can down the road will give us more information to work with.
calc-size()
function
and interpolate-size
property
will finally allow us to
transition or animate to and from auto
sizes!
I don’t have much more to say
about this specific issue,
but I’m keeping a close eye
on the overall feature.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.
Performance, scope, and fallbacks for the anchor positioning polyfill
Our sponsors are supporting the continued development of the CSS Anchor Positioning Polyfill. Here’s a summary of the latest updates.
Are we measuring what we meant to measure?
There’s been a lot of interest in the results of the annual State of CSS survey, but are we asking all the right questions?