Version 0.13.2

Box

The lowest-level component in Backstage UI with spacing, sizing, and display props.

Usage#

import { Box } from '@backstage/ui';

<Box p="4" surface="1">
  Content with padding and background
</Box>

API reference#

PropTypeDefaultDescription
as
string
divHTML element to render. Accepts any valid HTML tag (div, span, section, etc.).
surface
0123dangerwarningsuccessauto
-Background surface level for visual hierarchy. Higher numbers create elevation.
children
ReactNode
-Content to render inside the box.
width
string
-Sets the width of the element. Accepts CSS values.
minWidth
string
-Sets the minimum width. Element cannot shrink below this.
maxWidth
string
-Sets the maximum width. Element cannot grow beyond this.
height
string
-Sets the height of the element. Accepts CSS values.
minHeight
string
-Sets the minimum height. Element cannot shrink below this.
maxHeight
string
-Sets the maximum height. Element cannot grow beyond this.
position
staticrelativeabsolutefixedsticky
-CSS positioning scheme for the element.
display
noneflexblockinline
-Controls layout behavior. Use flex for flexbox layouts, none to hide.
className
string
-Additional CSS class name for custom styling.
style
CSSProperties
-Inline CSS styles object.
00.5auto
-Padding and margin properties for controlling spacing around the element.

Examples#

Surface#

Use surface levels to create visual hierarchy.

<Flex direction="column" gap="4">
  <Box p="4" surface="0">Surface 0</Box>
  <Box p="4" surface="1">Surface 1</Box>
  <Box p="4" surface="2">Surface 2</Box>
  <Box p="4" surface="3">Surface 3</Box>
</Flex>
Surface 0
Surface 1
Surface 2
Surface 3

Responsive props#

Props can accept breakpoint objects for responsive behavior.

<Box
  p={{ initial: '2', md: '4' }}
  display={{ initial: 'block', md: 'flex' }}
>
  Content
</Box>
Resize to see change

Theming#

Our theming system is based on a mix between CSS classes, CSS variables and data attributes. If you want to customise this component, you can use one of these class names below.

  • bui-Box

Changelog#

Version 0.13.0#

Breaking Changes

  • Breaking Simplified the neutral background prop API for container components. The explicit neutral-1, neutral-2, neutral-3, and neutral-auto values have been removed from ProviderBg. They are replaced by a single 'neutral' value that always auto-increments from the parent context, making it impossible to skip or pin to an explicit neutral level. #33002

    Migration Guide:

    Replace any explicit bg="neutral-1", bg="neutral-2", bg="neutral-3", or bg="neutral-auto" props with bg="neutral". To achieve a specific neutral level in stories or tests, use nested containers — each additional bg="neutral" wrapper increments by one level.

    // Before
    <Box bg="neutral-2">...</Box>
    
    // After
    <Box bg="neutral">
      <Box bg="neutral">...</Box>
    </Box>
    

Version 0.12.0#

Breaking Changes

  • Breaking Replaced Surface / onSurface system with new provider/consumer background system

    The old Surface type ('0''3', 'auto') and its associated props (surface, onSurface) have been replaced by a provider/consumer bg architecture.

    Types:

    • ContainerBg'neutral-1' | 'neutral-2' | 'neutral-3' | 'danger' | 'warning' | 'success'
    • ProviderBgContainerBg | 'neutral-auto'

    Consumer components (e.g. Button) inherit the parent's bg via data-on-bg, and CSS handles the visual step-up. See "Neutral level capping" below for details on how levels are bounded.

    Hooks:

    • useBgProvider(bg?) — for provider components. Returns { bg: undefined } when no bg is given (transparent). Supports 'neutral-auto' to auto-increment from the parent context.
    • useBgConsumer() — for consumer components. Returns the parent container's bg unchanged.

    Component roles:

    • Provider-only (Box, Flex, Grid): set data-bg, wrap children in BgProvider. Transparent by default — they do not auto-increment; pass bg="neutral-auto" explicitly if you want automatic neutral stepping.
    • Consumer-only (Button, ButtonIcon, ButtonLink): set data-on-bg, inherit the parent container's bg unchanged.
    • Provider + Consumer (Card): sets both data-bg and data-on-bg, wraps children. Card passes bg="neutral-auto" to its inner Box, so it auto-increments from the parent context.

    Neutral level capping:

    Provider components cap at neutral-3. There is no neutral-4 prop value. The neutral-4 level exists only in consumer component CSS — for example, a Button sitting on a neutral-3 surface uses neutral-4 tokens internally via data-on-bg. #32711

    Migration Guide:

    Rename the surface prop to bg on provider components and update values:

    - <Box surface="1">
    + <Box bg="neutral-1">
    
    - <Card surface="2">
    + <Card bg="neutral-2">
    
    - <Flex surface="0">
    + <Flex bg="neutral-1">
    
    - <Grid.Root surface="1">
    + <Grid.Root bg="neutral-1">
    

    Remove onSurface from consumer components — they now always inherit from the parent container:

    - <Button onSurface="1" variant="secondary">
    + <Button variant="secondary">
    
    - <ButtonIcon onSurface="2" variant="secondary" />
    + <ButtonIcon variant="secondary" />
    
    - <ToggleButton onSurface="1">
    + <ToggleButton>
    

    Update type imports:

    - import type { Surface, LeafSurfaceProps, ContainerSurfaceProps } from '@backstage/ui';
    + import type { ContainerBg, ProviderBg } from '@backstage/ui';
    

    Replace hook usage in custom components:

    - import { useSurface, SurfaceProvider } from '@backstage/ui';
    + import { useBgProvider, useBgConsumer, BgProvider } from '@backstage/ui';
    
    - const { surface } = useSurface({ surface: props.surface });
    + const { bg } = useBgProvider(props.bg);
    
    - const { surface } = useSurface({ onSurface: props.onSurface });
    + const { bg } = useBgConsumer();
    

    Update CSS selectors targeting surface data attributes:

    - [data-surface='1'] { ... }
    + [data-bg='neutral-1'] { ... }
    
    - [data-on-surface='1'] { ... }
    + [data-on-bg='neutral-1'] { ... }
    

    Note: Provider components use data-bg (values: neutral-1 through neutral-3, plus intent values). Consumer components use data-on-bg, which reflects the parent container's bg directly. The neutral-4 level never appears as a prop or data-bg value — it is used only in consumer CSS.

Changes

  • Fixed Box component to forward HTML attributes to the underlying div element. #32536

Version 0.11.0#

Changes

  • Fixes app background color on dark mode. #32203