Base-10 proportional layout engine based on the actual container width. No media queries. No breakpoints. A single CSS class.
With native CSS Grid, repeat(auto-fit, minmax(...)) creates equal columns. It's impossible to express relative proportions (this column = 2x wider than that one).
Media queries force you to think in viewport size, not container size. A component in a 300px sidebar and the same component full-width receive the same breakpoints.
A single CSS class is enough: grid-1-2-7. The numbers are weights on a base-10 scale: each unit equals 10% of the container width. Here, 10% + 20% + 70% = 100% of the row.
When the sum of weights exceeds 10 (100%), extra children wrap to the next row automatically. No media queries, no breakpoints — the proportions are fixed percentages of the container.
Each weight unit equals 10% of the container width. A row is complete when the sum reaches 10 (100%). grid-5-5 creates two 50% columns. grid-2-6-2 creates a 20%-60%-20% layout. Weights beyond 10 per row wrap to the next line.
grid-5-5 — 2 equal columns (50% + 50%)grid-3-7 — 30% / 70% splitgrid-2-6-2 — sidebar - content - sidebar (20% - 60% - 20%)grid-1-2-4-2-1 — pyramid (10% - 20% - 40% - 20% - 10%)
When the sum of weights is less than 10, Grid-Pro switches to ratio mode: weights become CSS fr units, stretched to fill 100% of the container. grid-4-2-1 → 4fr 2fr 1fr (57% + 29% + 14%).
grid-4-2-1 — proportional 4:2:1 ratio (57% + 29% + 14%)grid-2-1 — 2/3 + 1/3 split (67% + 33%)grid-1-1-1-1-1 — 5 equal columns via ratio (20% each)
Grid-Pro uses a base-10 grid system: repeat(10, 1fr). Each weight unit represents 10% of the container width. The columns always fill the container proportionally — no breakpoints, no collapse.
Resize the window or drag the slider below to see the proportions hold at every width.
Use the utility classes gap-0 through gap-7 for uniform spacing, or gap-x-* / gap-y-* to control horizontal and vertical separately. You can also use the CSS variable --gridpro-gap directly.
gap-0 (0px)gap-3 (16px)gap-6 (48px)gap-x-6 gap-y-1 — large horizontal gap, small vertical| Class | CSS Variable | Value |
|---|---|---|
gap-0 | --gridpro-gap | 0px |
gap-1 | --gridpro-gap | 4px |
gap-2 | --gridpro-gap | 8px |
gap-3 | --gridpro-gap | 16px |
gap-4 | --gridpro-gap | 24px |
gap-5 | --gridpro-gap | 32px |
gap-6 | --gridpro-gap | 48px |
gap-7 | --gridpro-gap | 64px |
Add the class gridpro-masonry to the container. The engine measures the actual height of each child and calculates the number of micro-rows (4px) needed via grid-row-end: span N. Items stack vertically filling gaps.
getBoundingClientRect().height. Images must have explicit dimensions or be fully loaded before apply() runs.
Only the weights matching available children are used. grid-2-6-2 with 2 children assigns span 2 and span 6 (the 3rd weight is ignored).
Extra children wrap to the next row, cycling through the weights pattern (CSS Grid auto-placement).
gridpro:applied
On every layout change, the container emits a CustomEvent with a detail object containing the grid state. Useful for animating transitions, updating an external calculation, or logging.
| Property | Type | Description |
|---|---|---|
detail.columns | number | Number of columns in the first row |
detail.template | string | First-row weights as fr units (e.g.: "1fr 2fr 7fr") |
detail.collapsed | boolean | Always false (no responsive collapse in base-10 mode) |
The plugin auto-initializes on load. For dynamic elements (created after DOM ready), use the public API.
GridPro.init(el, options?)Attaches observers (ResizeObserver + MutationObserver) and applies the grid once. Only runs once per element (internal flag).
| Option | Type | Default | Description |
|---|---|---|---|
debounce | number | 80 | ResizeObserver debounce delay (ms) |
autoObserve | boolean | true | If false, no observers (manual control) |
equalHeight | boolean | false | Force all items to the tallest item's height |
masonryBaseRow | number | 4 | Base micro-row height for masonry calculations (px) |
migrateLegacyRows | boolean | true | Auto-unwrap legacy .gridpro-row wrappers |
GridPro.apply(el)Recalculates and applies the grid immediately. Does not attach observers. Useful after a class or content change you manage yourself.
GridPro.destroy(el)
Disconnects all observers (ResizeObserver + MutationObserver), removes inline grid styles, removes .gridpro-active, and dispatches a gridpro:destroyed event.
GridPro.refresh(el)
Invalidates the signature cache and re-applies the grid immediately. Shortcut for el._gridproSig = null; GridPro.apply(el).
GridPro.initAll(root?, options?)
Initializes all Grid-Pro containers found within a root element (defaults to document). Useful for dynamically loaded sections.
GridPro.configure(options)
Sets global defaults for all Grid-Pro instances. Call before init() or initAll().
| Option | Type | Default | Description |
|---|---|---|---|
debounce | number | 80 | ResizeObserver debounce delay (ms) |
mobileBreakpoint | number | 768 | Container width threshold for mobile single-column mode (px) |
masonryBaseRow | number | 4 | Base micro-row height for masonry calculations (px) |
By default, the mode is auto-detected from the weight sum. Add .gridpro-ratio or .gridpro-base10 to override.
| Class | Effect |
|---|---|
.gridpro-ratio | Force ratio mode (fr units, 100% width) |
.gridpro-base10 | Force base-10 mode (repeat(10, 1fr) + span) |
.gridpro-masonry | Enable masonry vertical packing |
.gridpro-equal-height | Force all items to the tallest item's height |
Add the class gridpro-equal-height (or pass { equalHeight: true }) to make all items match the tallest item's height. Incompatible with masonry.
If JavaScript fails to load, the following CSS rule takes over automatically. The layout won't be proportional but will remain functional thanks to auto-fit. As soon as JS initializes and adds .gridpro-active, the fallback is neutralized.
Grid-Pro makes it easy to build responsive dashboard layouts. Here's how to structure a complete analytics interface using only Grid-Pro classes — KPI cards, charts, and data panels adapt fluidly to any container width.
grid-5-5 — KPI cards (2x2 responsive grid)grid-7-3 — line chart + doughnut (70% / 30%)grid-5-5 — two bar charts (50% / 50%)
The admin dashboard includes server-side filtering to exclude specific IPs (e.g. 127.0.0.1) and cities from all analytics — KPI counts, charts, and data tables are all computed from the filtered dataset.
grid-7-3 for main+sidebar chart layouts and grid-5-5 for equal panels. The proportions remain stable regardless of the container width — ideal for embedded dashboard widgets.