Skip to content

Surface

When to use it

Surface creates a passive, elevated area for related content. It owns the background, corner radius, shadow and the relationship between its regions. It does not make the whole area clickable and it does not prescribe the layout or typography inside the regions. A Surface stretches across the available width when it is placed directly in a column Flex.

Use Flex and utility classes inside a Surface when the contents need alignment, wrapping, spacing or a particular text size. Use Card or Tile when the component itself is an interactive card or list item.

The default layout places __head and __body side by side when the Surface has room. At narrower container widths, they stack. The breakpoint responds to the Surface width, not the viewport width. Add c-surface--vertical when the regions should always stack. __foot, when present, always follows the layout on its own row.

Variants

Use .c-surface--vertical for an always-stacked head and body. Use .c-surface--flat when the surface should have no shadow, or .c-surface--outlined when it needs a visible outline.

INFO

Surface needs its layout wrapper (c-surface__layout) to handle padding and gaps between head and body correctly. You can easily customize this gap by applying a Gap utility class (u-gap--*) directly to the Surface element. For example c-surface u-gap--xxl sets a larger gap between the head and body regions (default is --l).

TIP

Need more overrides? If you're using custom CSS in your app, you can set --surface-gap, --surface-color, --surface-radius or --surface-padding to adjust more of its appearance. Use Flex and utilities to control the layout of nested content.

What it looks like

Code examples

html
<article class="c-surface">
    <div class="c-surface__layout">
        <div class="c-surface__head">
            <div class="o-flex o-flex--column u-gap--xs">
                <span class="c-label">Settlement status</span>
                <h2 class="u-margin-bottom--none u-font--large">Summer Stage Festival</h2>
                <p class="u-margin-bottom--none u-font--smaller">Payout is scheduled after the final sales report has been approved.</p>
            </div>
        </div>
        <div class="c-surface__body">
            <div class="o-flex o-flex--start u-gap--l">
                <div class="o-flex o-flex--column u-gap--none">
                    <span class="c-label">Net sales</span>
                    <strong class="u-font--large">SEK 184,250</strong>
                </div>
                <div class="o-flex o-flex--column u-gap--xs">
                    <span class="c-label">Status</span>
                    <span class="c-pill">Awaiting approval</span>
                </div>
            </div>
        </div>
    </div>
    <footer class="c-surface__foot">
        <div class="o-flex o-flex--justify">
            <span class="u-font--smaller">Updated 12 minutes ago</span>
            <button class="c-button c-button--small" type="button">Review report</button>
        </div>
    </footer>
</article>
html
<article class="c-surface c-surface--vertical">
    <div class="c-surface__layout">
        <div class="c-surface__head">
            <div class="o-flex o-flex--justify">
                <div>
                    <span class="c-label">Event capacity</span>
                    <h2 class="u-font--large u-margin-bottom--none">Friday, 18 October · Main Hall</h2>
                </div>
                <span class="c-pill">On sale</span>
            </div>
        </div>
        <div class="c-surface__body">
            <div class="o-flex o-flex--justify u-gap--l">
                <div class="o-flex o-flex--column u-gap--none">
                    <span class="c-label">Available</span>
                    <strong class="u-font--large">236</strong>
                </div>
                <div class="o-flex o-flex--column u-gap--none">
                    <span class="c-label">Reserved</span>
                    <strong class="u-font--large">48</strong>
                </div>
                <div class="o-flex o-flex--column u-gap--none">
                    <span class="c-label">Sold</span>
                    <strong class="u-font--large">1,116</strong>
                </div>
            </div>
        </div>
    </div>
    <footer class="c-surface__foot">
        <div class="o-flex o-flex--justify">
            <span class="u-font--smaller">Last order received at 14:32</span>
            <button class="c-button c-button--small" type="button">Manage capacity</button>
        </div>
    </footer>
</article>
html
<aside class="c-surface c-surface--flat c-surface--outlined">
    <div class="c-surface__layout">
        <div class="c-surface__head">
            <div class="o-flex o-flex--column u-gap--xs">
                <span class="c-label">Import completed</span>
                <h2 class="u-margin-bottom--none u-font--medium">Audience list: Gothenburg members</h2>
            </div>
        </div>
        <div class="c-surface__body">
            <div class="o-flex">
                <strong class="u-font--larger">8,492</strong>
                <span class="u-font--smaller u-margin-top--small">contacts ready to use</span>
            </div>
        </div>
    </div>
</aside>

Accessibility notes

Surface has no implicit landmark or interactive semantics. Choose an element that matches the content, such as <article> for a self-contained item, <section> for a named group or <aside> for supporting information. Keep interactive controls inside their relevant region and give icon-only controls an accessible name.