Skip to main content

Migrate Box from Polaris React

The Polaris box component is a generic container for spacing, sizing, backgrounds, borders, and accessibility. It replaces the Polaris React Box component from @shopify/polaris and is available as <s-box>.

Use s-box only when the container owns a visual or accessibility boundary. Prefer s-section, s-banner, s-stack, s-grid, and interactive components when they describe the content or behavior more precisely.

Migrating Box to s-box

export function InventorySummary() {
return (
<s-box
background="subdued"
border="base base solid"
borderRadius="large"
padding="base"
>
<s-stack gap="small-200">
<s-heading>Inventory</s-heading>
<s-text>18 units available at three locations.</s-text>
</s-stack>
</s-box>
);
}
import {BlockStack, Box, Text} from '@shopify/polaris';

export function InventorySummary() {
return (
<Box
background="bg-surface-secondary"
borderColor="border"
borderStyle="solid"
borderWidth="025"
borderRadius="300"
padding="400"
>
<BlockStack gap="200">
<Text as="h2" variant="headingSm">Inventory</Text>
<Text as="p">18 units available at three locations.</Text>
</BlockStack>
</Box>
);
}

Preview


The following properties are different in the Polaris box component.

The background values now describe surface emphasis rather than exposing every Polaris React color token.

Polaris React valuePolaris web components
"bg-surface-transparent""transparent" or omitted
"bg-surface""base"
"bg-surface-secondary""subdued"
"bg-surface-tertiary""strong"

Other fill, interaction-state, inverse, and semantic color tokens don't have direct values. Use a semantic component such as s-banner for success, warning, or critical content. Don't freeze hover, active, selected, or disabled colors onto a static box.

Anchor to border color, style, and widthborder color, style, and width

You can keep separate border properties or combine them with the border shorthand in the order width color style.

Polaris ReactPolaris web components
borderColor="border-secondary"borderColor="subdued"
borderColor="border"borderColor="base"
borderColor="border-tertiary"borderColor="strong"
borderStyle="solid"borderStyle="solid"
borderStyle="dashed"borderStyle="dashed"
borderWidth="0"borderWidth="none"
borderWidth="0165"borderWidth="small"
borderWidth="025"borderWidth="base"
borderWidth="050"borderWidth="large"

The old borderWidth="100" and semantic border colors such as border-critical don't have direct box values. Use the nearest supported width only when the boundary remains necessary, and use a semantic component when the color communicated status.

borderColor="transparent" also has no direct value. Remove the border when it isn't visible. If a transparent border reserved layout space for an interaction state, migrate the complete interaction to a component that owns its states.

Anchor to Per-edge border widthsPer-edge border widths

Replace borderBlockStartWidth, borderInlineEndWidth, borderBlockEndWidth, and borderInlineStartWidth with the one-to-four-value borderWidth shorthand. Four values apply in that order.

For example, replace borderBlockStartWidth="025" with borderWidth="base none none none". Replace each old token using the width table above, and test inline start and end in right-to-left languages.

Replace the old radius scale with the Polaris web component scale.

Polaris React valuePolaris web components
"0""none"
"100""small-200"
"150""small-100"
"200""base"
"300""large"
"400""large-200"

The old "050", "500", "750", and "full" values don't have exact equivalents. Choose the nearest supported radius from the containing surface. Don't use s-box to recreate a pill control; use the appropriate button, chip, badge, or field component.

Replace borderStartStartRadius, borderStartEndRadius, borderEndEndRadius, and borderEndStartRadius with the one-to-four-value borderRadius shorthand. Four values follow that corner order. For example, top-only rounding becomes borderRadius="large large none none".

Keep padding, paddingBlock, paddingBlockStart, paddingBlockEnd, paddingInline, paddingInlineStart, and paddingInlineEnd, but replace old numeric spacing tokens.

Polaris React valuePolaris web components
"0""none"
"050""small-500"
"100""small-400"
"150""small-300"
"200""small-200"
"300""small-100"
"400""base"
"500""large"
"600""large-200"
"800""large-300"
"1000""large-400"
"1200""large-500"

