Skip to main content

Catalog · Page structure

Main and sections

Gives a landing page its rhythm: wide room between the blocks of the main, a closer one inside each section, with its head, and an optional glow behind the page.

Fits best: landing — the body of a landing page, between the header and the footer

Example

A main with two sections: the first shows its blocks as boxes, the second has a real head.

Heading
Lead
Content
Heading
Content

Sections are 64 px (--luz-space-3xl) apart in the main; their blocks, 16 px (--luz-space-md).

Why teams switch

One count for every shelf

Acme Stock reads each sale as it happens, in every shop.

Content

The head of a section: an eyebrow, a title and a lead. The title is a paragraph here, as this page already has its headings.

Upcoming talks

See all talks
Content

A title with a link to the whole list, at the end of the head. The title and the link are placeholders: write your own.

.luz-glow

Known issues

None known for the main and the sections. A section on core's band has the band's.

Code

Copy the markup

Bundler
import "@luz-ds/catalog/components/glow.css";
HTML
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@luz-ds/catalog@0.3.0/dist/components/glow.min.css" integrity="sha384-Jz/eFLH0Ygi6iqQ+xcRrRhniKJbUEGD6yVdCDsRKJDrTq4H6FcjT1dFGo7UmRWba" crossorigin="anonymous">
Bundler
import "@luz-ds/catalog/components/main.css";
HTML
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@luz-ds/catalog@0.3.0/dist/components/main.min.css" integrity="sha384-fSDcBofUvDclss8ermBOj5Mp3HwqS0KiPg5PdY1+ux+91hdpKOF9wcLmM+G3Coq4" crossorigin="anonymous">
Bundler
import "@luz-ds/catalog/components/section.css";
HTML
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@luz-ds/catalog@0.3.0/dist/components/section.min.css" integrity="sha384-IQZYJCtvKeQG+qt4Hfu95jMHtMMQam8TJG78lOSvj106ud4ncidLUQ+JjWKJKKpV" crossorigin="anonymous">
HTML
<body class="o-page luz-glow">
  <a class="luz-skip-link" href="#main-content">Skip to content</a>
  <!-- the header -->
  <main id="main-content" class="o-container o-stack luz-main" tabindex="-1">
    <!-- the hero -->
    <section class="o-stack luz-section" aria-labelledby="programme-title">
      <h2 id="programme-title">Programme</h2>
      <p>Twelve talks and six workshops over two days.</p>
    </section>
    <section class="o-stack luz-section luz-band" aria-labelledby="last-seats-title">
      <h2 id="last-seats-title">Registration closes on 30 April</h2>
      <div class="o-actions">
        <a class="luz-btn luz-btn--primary" href="#register">Register now</a>
      </div>
    </section>
  </main>
  <!-- the footer -->
</body>
HTML
<section class="o-stack luz-section" aria-labelledby="why-title">
  <p class="luz-section__eyebrow">Why teams switch</p>
  <h2 class="luz-section__title" id="why-title">One count for <em>every</em> shelf</h2>
  <p class="luz-section__lead">Acme Stock reads each sale as it happens, in every shop.</p>
  <!-- the content -->
</section>
HTML
<section class="o-stack luz-section" aria-labelledby="talks-title">
  <div class="o-row">
    <h2 class="luz-section__title" id="talks-title">Upcoming talks</h2>
    <a class="luz-section__more" href="/talks/">See all talks</a>
  </div>
  <!-- the content -->
</section>

Variants and options

Classes of the landing on core's objects, the head of a section and two knobs. A section stands out on core's band.

ClassEffect
.luz-main
On main.o-container.o-stack: 64 px (--luz-space-3xl) between the blocks and under the last one; none above the first, as the hero brings its own
.luz-section
On section.o-stack: 16 px (--luz-space-md) between its children
.luz-section__eyebrow
Above the title: a short label, as the hero's eyebrow
.luz-section__title
The title, as the hero's one step smaller: 3xl; 2xl below 1024 px and xl at 640 px and below
.luz-section__lead
One or two sentences in the secondary text colour, 70 characters wide at most; lg, and base at 640 px and below
.luz-section__more
A link at the end of the head, such as "See all talks". Put it with the title in a .o-row: an auto margin on the inline start pushes it to the end, left or right, and it wraps to its own line, still at the end
--luz-title-accent
A knob: the colour of the em in a hero's or a section's title. Unset, the title's colour
.luz-glow
On the .o-page element: the brand's subtle tint at the top, in the corner where reading starts, over a fade from the page surface to the muted one; none in print
--luz-glow-x
A knob on the glow's element: where along the top edge the tint sits, 0% the left to 100% the right, in both directions. Unset, the start edge

How it works

