Corncob

Tokens | Grid | Corncob

Corncob is a framework-neutral design language built with tokens, CSS, and plain JavaScript behavior.

Grid Tokens and Utilities

Corncob provides a set of grid utilities that provide a responsive 12-column layout using CSS Grid. Use corn-container to constrain page width, corn-row to create a grid context, and corn-col-* classes to control how many columns each item spans.

This grid uses CSS Grid under the hood to lay out the 12-column system that the corn-row / corn-col-* utilities leverage. This allows the grid to take advantage of the features of CSS Grid such as column spanning, responsive layouts, and gap control while still using the corn-row / corn-col-* utilities to define the 12-column layout.

Flex based grid systems don’t apply the gap to wrapped rows of columns, whereas CSS Grid applies the gap between the grid items even when the items wrap to the next row.

This is your basic grid system. Look at Bootstrap, Carbon, Tailwind, 960 grid system or one of the other popular grid systems for reference on how the 12-column layout works and the types of more complicated layouts that are available.

AI Layout Default

When AI generates a page, section, or general layout in Corncob, this grid is the default layout system.

Use corn-container, corn-row, and corn-col-* unless a component page documents a different internal layout. If a component has its own documented structure, preserve that structure and use the grid around the component rather than replacing it.

<main class="corn-main corn-container">
<div class="corn-row">
  <aside class="corn-col-12 corn-col-lg-4">Sidebar</aside>
  <section class="corn-col-12 corn-col-lg-8">Primary content</section>
</div>
</main>

AI should follow this order:

  • start from the documented component markup
  • use the grid for page and section composition
  • only add enhancements after the canonical component code is correct

Container and Row

corn-container centers content and applies max-widths at each breakpoint. It is the outer wrapper you should use for page sections before adding rows and columns.

corn-row creates a grid context in which the corn-col-* column utilities can be placed. Each corn-row should wrap the corn-col-* elements that make up the 12-column layout.

This panel is inside corn-container
<div class="corn-container">
  <div class="corn-row">
  <!-- page content -->
  </div>
</div>

Equal Columns

Use the same span value on each item when you want evenly divided columns. In this example, three items each span 4 columns for a 3-up layout.

4 / 12
4 / 12
4 / 12
<div class="corn-container">
  <div class="corn-row">
    <div class="corn-col-4">Column one</div>
    <div class="corn-col-4">Column two</div>
    <div class="corn-col-4">Column three</div>
  </div>
</div>

Mixed Column Spans

Mix span sizes to create common application layouts like a sidebar with a content area.

Main content 8 / 12
<div class="corn-container">
<div class="corn-row">
  <aside class="corn-col-4">Sidebar</aside>
  <main class="corn-col-8">Main content</main>
</div>
</div>

Responsive Columns

Responsive modifiers let each item span different widths at different breakpoints. Here each card is full width by default, becomes 6 columns on small screens, and 4 columns on large screens.

12 - 6sm - 4lg
12 - 6sm - 4lg
12 - 6sm - 4lg
Card four (wrapped)
<div class="corn-container">
  <div class="corn-row">
    <div class="corn-col-12 corn-col-sm-6 corn-col-lg-4">Card one</div>
    <div class="corn-col-12 corn-col-sm-6 corn-col-lg-4">Card two</div>
    <div class="corn-col-12 corn-col-sm-6 corn-col-lg-4">Card three</div>
    <div class="corn-col-12 corn-col-sm-6 corn-col-lg-4">Card four (wrapped)</div>
  </div>
</div>

Note:

The @media breakpoints do not use css custom properties because variables are not supported inside media queries in css at this time.

The available responsive prefixes are:

  • corn-col-sm-* for 576px and up
  • corn-col-md-* for 768px and up
  • corn-col-lg-* for 992px and up
  • corn-col-xl-* for 1200px and up
  • corn-col-xxl-* for 1400px and up

Grid Source

:root {
  /* Breakpoints */
  --cc-breakpoint-xs: 0px;
  --cc-breakpoint-sm: 576px;
  --cc-breakpoint-md: 768px;
  --cc-breakpoint-lg: 992px;
  --cc-breakpoint-xl: 1200px;
  --cc-breakpoint-xxl: 1400px;

  /* Container max-widths */
  --cc-container-sm: 540px;
  --cc-container-md: 720px;
  --cc-container-lg: 960px;
  --cc-container-xl: 1140px;
  --cc-container-xxl: 1320px;

  /* Grid settings */
  --cc-grid-gutter: 1rem;
  --cc-grid-columns: 12;
}

.corn-container {
  box-sizing: border-box;
  margin-left: auto;
  margin-right: auto;
  width: calc(100% - (var(--cc-grid-gutter) * 2));
}

@media (width >= 576px) {
  .corn-container {
    max-width: var(--cc-container-sm);
  }
}

@media (width >= 768px) {
  .corn-container {
    max-width: var(--cc-container-md);
  }
}

@media (width >= 992px) {
  .corn-container {
    max-width: var(--cc-container-lg);
  }
}

@media (width >= 1200px) {
  .corn-container {
    max-width: var(--cc-container-xl);
  }
}

@media (width >= 1400px) {
  .corn-container {
    max-width: var(--cc-container-xxl);
  }
}

.corn-container--fluid {
  max-width: 100%;
}

/* Grid */

.corn-row {
  display: grid;
  gap: var(--cc-grid-gutter);
  grid-template-columns: repeat(var(--cc-grid-columns, 12), 1fr);
  grid-template-rows: repeat(1, 1fr);
}

.corn-col {
  grid-column: auto / span var(--cc-grid-columns);
}

/* === XS (default - no media query) === */
.corn-col-1 {
  grid-column: auto / span 1;
}

