oddbird / oddbird/css-anchor-positioning
[BUG] Inset shorthand expansion overrides non-shorthands
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 493
- Forks
- 18
- Avg merge
- 12h 37m
- Merged PRs (30d)
- 5
Description
I think this is broader than the title suggests.
position-try-fallbacksisn't needed. A plain rule withinset: autofollowed byanchor()insets is all it needs to fail.I tested in Firefox 152 with
layout.css.anchor-positioning.enabled = false.In my test (CodePen link), I have
div.wrap, which has 100px padding on either side. Inside isdiv.band. Thendiv.panelshould be anchored to it./* A — panel 0 → 66 ✗ does not span */ .panel { position: fixed; inset: auto; /* reset the [popover] UA inset: 0 */ inset-block-start: anchor(--band end); inset-inline-start: anchor(--band start); inset-inline-end: anchor(--band end); inline-size: auto; } /* B — panel 100 → 800 ✓ spans, `inset: auto` deleted */ /* C — panel 100 → 800 ✓ spans, `top/right/bottom/left: auto` */Deleting that one declaration is the whole difference. In every case the polyfill writes identical, correct custom properties. The anchor values are never wrong; they just get overridden.
expandInsetShorthands()insrc/cascade.tsexpands the shorthand withblock.children.appendData(...), which appends the longhands to the end of the rule regardless of where the shorthand appeared in source. The installed rule becomes:.panel{position:fixed;inset:auto; inset-block-start:var(--anchor-…); inset-inline-start:var(--anchor-…); inset-inline-end:var(--anchor-…); inline-size:auto; top:auto;right:auto;bottom:auto;left:auto; /* ← appended, wins on source order */ }Physical and logical longhands resolve to the same properties, so the appended
autos win. Trigger conditions measured:inset: autobreaks both axes;inset: 0breaks both;inset-inline: autobreaks only the inline axis;inset-block: autoonly the block axis. A shorthand in a separate earlier rule is harmless.
inset: autoseems like the natural way to reset the[popover]UAinset: 0before applyinganchor()insets, so it shows up in popover-anchored panels, which seems like a common case.The longhand workaround doesn't survive minification. C looks like a clean fix but LightningCSS 1.32.0 collapses
top/right/bottom/left: autostraight back intoinset: autoand hoists it above the anchor longhands. Authoring the longhands in source doesn't reach the browser. (Native engines are unaffected: the hoisting putsinset:autobefore the anchor longhands, which is the order native needs.) I'm guessing other minifiers will do the same. A workaround that does work with minification is to reset only the specific side you need — e.g.inset-block-end: autoalone — since there's then no shorthand to collapse or expand.Happy to test a fix if that helps.
Originally posted by @freshyill in #319
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/cascade.ts at expandInsetShorthands(), then reproduce the inset: auto case from the issue with the anchor-positioning polyfill. Done means expanded inset longhands retain the shorthand’s source position so they do not override later logical anchor insets; verify the reported physical and logical shorthand cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- css, typescript
- Domain
- frontend, web-dev
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100