LEARN

Modern CSS patterns

Native HTML, inherited appearance and optional CSS enhancements. These patterns add no framework JavaScript. Support checks preserve readable content when an enhancement is unavailable.

1. Safe areas for viewport overlays

Full-height drawers and mobile app-shell popovers keep their controls inside the viewport safe area. Modal dialogs are centred within the safe rectangle. Ordinary cards, menus and nested containers keep their existing spacing: only the application knows whether they touch a viewport edge.

HTMLSelect text to copy
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">

Add viewport-fit=cover only when your page deliberately draws beneath display cutouts. Keep user zoom enabled. Your application must also protect its own full-bleed headers, footers and content; the framework does not pad the entire body.

Inherited physical inset tokens
TokenDefault
--re-safe-topenv(safe-area-inset-top, 0px)
--re-safe-rightenv(safe-area-inset-right, 0px)
--re-safe-bottomenv(safe-area-inset-bottom, 0px)
--re-safe-leftenv(safe-area-inset-left, 0px)

These values are physical edges even in right-to-left content. Each drawer padding side uses the larger of its normal spacing and its inset, avoiding addition of two gutters. They do not represent a virtual keyboard, and they do not lock body scrolling or turn a popover into a modal.

Specification: safe-area environment variables.

Settings drawer: simulated inset spacing

Open the native popover. Numeric overrides simulate top and bottom insets; this is a layout example, not an actual notched-device test.

HTMLSelect text to copy
<button type="button" popovertarget="safe-settings">Open safe-area example</button>
<aside id="safe-settings" class="drawer" popover="auto" aria-labelledby="safe-heading" style="--re-safe-top: 3rem; --re-safe-bottom: 2rem">
  <header><h2 id="safe-heading">Settings</h2><button type="button" popovertarget="safe-settings" popovertargetaction="hide">Close</button></header>
  <section><p>The surface reaches the viewport edges. Controls retain safe padding.</p></section>
  <footer><button type="button" popovertarget="safe-settings" popovertargetaction="hide">Done</button></footer>
</aside>

2. Container-responsive cards and subgrid

Use .card-grid for pricing plans, product summaries or project cards with exactly three direct regions: header, section, footer. Existing .card supplies the surface. Both are structural classes; settings still inherit from the parent.

Subgrid aligns those regions across each visual row. Without subgrid, independent card grids remain usable. Each footer is a named inline-size container: its action group stacks below 22rem of footer content width, even on a wide desktop. Neither ordinary cards nor the subgridded card itself receives size containment. Wrap footer actions in a native div; a labelled role=group can describe their purpose.

Set --re-column numerically to change the minimum card width. The column count follows available space. Use the existing dl.description-list for container-responsive term/value pairs.

Included in the core; modular users load reva.card-grid.css after tokens, base, components and card patterns. Subgrid specification · Container query specification.

Pricing cards with aligned regions

Resize the page: the same card footer adapts to its own width, while subgrid aligns neighbouring sections.

Team workspace with shared reporting

Keep projects, activity and reporting together. Longer headings and descriptions share row tracks with neighbouring cards.

HTMLSelect text to copy
<div class="card-grid">
  <article class="card">
    <header><h3>Personal</h3></header>
    <section><p>A simple workspace for your own projects.</p></section>
    <footer><div role="group" aria-label="Personal plan actions"><a class="button" href="#pricing">Choose Personal</a></div></footer>
  </article>
  <article class="card">
    <header><h3>Team workspace with shared reporting</h3></header>
    <section><p>Keep projects, activity and reporting together. Longer headings and descriptions share row tracks with neighbouring cards.</p></section>
    <footer><div role="group" aria-label="Team plan actions"><a class="button" href="#pricing">Choose Team</a><a href="#pricing">Compare plans</a></div></footer>
  </article>
</div>

4. Optional scroll-driven entrance motion

Load reva.scroll-motion.css after the core, or its matching .scoped.css extension after reva.scoped.css. Within inherited data-motion="expressive", cards move gently into place as they enter the scrollport. none and subtle boundaries opt out.

The effect uses a view progress timeline and an entry range, rather than a time-based animation or JavaScript observer. Content is always visible; unsupported timelines show static cards. Reduced motion, forced colours and print remove the effect. Set --re-reveal-distance for the translation distance. Avoid combining it with another card animation or translation; author CSS remains in control.

HTMLSelect text to copy
<link rel="stylesheet" href="/assets/reva/reva.css">
<link rel="stylesheet" href="/assets/reva/reva.scroll-motion.css">
<section data-motion="expressive">
  <article class="card"><h2>Visible as you scroll</h2><p>Your content.</p></article>
</section>

Scroll-driven card

This card uses the optional stylesheet loaded on this guide only.

Local motion exception

This card remains static inside the expressive section.

Scroll-driven Animations specification.

5. Optional document transitions

Load reva.transitions.css on both same-origin pages to opt into native cross-document view transitions. Normal links still navigate normally; supported browsers animate the root snapshots. There is no router or JavaScript transition trigger.

This is a document-level extension and has no scoped build. It uses inherited --re-duration, including zero duration for data-motion="none"; --re-view-duration supplies a numeric override. The OS reduced-motion preference and forced colours disable navigation transitions.

Cross-origin links, unsupported browsers and ineligible navigations retain ordinary navigation. Same-document application updates need an application-owned API call and are not supplied by this stylesheet.

HTMLSelect text to copy
<link rel="stylesheet" href="/assets/reva/reva.css">
<link rel="stylesheet" href="/assets/reva/reva.transitions.css">
<a href="/another-page">Open another page</a>

Open the two-page transition example

View Transitions Level 2 specification.