Usage
The grid, the bleed and the setup, in HTML and CSS.
Basic layout
og-grid centres the columns, caps them at the max width and pads the sides. Its children span the whole content area until you place them.
<div class="og-grid">
<aside class="sidebar">…</aside>
<main class="content">…</main>
</div>The rest is your CSS. Any grid property works on the children:
.sidebar {
grid-column: span 3;
}
.content {
grid-column: span 9;
}Placing items
Lines are numbered like in any grid. The lines also have names: content-start and content-end around the columns, col-start N and col-end N around column N.
.single {
grid-column: col-start 5 / col-end 5;
}
.range {
grid-column: col-start 2 / col-end 4;
}
.from {
grid-column: col-start 7 / span 6;
}
.cover {
grid-column: content;
grid-row: 3;
}Responsive
There are no breakpoints of its own: a media query moves things like on any grid.
.card {
grid-column: span 12;
}
@media (min-width: 48rem) {
.card {
grid-column: span 6;
}
}
@media (min-width: 64rem) {
.card {
grid-column: span 4;
}
}Nesting
grid-template-columns: subgrid reuses the parent's columns instead of making new ones, so nested items stay aligned to the page. The gutter comes with them.
.articles {
grid-column: span 8;
display: grid;
grid-template-columns: subgrid;
}
.articles > article {
grid-column: span 4;
}Aligned rows
grid-template-rows: subgrid does the same for rows: sibling cards share them, so titles, text and footers line up even when the text is longer in one of them.
.card {
grid-column: span 4;
grid-row: span 3;
display: grid;
grid-template-rows: subgrid;
}Full bleed
og-full runs an item to the edges of the screen. og-start-full and og-end-full bleed one side only, and og-pl-bleed, og-pr-bleed and og-px-bleed bring the content back on the columns.
<div class="og-grid">
<img class="og-full" />
<nav class="og-start-full og-pl-bleed menu">…</nav>
</div>Where the item ends is still your CSS: set only the side that doesn't bleed, so the class keeps the other. The classes have no breakpoints, but the distance to the edge is --og-bleed, so a media query bleeds only where you want it to:
.menu {
grid-column-end: col-end 3;
}
@media (min-width: 64rem) {
.cover {
margin-inline: calc(var(--og-bleed) * -1);
}
}Without columns
og-container gives you the width and padding of the grid, without columns.
<header class="og-container">…</header>Setup
Everything is a custom property. I set them once on :root, after the import:
@import "outgrid";
:root {
--og-columns: 12;
--og-max-width: 90rem;
--og-padding: 1rem;
--og-gutter-x: 2rem;
--og-gutter-y: 2rem;
}Every class has zero specificity, so any rule of yours wins over the defaults and a single grid can change without touching the properties:
.compact {
row-gap: 0;
}Reference
| class | |
|---|---|
og-grid | the grid: centred, capped at the max width, padded on both sides |
og-container | the width and padding of the grid, without columns |
og-full | edge to edge of the screen |
og-content | the whole content area; cancels any bleed |
og-start-full | bleeds off the left edge |
og-end-full | bleeds off the right edge |
og-pl-bleed / pr / px | padding as wide as the bleed, to bring content back on the columns |
| token | |
|---|---|
--og-columns | number of columns; 12 by default |
--og-max-width | the widest the content area gets, padding excluded |
--og-padding | side padding of the grid |
--og-gutter-x | space between columns |
--og-gutter-y | space between rows |
--og-bleed | distance from the content area to the edge of the screen; computed, read it, don't set it |