component — brand
Low Title
The headline set low in the frame, the signature of the system: an Outfit display title under a hairline, with one sentence and one action beside it (m) or in a footer row beneath it (xl). Sinks to the floor of a Stage with mt-auto.
- brand
- headline
- hero
- typography
- title
use a low title when
- The headline of a
Stage—as="h1"on the first stage of a page,h2after that. size="xl"for a gallery page's title, where the headline is most of the frame.
don't
- The title is lowercase, short, one idea, and ends with a full stop. A second sentence goes in
children, not the title. - One action only, normally a
TextLink— not a row of buttons. - Not a section heading inside the page body; that is a
display-sheading with anEyebrowcount.
03 examples
Medium
The default: display-m under a hairline, one sentence and one action in the side column.
full-stack software development.
We build web applications end to end: database, backend and interface.
get started →Extra large
Outfit Thin at display-xl for gallery pages; the sentence and the action move to a footer row.
full-stack software.
Two developers, Munich.
talk to us →Title only
Both the sentence and the action are optional; the hairline and the low setting stay.
contact.
what to use instead
by jobBy what the low title was doing.
source
low-title.tsxCopy this into your project. Resolve its dependencies from the registryDependencies in the component's API entry.
import { cn } from "@/lib/utils"
/**
* LowTitle — quebi design system
*
* The headline set low in the frame, the signature of the system. It takes
* `mt-auto`, so inside a `Stage` (or any flex column) it sinks to the floor
* and leaves the middle empty.
*
* - `size="m"` (default): `display-m` under a hairline, with a side column
* holding the one sentence and the one action.
* - `size="xl"`: `display-xl`, Outfit Thin, for gallery pages; the sentence
* and the action move to a footer row under a hairline.
*
* The title is lowercase, short, one idea, and ends with a full stop. It is
* lowercased by CSS too, so a title that arrives in sentence case from a CMS
* still reads as the system wants while the source text stays intact. Give it
* one action, normally a `TextLink` ("get started →").
*/
export interface LowTitleProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "title"> {
/** The headline. Lowercase, short, ends with a full stop. */
title: React.ReactNode
/** `m` (default) with a side column; `xl` with a footer row. */
size?: "m" | "xl"
/**
* The heading element. `h1` on the first stage of a page, `h2` (default)
* after that — a library default of `h1` would put a second one on any page
* that already has its own.
*/
as?: "h1" | "h2"
/** One call to action, normally a `TextLink`. */
action?: React.ReactNode
/** The one sentence that goes with the title. */
children?: React.ReactNode
}
export function LowTitle({
title,
size = "m",
as: Heading = "h2",
action,
children,
className,
...props
}: LowTitleProps) {
const hasAside = children != null || action != null
if (size === "xl") {
return (
<div data-slot="low-title" data-size="xl" className={cn("mt-auto", className)} {...props}>
<Heading className="m-0 font-display text-quebi-display-xl text-quebi-fg lowercase max-sm:text-quebi-display-l max-sm:font-thin">
{title}
</Heading>
{hasAside && (
<div className="mt-4.5 flex items-end justify-between gap-4 border-t border-quebi-hairline pt-3.5">
{children != null && <p className="m-0 text-quebi-caption text-quebi-fg-muted">{children}</p>}
{action}
</div>
)}
</div>
)
}
return (
<div
data-slot="low-title"
data-size="m"
className={cn(
"mt-auto grid grid-cols-1 items-end gap-5 border-t border-quebi-hairline pt-4 sm:grid-cols-[1.3fr_1fr]",
className,
)}
{...props}
>
<Heading
className={cn(
"m-0 font-display text-quebi-display-m text-quebi-fg lowercase",
// The first stage of a page carries the larger cut on a wide screen.
Heading === "h1" && "md:text-quebi-display-l",
)}
>
{title}
</Heading>
{hasAside && (
<div>
{children != null && <p className="m-0 mb-3 text-quebi-body-s text-quebi-fg-muted">{children}</p>}
{action}
</div>
)}
</div>
)
}