.corn-col-2 {
  grid-column: auto / span 2;
}

.corn-col-3 {
  grid-column: auto / span 3;
}

.corn-col-4 {
  grid-column: auto / span 4;
}

.corn-col-5 {
  grid-column: auto / span 5;
}

.corn-col-6 {
  grid-column: auto / span 6;
}

.corn-col-7 {
  grid-column: auto / span 7;
}

.corn-col-8 {
  grid-column: auto / span 8;
}

.corn-col-9 {
  grid-column: auto / span 9;
}

.corn-col-10 {
  grid-column: auto / span 10;
}

.corn-col-11 {
  grid-column: auto / span 11;
}

.corn-col-12 {
  grid-column: auto / span 12;
}

/* === SM ≥ 576px === */
@media (width >= 576px) {
  .corn-col-sm-1 {
    grid-column: auto / span 1;
  }

  .corn-col-sm-2 {
    grid-column: auto / span 2;
  }

  .corn-col-sm-3 {
    grid-column: auto / span 3;
  }

  .corn-col-sm-4 {
    grid-column: auto / span 4;
  }

  .corn-col-sm-5 {
    grid-column: auto / span 5;
  }

  .corn-col-sm-6 {
    grid-column: auto / span 6;
  }

  .corn-col-sm-7 {
    grid-column: auto / span 7;
  }

  .corn-col-sm-8 {
    grid-column: auto / span 8;
  }

  .corn-col-sm-9 {
    grid-column: auto / span 9;
  }

  .corn-col-sm-10 {
    grid-column: auto / span 10;
  }

  .corn-col-sm-11 {
    grid-column: auto / span 11;
  }

  .corn-col-sm-12 {
    grid-column: auto / span 12;
  }
}

/* === MD ≥ 768px === */
@media (width >= 768px) {
  .corn-col-md-1 {
    grid-column: auto / span 1;
  }

  .corn-col-md-2 {
    grid-column: auto / span 2;
  }

  .corn-col-md-3 {
    grid-column: auto / span 3;
  }

  .corn-col-md-4 {
    grid-column: auto / span 4;
  }

  .corn-col-md-5 {
    grid-column: auto / span 5;
  }

  .corn-col-md-6 {
    grid-column: auto / span 6;
  }

  .corn-col-md-7 {
    grid-column: auto / span 7;
  }

  .corn-col-md-8 {
    grid-column: auto / span 8;
  }

  .corn-col-md-9 {
    grid-column: auto / span 9;
  }

  .corn-col-md-10 {
    grid-column: auto / span 10;
  }

  .corn-col-md-11 {
    grid-column: auto / span 11;
  }

  .corn-col-md-12 {
    grid-column: auto / span 12;
  }
}

/* === LG ≥ 992px === */
@media (width >= 992px) {
  .corn-col-lg-1 {
    grid-column: auto / span 1;
  }

  .corn-col-lg-2 {
    grid-column: auto / span 2;
  }

  .corn-col-lg-3 {
    grid-column: auto / span 3;
  }

  .corn-col-lg-4 {
    grid-column: auto / span 4;
  }

  .corn-col-lg-5 {
    grid-column: auto / span 5;
  }

  .corn-col-lg-6 {
    grid-column: auto / span 6;
  }

  .corn-col-lg-7 {
    grid-column: auto / span 7;
  }

  .corn-col-lg-8 {
    grid-column: auto / span 8;
  }

  .corn-col-lg-9 {
    grid-column: auto / span 9;
  }

  .corn-col-lg-10 {
    grid-column: auto / span 10;
  }

  .corn-col-lg-11 {
    grid-column: auto / span 11;
  }

  .corn-col-lg-12 {
    grid-column: auto / span 12;
  }
}

/* === XL ≥ 1200px === */
@media (width >= 1200px) {
  .corn-col-xl-1 {
    grid-column: auto / span 1;
  }

  .corn-col-xl-2 {
    grid-column: auto / span 2;
  }

  .corn-col-xl-3 {
    grid-column: auto / span 3;
  }

  .corn-col-xl-4 {
    grid-column: auto / span 4;
  }

  .corn-col-xl-5 {
    grid-column: auto / span 5;
  }

  .corn-col-xl-6 {
    grid-column: auto / span 6;
  }

  .corn-col-xl-7 {
    grid-column: auto / span 7;
  }

  .corn-col-xl-8 {
    grid-column: auto / span 8;
  }

  .corn-col-xl-9 {
    grid-column: auto / span 9;
  }

  .corn-col-xl-10 {
    grid-column: auto / span 10;
  }

  .corn-col-xl-11 {
    grid-column: auto / span 11;
  }

  .corn-col-xl-12 {
    grid-column: auto / span 12;
  }
}

/* === XXL ≥ 1400px === */
@media (width >= 1400px) {
  .corn-col-xxl-1 {
    grid-column: auto / span 1;
  }

  .corn-col-xxl-2 {
    grid-column: auto / span 2;
  }

  .corn-col-xxl-3 {
    grid-column: auto / span 3;
  }

  .corn-col-xxl-4 {
    grid-column: auto / span 4;
  }

  .corn-col-xxl-5 {
    grid-column: auto / span 5;
  }

  .corn-col-xxl-6 {
    grid-column: auto / span 6;
  }

  .corn-col-xxl-7 {
    grid-column: auto / span 7;
  }

  .corn-col-xxl-8 {
    grid-column: auto / span 8;
  }

  .corn-col-xxl-9 {
    grid-column: auto / span 9;
  }

  .corn-col-xxl-10 {
    grid-column: auto / span 10;
  }

  .corn-col-xxl-11 {
    grid-column: auto / span 11;
  }

  .corn-col-xxl-12 {
    grid-column: auto / span 12;
  }
}