Updates to Popover and CSS Anchor Positioning Polyfills
hint
popovers, position-area
and more
We have been busy updating the Popover and CSS Anchor Positioning Polyfills, but there is still more we can do with your help.
There are several proposals, but one major road block
We’re trying to make progress on shorthand syntax for CSS logical properties. But the path forward depends on where we hope to be a decade from now.
The specification for CSS Logical Properties & Values was first published as a Working Draft in 2017, almost three years after the first GitHub commit. In many ways, this is an offshoot of the spec for CSS Writing Modes first published in 2010.
Writing Modes define
how the text flows in a document.
Many languages are written horizontally
(either left-to-right or right-to-left)
with lines of text stacking
from top to bottom.
This is the default horizontal-tb
writing mode.
But some languages can also be written vertically,
and stack in either direction:
vertical-lr
or vertical-rl
.
In any given writing mode,
text creates lines on one axis,
and those lines wrap to stack up on the cross axis.
We call those the inline
and block
axes respectively.
This allows us to use
‘flow-relative’ or ‘logical’ language
in place of the ‘physical’ terms
that CSS started with:
horizontal
/x
and vertical
/y
are always fixed in place,
but inline
and block
change relative to the writing mode.rtl
or ltr
) then the
top
, right
, bottom
, and left
sides
can be replaced with
inline-start
, inline-end
, and so on.width
and height
of an element can be described
as the inline-size
and block-size
.The original specifications
use length
(or later extent
) and measure
to describe
the block and inline dimensions.
That eventually became block-size
and inline-size
in 2014,
which I think is a big improvement for clarity.
I trace this history in my notes,
with links to all the discussion I can find.
CSS Logical Properties & Values Module Level 1
defines a number of flow-relative values
for existing properties such as flow
, clear
,
text-align
, and resize
.
Then it defines two logical dimension properties –
inline-size
and block-size
–
and a list of logical sub-properties
for margin-<side>
, padding-<side>
, and border-<side>
.
CSS provides several 2-value
logical shorthand properties,
allowing us to specify
both -start
and -end
values on either the inline
or block
axis.
I find these extremely useful
for quickly setting the margin-block
,
border-block
, and padding-block
on elements:
See the Pen 2-Value Logical Shorthands by @miriamsuzanne on CodePen.
The Logical Properties spec also
includes a proposal
that was never implemented by browsers,
so that we can use the existing
4-value margin
, padding
, or border
shorthands
to set the logical rather than physical values.
Since these properties already exist
and have a purely physical meaning,
it’s a bit more work.
But the spec adds an optional logical
keyword
that can be set before the value:
/* These two rules are equivalent: */
blockquote {
margin: logical 1em 2em 3em 4em;
}
blockquote {
margin-block-start: 1em;
margin-inline-start: 2em;
margin-block-end: 3em;
margin-inline-end: 4em;
}
That’s one of four approaches discussed in a 2017 Github issue which Elika Etimad (fantasai) opened a few weeks before publishing the spec:
logical
or relative
to the value!logical
or !relative
to toggle declarationsmargin-logical
and padding-logical
margin-mode: relative
For now we’ll set aside finding the right word (logical, relative, or something else), and focus on choosing a mechanism: keyword, flag, special shorthands, or toggle. These all have potential issues – which I’ll cover with more detail in the another post – but option 4 raises an important issue we should address right away.
The first three proposals are declaration-level solutions, which we have to repeat every time we use the shorthand syntax. The result is a logical shorthand that’s significantly less short than the physical alternatives.
That might be okay as a partial fix, but if we stop there logical shorthands still feel like a second-class feature. That’s a big problem for the language. It’s hard to encourage a logical-first approach as the best practice, when the language is clearly giving preference to physical values instead. Will it still make sense 10 years from now, or will it always feel like a mistake we’re stuck with for legacy reasons?
A toggle like margin-mode
would be one approach to that,
similar to the box-sizing
property.
I’m not sure we would actually need
different mode-toggles for each shorthand,
so let’s call it shorthand-mode
for now.
But that still comes with some significant issues.
First, we have to consider the order of the values. I don’t know why Bert Bos and Håkon Lie used the clockwise top-right-bottom-left ordering for 4-value properties. The best thing about it is the alternating-axis, which allows us to shorten things even more – down to 3 values, 2 values, or even a single value:
article {
/* top, right, bottom, left */
margin: 1em 2em 3em 4em;
/* top, right & left, bottom */
margin: 1em 2em 3em;
/* top & bottom, right & left */
margin: 1em 2em;
/* all at once! */
margin: 1em;
}
That would still be possible
if we went counter-clockwise,
and everything else about it would make more sense.
Given a default horizontal-tb
writing mode
and the default ltr
text direction,
why do we set the block-start
first,
then the inline-end
?
Why is the inline-start
at the very end?
Given this reality,
if we assume the default flow of text
and try to directly transpose
the syntax from physical to relative,
it looks strange:
block-start
then inline-end
,
block-end
, and inline-start
.
Sure, I could learn that –
but it has absolutely no logic to it
outside that direct transposing of defaults.
If the entire goal is to have
a flow-relative set of values,
they should have a flow-relative order as well.
That’s why grid syntax (for example)
uses block-start
and then inline-start
,
and then the alternating -end
values.
That leads to the second issue:
Any global toggle will be applying
action-at-a-distance.
The toggle is not positioned in our code
next to the values that it will impact.
When we encounter a margin of 1em 2em 3em 4em
,
we have no idea what that value means
until we find the toggle.
If that toggle is another value in the cascade,
there is no way to know what mode we’re in
before rendering the page,
and allowing the cascade to resolve.
This works okay for box-sizing
,
which only impacts the width
and height
properties.
We can set the toggle on an element
as we size it,
and generally assume the three properties
will cascade together.
If a third-party tool is using a different mode
to size specific components,
we can make sure the right box-sizing
is applied
on those components specifically.
But there are many properties
that could accept logical properties,
and they aren’t always clearly related.
Are we sure we want
scroll-snap-margin
to use the same mode
as border-radius
and box-shadow
and background-position
?
Are we going to create distinct toggles for each?
We can continue to discuss the pros and cons of each syntax, but this is where we’re forced to step back and consider the bigger question:
No one knows the full list of CSS properties that will be impacted by our choice.
We will also have to consider the serialization and CSSOM representations for each property. We can get into all of that in more detail later, but the current blocker is clear – and it’s been blocking this issue for several years now…
Before anything else can move forward, someone has to make a list of all the shorthand properties that accept physical dimensions, but should allow logical dimensions as well. That’s a lot of research, and that’s what we’re currently trying to fund.
Are you willing to help support that work?
hint
popovers, position-area
and more
We have been busy updating the Popover and CSS Anchor Positioning Polyfills, but there is still more we can do with your help.
Display color gamut ranges and more
OddContrast, OddBird’s color format converter and contrast checker, gets new features – including the ability to swap background and foreground colors, and display color gamut ranges on the color sliders. Contrast ratios now incorporate foreground color alpha values.
Start using author-defined functions
There’s been a lot of progress in the CSS Working Group lately, but I want to draw your attention to a prototype that landed in Chromium ‘Canary’ (v136+) browsers with the experimental platform features flag enabled. Author-defined Functions are coming to CSS, and you can start to experiment with them…