Container

Centers content with a max-width and horizontal padding.

import { Container } from "@ps1ui/core";

Sizes

size="sm" — max-width 40rem
size="md" — max-width 48rem
size="full" — unbounded
<Container size="sm">max-width 40rem</Container>
<Container size="md">max-width 48rem</Container>
<Container size="full">unbounded</Container>

Responsive padding

px switches from md to 2xl at the md container breakpoint.
<Container size="sm" px={{ base: "md", md: "2xl" }}>
  Horizontal padding scales with the container width.
</Container>

Semantic element

A Container usually wraps the page's own content region, so it is normally a landmark: <main>, a <section>, the<footer>. Pass as to render that tag instead of the default <div> rather than layering a role onto it.

The centering, max-width cap, padding and queryContainer behave identically on any tag; the rendered element's own attributes (and a correctly typed ref) become available, and as also accepts a component rather than a tag name.

A document may only have one <main>, and this page is already inside the site layout's — so the example below uses as="section". On a real page the outermost Container is usually the <main> itself.

As a landmark element

as="section" — the landmark and the centered measure in one element
<Container as="section" size="md" aria-label="Pricing">
  Section content, centered and capped at 48rem.
</Container>

Query container

Responsive props resolve against the nearest ancestor that is a container-query context — normally the PS1Root wrapping your app. Pass queryContainer to make aContainer that context instead, so its descendants respond to that Container's own width rather than the page's.

It is opt-in because container-type: inline-size erases the element's intrinsic width. width: 100% keeps Container upright in most parents, but as an item of an auto-sized grid track it still collapses to zero — give it a definite inline size whenever you turn it on.

Query container

Padding flips at the md container breakpoint.
{/* The inner Container now measures the 320px outer
    Container instead of the page, so it stays on its `base` padding. */}
<Container queryContainer size="full" px="none" style={{ width: 320 }}>
  <Container px={{ base: "none", md: "2xl" }}>
    Padding flips at the md container breakpoint.
  </Container>
</Container>

Props

PropTypeDefaultDescription
asElementType"div"

Element or component to render instead of the default <div> — e.g. "main" / "section" when the centered measure is also the page landmark.

size"sm" | "md" | "lg" | "xl" | "full""lg"

Max-width preset; "full" removes the cap.

px"none" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl""lg"

Horizontal padding on the space scale.

queryContainerbooleanfalse

Make this Container a container-query context so descendants' responsive props resolve against its width instead of the nearest ancestor container. Costs the Container its intrinsic width — `width: 100%` keeps it upright in most parents, but as an auto-sized grid track's item it still collapses to 0.

Also accepts the attributes of the element rendered via as (default: <div>).