CSS from components/main.css, section.css and glow.css of @luz-ds/catalog on core's objects. No JavaScript.

  • Core's .o-container gives the main its width and gutters, and .o-stack the column; the catalog layer comes after core's objects, so its gaps win over the stack's.
  • The glow's tint sits at the start edge: top left in a left-to-right page and top right in a right-to-left one. --luz-glow-x moves it: 50% centres it in both directions.
  • The head shares its rules, and the em knob, with the hero.
  • The link of .luz-section__more is aligned to the end with margin-inline-start: auto, so it follows the reading direction; it is aligned to the title's baseline.
  • Use a section on a <section> when the group has its own heading, or on a <div> when it does not.

Without JavaScript

Nothing changes: the main, the sections and the glow are CSS.

Keyboard and ARIA

None of the three has an interaction or a role of its own.

  • The <main> is the main landmark, and the target of the skip link: give it id and tabindex="-1".
  • The link of .luz-section__more is an ordinary link, in the order of the page after the title. Its text names the page it opens, so out of context it still makes sense in a list of links.
  • A <section> named with aria-labelledby becomes a region landmark; name only the sections people would jump to.
  • The glow carries no meaning: without it (forced colors, print) nothing is lost.

Contrast and focus are in the Design tab.

Design

When to use

Use the main and its sections for every page of a landing site, so the space between blocks is the same everywhere. Use the glow on a short page, such as a home page or a sign-up page, to give it some warmth.

When not to use

Do not use a section to space the paragraphs of running text: the text styles already do.

  • For blocks side by side, use core's grid objects, such as ul.o-grid.o-grid--split for a few features of equal weight.
  • Do not use the glow on a long page or behind a band: the tint competes with the band's.

Do and don't

Do Blocks of different kinds, spaced as one group: a heading, a lead, the content.
Don't Running text in a section: every paragraph gets the section's gap, and the text reads as separate blocks.
Do An eyebrow of a few words that names the topic, over a title that says the point.
Don't A sentence as the eyebrow: it is set in small spaced capitals, which are slow to read at length.

Writing the content

Start each section with a heading that says what the section is for.

  • Use the next heading level after the page title: <h2> under the hero's <h1>.
  • Keep one idea per section; a second idea is a second section.
  • The eyebrow is one to three words, a label and not a sentence. The title is the point of the section, in sentence case. The lead is one or two sentences; leave out any of the three you do not need.
  • Make the link of .luz-section__more say where it goes: "See all talks", not "See all" or "More". Its text is yours; the examples are placeholders.
  • Put the em on one or two words of a title, to make them stand out. Use it for emphasis, not for colour alone.

Contrast and focus

The main and the sections are spacing only; the head adds primary and secondary text on the page. The glow puts the page's text on the brand's subtle tint in one corner, and on the muted surface at the bottom.

PartColour on backgroundLightDarkHigh contrastNeeds
Section title
--luz-text-primary on --luz-surface-page
15.8:1
15.1:1
21.0:1
4.5:1
Link at the end of the head
--luz-brand-primary on --luz-surface-page
5.6:1
7.7:1
14.1:1
4.5:1
Eyebrow and lead
--luz-text-secondary on --luz-surface-page
6.2:1
7.5:1
19.3:1
4.5:1
Text in the tinted corner
--luz-text-primary on --luz-brand-subtle over --luz-surface-page
14.3:1
12.7:1
20.1:1
4.5:1
Secondary text in the tinted corner
--luz-text-secondary on --luz-brand-subtle over --luz-surface-page
5.6:1
6.3:1
18.5:1
4.5:1
Text at the bottom
--luz-text-primary on --luz-surface-muted
15.8:1
15.1:1
20.1:1
4.5:1
Secondary text at the bottom
--luz-text-secondary on --luz-surface-muted
6.2:1
7.5:1
18.4:1
4.5:1

Measured from the token values of each mode, rounded down. Needs is the WCAG 2.2 AA minimum: 4.5:1 for text.

  • Focus: none of the three takes focus; what is inside keeps its own ring.
  • Accent: --luz-title-accent is yours. Check the colour you set against the page surface in every mode you ship, as text needs 4.5:1.
  • Forced colors: the glow is removed, and the page is the system's background.

Tokens it uses

The 18 tokens that the .luz-main, .luz-section and .luz-glow rules of catalog’s components/main.css, section.css and glow.css read, by family. Each family links to its page, with the values in every mode. In Figma they are variables with the same names: see Tokens in Figma.

Spacing and sizing
--luz-space-3xl, --luz-space-md, --luz-space-sm
Typography
--luz-font-heading, --luz-font-mono, --luz-font-sans, --luz-text-2xl, --luz-text-3xl, --luz-text-4xl, --luz-text-base, --luz-text-lg, --luz-text-xl, --luz-text-xs

Keyboard and ARIA are in the Code tab.