Skip to content

Reject a single-axis position followed by a length in transform-origin#217

Open
jhaygood86 wants to merge 1 commit into
TylerBrinks:masterfrom
jhaygood86:bugfix/transform-origin-keyword-then-length
Open

Reject a single-axis position followed by a length in transform-origin#217
jhaygood86 wants to merge 1 commit into
TylerBrinks:masterfrom
jhaygood86:bugfix/transform-origin-keyword-then-length

Conversation

@jhaygood86

Copy link
Copy Markdown
Contributor

Summary

transform-origin accepted two forms that are invalid per CSS Transforms 1:

  • transform-origin: top 2px — a single-axis position followed by a length. It was accepted and resolved to center/top with 2px swallowed as the z-offset, but the trailing <length> z-offset only exists in the two-value production.
  • transform-origin: 2px left (and 2px left 10px) — a <length> in the horizontal slot paired with a horizontal keyword left in the vertical slot. The two-value form is ordered (horizontal then vertical), and only the keyword-only form may be reordered, so this pair is invalid.

Fix

The converter is restructured around explicit Horizontal/Vertical axis converters and a TwoValuePosition that requires both axes to be present. The <length> z-offset is gated behind TwoValuePosition, so it can only follow a genuine two-value position; a one-or-two-value <position> with no z-offset is the fallback.

Grammar

[ left | center | right | top | bottom | <length-percentage> ]
| [ left | center | right | <length-percentage> ] [ top | center | bottom | <length-percentage> ] <length>?
| [ [ center | left | right ] && [ center | top | bottom ] ] <length>?

Tests

  • Adds CssTransformOriginVerticalKeywordThenLengthIllegal / ...WithZIllegal (top 2px, top 2px 10px).
  • Updates the two existing tests that asserted the non-conformant 2px left / 2px left 10px forms to assert rejection.
  • Legal forms (left 2px, 2px 30%, right top, 2px 30% 10px, left 5px -3px, …) continue to pass. Full suite green.

Ported from a fix made in PeachPDF, which vendors ExCSS.

transform-origin accepted `top 2px` (resolved to center/top with 2px as
the z-offset) and `2px left` (a length in the horizontal slot paired with a
horizontal keyword in the vertical slot), both invalid per CSS Transforms 1
(https://www.w3.org/TR/css-transforms-1/#transform-origin-property).

The two-value form is ordered (horizontal then vertical) and only the
keyword-only form may be reordered; the trailing <length> z-offset exists
only in the two-value production. Restructure the converter around explicit
Horizontal/Vertical axis converters and a TwoValuePosition that requires both
axes, and gate the z-offset behind it so it can only follow a genuine
two-value position.

Fixes the two tests that asserted the non-conformant `2px left` forms.
@jhaygood86
jhaygood86 marked this pull request as ready for review July 24, 2026 19:59
@jhaygood86
jhaygood86 marked this pull request as draft July 24, 2026 20:35
@jhaygood86
jhaygood86 marked this pull request as ready for review July 24, 2026 20:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant