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
Polaris web components
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>
);
}Polaris React
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
Anchor to Updated propertiesUpdated properties
The following properties are different in the Polaris box component.
Anchor to backgroundbackground
The background values now describe surface emphasis rather than exposing every Polaris React color token.
| Polaris React value | Polaris 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 React | Polaris 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.
Anchor to border radiusborder radius
Replace the old radius scale with the Polaris web component scale.
| Polaris React value | Polaris 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".
Anchor to paddingpadding
Keep padding, paddingBlock, paddingBlockStart, paddingBlockEnd, paddingInline, paddingInlineStart, and paddingInlineEnd, but replace old numeric spacing tokens.
| Polaris React value | Polaris 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.
Anchor to SizingSizing
Rename physical size properties to flow-relative properties.
| Polaris React | Polaris web components |
|---|---|
width | inlineSize |
minWidth | minInlineSize |
maxWidth | maxInlineSize |
minHeight | minBlockSize |
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.
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 React | Polaris web components |
|---|---|
role="status" | accessibilityRole="status" |
role="presentation" | accessibilityRole="presentation" |
aria-label="…" | accessibilityLabel="…" |
aria-hidden={true} | accessibilityVisibility="hidden" |
visuallyHidden | accessibilityVisibility="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.
Anchor to id and childrenid and children
Keep id when another element or app logic still references it. Move children into the default slot and migrate each nested Polaris React component.
Anchor to Removed propertiesRemoved properties
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.
Anchor to colorcolor
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.
Anchor to shadowshadow
s-box doesn't expose shadows. Use the surface hierarchy provided by sections, modals, popovers, and other components instead of rebuilding elevation.
Anchor to tabIndextab Index
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 z Index
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.
Anchor to opacityopacity
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.
Anchor to outline propertiesoutline properties
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.
Anchor to New propertiesNew properties
The Polaris box component introduces the following useful properties:
| Property | Description |
|---|---|
blockSize and maxBlockSize | Add flow-relative height and maximum-height constraints. |
accessibilityVisibility | Controls visible, assistive-technology-hidden, or screen-reader-only content. |
display | Shows or removes the box with "auto" or "none" and accepts responsive values. |
border | Combines supported width, color, and style tokens in one value. |
Anchor to Test the migrationTest the migration
- 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
Boximport after their final consumers are migrated.