The old "025", "250", "700", and values larger than "1200" don't have exact equivalents. Re-evaluate the content relationship instead of adding arbitrary large padding.

Replace {xs, sm, md, lg, xl} objects with responsive value strings. padding also supports one-to-four space-separated flow-relative values.

Rename physical size properties to flow-relative properties.

Polaris ReactPolaris web components
widthinlineSize
minWidthminInlineSize
maxWidthmaxInlineSize
minHeightminBlockSize

The new size properties accept pixel values, percentages, or "0". inlineSize and blockSize also accept "auto"; maximum sizes accept "none". Rework old calc(), viewport-unit, keyword, and other arbitrary CSS values instead of passing them through.

Anchor to overflowX and overflowYoverflowX and overflowY

Replace matching overflowX="hidden" and overflowY="hidden" values with overflow="hidden". The new property applies to both axes and also accepts "visible".

There is no axis-specific, scroll, or clip equivalent. Use components that own overflow, such as modal content or responsive tables, instead of creating a generic scroll region without its keyboard and focus behavior.

Anchor to role and accessibilityrole and accessibility

Rename supported semantics and visibility properties:

Polaris ReactPolaris web components
role="status"accessibilityRole="status"
role="presentation"accessibilityRole="presentation"
aria-label="…"accessibilityLabel="…"
aria-hidden={true}accessibilityVisibility="hidden"
visuallyHiddenaccessibilityVisibility="exclusive"

The old menu, listbox, combobox, and group roles aren't available on s-box. Migrate those complete interactions to the corresponding web component or a labeled semantic region.

Keep id when another element or app logic still references it. Move children into the default slot and migrate each nested Polaris React component.


s-box doesn't accept as. Use s-box for a generic container, s-text for inline text, s-section for a labeled section, s-unordered-list and s-list-item for lists, and the owning field component for legend or choice-group semantics.

s-box doesn't set a text color on all descendants. Move color to the text or icon that owns it, using its documented tone or color. Prefer semantic tone over a copied Polaris React color token.

s-box doesn't expose shadows. Use the surface hierarchy provided by sections, modals, popovers, and other components instead of rebuilding elevation.

s-box isn't a generic focus target. Use s-button, s-link, s-clickable, or the relevant field for interactive content. Move programmatic focus to a meaningful heading, field, or control supported by the workflow.

Anchor to position, inset properties, and zIndexposition, inset properties, and zIndex

Remove position, insetBlockStart, insetBlockEnd, insetInlineStart, insetInlineEnd, and zIndex. Rebuild columns and alignment with s-grid or s-stack, and use s-modal, s-popover, s-menu, or s-tooltip for layered content.

s-box doesn't support opacity. Use disabled, loading, hidden, or display="none" on the component that owns that state. Don't reduce opacity as the only indication of status.

Remove outlineColor, outlineStyle, and outlineWidth. Focus indicators belong to interactive web components. For a non-interactive boundary, use the supported border properties.

There is no print-only visibility property. Remove print-specific UI when it isn't essential, or keep print behavior in the app's existing stylesheet until that content can be restructured. display="none" isn't a print-only replacement; it hides content for everyone.


The Polaris box component introduces the following useful properties:

PropertyDescription
blockSize and maxBlockSizeAdd flow-relative height and maximum-height constraints.
accessibilityVisibilityControls visible, assistive-technology-hidden, or screen-reader-only content.
displayShows or removes the box with "auto" or "none" and accepts responsive values.
borderCombines supported width, color, and style tokens in one value.

  • Verify padding, borders, backgrounds, and size constraints at every responsive iframe width.
  • Test inline start and end behavior in both left-to-right and right-to-left languages.
  • Confirm hidden, screen-reader-only, status, and presentation semantics with a screen reader.
  • Check that removed positioning and overflow don't create clipping, horizontal scrolling, or unreachable controls.
  • Verify interactive call sites now use a component with keyboard behavior and a visible focus indicator.
  • Remove old token helpers, layout CSS, and the Polaris React Box import after their final consumers are migrated.


Was this page helpful?