Skip to content

[BUG] Inset shorthand expansion overrides non-shorthands #456

Description

@jamesnw

I think this is broader than the title suggests. position-try-fallbacks isn't needed. A plain rule with inset: auto followed by anchor() 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 is div.band. Then div.panel should 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() in src/cascade.ts expands the shorthand with block.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: auto breaks both axes; inset: 0 breaks both; inset-inline: auto breaks only the inline axis; inset-block: auto only the block axis. A shorthand in a separate earlier rule is harmless.

inset: auto seems like the natural way to reset the [popover] UA inset: 0 before applying anchor() 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: auto straight back into inset: auto and hoists it above the anchor longhands. Authoring the longhands in source doesn't reach the browser. (Native engines are unaffected: the hoisting puts inset:auto before 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: auto alone — since there's then no shorthand to collapse or expand.

Happy to test a fix if that helps.

Originally posted by @freshyill in #319

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions