Styling contract
Headless empty exposes only slot hooks. All visual hierarchy, spacing, and action styling are owned by your CSS.
Slot hooks
Target the root and parts directly through their public data-slot values. There are no hidden wrapper classes in the primitive.
Slot selectors
css
[data-slot="empty"] {
display: grid;
gap: 0.75rem;
}
[data-slot="empty-icon"] {
font-size: 2rem;
line-height: 1;
}
[data-slot="empty-actions"] {
display: flex;
flex-wrap: wrap;
gap: 0.65rem;
}
CSS starter
A practical empty-state baseline usually means styling the root as a centered stack, then adding a text scale for title and description.
Starter empty CSS
css
.empty-state {
border: 1px dashed var(--tng-semantic-border-strong);
border-radius: 1rem;
justify-items: center;
padding: 1.5rem;
text-align: center;
}
.empty-state [data-slot="empty-title"] {
font-size: 1.05rem;
font-weight: 600;
margin: 0;
}
.empty-state [data-slot="empty-description"] {
color: var(--tng-semantic-foreground-muted);
line-height: 1.5;
margin: 0;
max-width: 32rem;
}
Owner guidance
- Keep the visual emphasis on the title and use the description to explain the recovery path.
- Use actions sparingly. One primary next step is usually better than a crowded empty state.
- When the empty state belongs inside a panel, style the surrounding surface yourself rather than relying on a default shell.
- Use the wrapper or ownable install when you want the default dashed surface and part templates out of the box.