Skip to content

Add CSS Grid parsing (track lists, placement, areas, subgrid, shorthands)#223

Open
jhaygood86 wants to merge 7 commits into
TylerBrinks:masterfrom
jhaygood86:feature/css-grid
Open

Add CSS Grid parsing (track lists, placement, areas, subgrid, shorthands)#223
jhaygood86 wants to merge 7 commits into
TylerBrinks:masterfrom
jhaygood86:feature/css-grid

Conversation

@jhaygood86

@jhaygood86 jhaygood86 commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds CSS Grid parsing to ExCSS (CSS Grid Layout Level 1 / Level 2): value grammars, properties, converters, and serialization.

Delivered as 7 ordered commits:

  1. Track-list parsingGridTrackListGrammar (lengths, %, fr, auto, min-content/max-content, minmax(), fit-content(), repeat() incl. auto-fill/auto-fit); grid-template-columns/-rows, grid-auto-columns/-rows/grid-auto-flow.
  2. Line-based placementGridLineGrammar (auto | <integer> | span n | named); grid-column/-row-start/-end longhands + the grid-column/grid-row/grid-area shorthands (with the §8.3.1 omitted-value copy rule).
  3. Box alignmentjustify-items/justify-self + place-items/place-content/place-self (reusing the existing align-*/justify-content converters).
  4. grid-template-areasGridTemplateAreasGrammar (validates rectangular named areas). Also makes ValueBuilder accept [/] tokens in a value (prerequisite for named lines; mirrors the existing unicode-range Range-token handling).
  5. Named grid lines[name] groups in track lists + <custom-ident>/Nth named-line placement.
  6. subgrid — accepted in the track-list grammar (subgrid [ <line-name-list> ]?).
  7. grid / grid-template mega-shorthands — via GridTemplateShorthand; excluded from serialization reconstruction so ToCss() never re-collapses the longhands.

Design

Every grid value-converter validates via the grammar and preserves the authored text (mirroring the existing AspectRatioValueConverter). The grammar model types (GridTemplate, GridLine, GridAreas) back the grammars and tests.

Portability

Builds clean across all 8 target frameworks (0 errors/warnings). C# stays within LangVersion 9.

Tests

GridTrackListGrammarTests, GridLineGrammarTests, GridTemplateAreasGrammarTests, GridTemplateShorthandTests, plus per-feature property round-trip tests — 174 new cases. Full suite green at 1690 passing, no regressions.

…o-*)

Introduce the shared GridTrackListGrammar parsing a full <track-list>:
lengths, percentages, fr, auto, min-content/max-content, minmax(),
fit-content(), repeat(N, ...) expanded inline, and
repeat(auto-fill|auto-fit, ...) recorded as a layout-time section. The
grammar emits GridTemplate / GridTrackSize model types.

Add the grid-template-columns / grid-template-rows / grid-auto-columns /
grid-auto-rows / grid-auto-flow longhands. Each is validated by the
grammar (grid-auto-flow as [row|column] || dense) and preserves the
authored text as a TokenValue, mirroring the aspect-ratio converter.
Introduce the shared GridLineGrammar for a single <grid-line>
(auto | <integer> | span <integer>) and the placement longhands
grid-column-start/end and grid-row-start/end.

Add the grid-column / grid-row / grid-area shorthands via a shared
GridPlacementShorthand that splits on '/', validates each component with
the grammar, preserves each component's internal whitespace, and applies
the CSS Grid 8.3.1 omitted-value copy rule. The result distributes to the
longhands through a MappedShorthandValue.
Add the justify-items / justify-self longhands and the place-items /
place-content / place-self shorthands, reusing the existing align-items /
align-content / align-self / justify-content value grammars. The place-*
shorthands use a periodic <align> <justify>? converter so a single value
applies to both axes.
Add the shared GridTemplateAreasGrammar, which parses the quoted-string
rows into a rectangular GridAreas grid (equal columns per row, each named
area a single filled rectangle; '.' runs are empty cells), plus the
grid-template-areas property and its text-preserving converter.

Also accept SquareBracketOpen/Close tokens in ValueBuilder so a grid
line-names group [name ...] survives strict value parsing, mirroring the
existing unicode-range Range-token handling. This is a prerequisite for
named grid lines.
Extend GridLineGrammar to accept a bare <custom-ident> named line and the
<custom-ident> <integer> Nth-line form (guarding against auto/span/none and
the CSS-wide keywords). Extend GridTrackListGrammar to collect [name] groups
in the top-level track list into GridTemplate.LineNames (name -> sorted
1-based line numbers); names inside repeat() are rejected. The bare
custom-ident now drives the grid-column/row/area omitted-value copy rule.
Extend GridTrackListGrammar to accept subgrid [ <line-name-list> ]? on
grid-template-columns/rows (CSS Grid Level 2 9): the axis adopts the parent
grid's tracks, carrying no track sizes, with an optional run of [name]
line-name groups recorded per line. A track size after subgrid, subgrid not
first, repeat() of line names, or an unclosed bracket are all rejected.

This is the parser subset only; the typed-cascade CssProperty<T> plumbing
from the source commit is intentionally not ported.
Implement the grid-template (CSS Grid 7.4) and grid (7.8) shorthands as a
CSS-OM shorthand-to-longhand expansion. A shared GridTemplateShorthand helper
splits the value on the top-level '/', runs the areas-form row scanner
(feeding strings to GridTemplateAreasGrammar and synthesizing the
grid-template-rows track list), and validates each slice via the existing
grid grammars; TryParseAutoFlowSide handles the [auto-flow && dense?]
<track-size>* forms. Two thin converters emit a MappedShorthandValue over the
covered longhands, resetting omitted longhands to their initial value.

Register both via a new AddLogicalShorthand so they parse/expand but are
excluded from serialization reconstruction (GetShorthands), so ToCss never
re-collapses the longhands into a mega-shorthand.
@jhaygood86
jhaygood86 marked this pull request as ready for review July 24, 2026 20:39
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