Spacer
Empty space as an element. It exists for one job: pushing siblings apart inside a flex container.
Playground
Change a prop and watch it. The code below follows along.
Live
Open full cardInstall and import
Spacer is in @dovetail-ds/react. Install it with React, if you haven't:
npm install @dovetail-ds/react react react-dom
import { Spacer } from "@dovetail-ds/react";
Import @dovetail-ds/react/styles.css once at your app's root, then your theme after it. Setup covers the stylesheets, fonts and dark mode.
Guidelines
Empty space as an element. It exists for one job: pushing siblings apart inside a flex container.
Use it flexible, rarely fixed
With no size, Spacer absorbs the remaining space: the clean way to push a trailing action to the far end of a toolbar without margin-left: auto scattered through the markup.
``jsx <Inline align="center"> <Heading>Members</Heading> <Spacer /> <Button variant="primary">Invite</Button> </Inline> ``
A fixed size is almost always the wrong tool. If two children need a gap, set gap on the Stack or Inline that holds them; the container should own the rhythm, not a sibling wedged between them. Reach for a fixed Spacer only when one gap in a set genuinely differs and you do not want to split the container in two.
Spacer is aria-hidden. It never carries content.
Props
The typed contract, from Spacer.d.ts.
import * as React from "react";
/** Flexible or fixed empty space inside a flex container. */
export interface SpacerProps extends React.HTMLAttributes<HTMLElement> {
/** Fixed size from the space scale. Omit to absorb all remaining space. */
size?: "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl";
/** @default "vertical" */
axis?: "vertical" | "horizontal";
}
export declare function Spacer(props: SpacerProps): React.JSX.Element;
Tokens it reads
Every custom property Spacer.jsx resolves, read from the source: 7 semantic. Component tier first, because that is the one to reach for.
- semantic Shared roles. Override one and everything using that role moves with it.
| Token | Tier | Declared as |
|---|---|---|
--dt-space-stack-2xl | semantic | var(--dt-dim-16) |
--dt-space-stack-2xs | semantic | var(--dt-dim-1) |
--dt-space-stack-lg | semantic | var(--dt-dim-6) |
--dt-space-stack-md | semantic | var(--dt-dim-4) |
--dt-space-stack-sm | semantic | var(--dt-dim-3) |
--dt-space-stack-xl | semantic | var(--dt-dim-10) |
--dt-space-stack-xs | semantic | var(--dt-dim-2) |
Source
React only, no dependencies, every value a token.
import React from "react";
const SIZES = { "2xs": "var(--dt-space-stack-2xs)", xs: "var(--dt-space-stack-xs)", sm: "var(--dt-space-stack-sm)", md: "var(--dt-space-stack-md)", lg: "var(--dt-space-stack-lg)", xl: "var(--dt-space-stack-xl)", "2xl": "var(--dt-space-stack-2xl)" };
export function Spacer({ size, axis = "vertical", style, ...rest }) {
if (size === undefined) {
return <div aria-hidden="true" style={{ flex: 1, ...style }} {...rest} />;
}
const value = SIZES[size] || SIZES.md;
return <div aria-hidden="true" style={{ flex: "none", width: axis === "horizontal" ? value : undefined, height: axis === "vertical" ? value : undefined, ...style }} {...rest} />;
}
In context
Spacer also appears on the primitives reference cards, alongside the rest of its family.