Simplifying Responsive Styles in Chakra UI with useBreakpointValue
Learn how Chakra UI’s useBreakpointValue hook replaces verbose media queries with a declarative, type‑safe API for responsive styling.
22 Dec 2025, 23:20 UTC

Problem: Repetitive media queries clutter component JSX
When building responsive layouts with Chakra UI, developers often write inline objects or separate style blocks for each breakpoint. This leads to duplicated logic, harder‑to‑read JSX, and a higher chance of inconsistency when a design token changes.
Thesis: useBreakpointValue centralizes responsive mapping
Chakra UI’s useBreakpointValue hook lets you declare a value for each breakpoint in a single call. The hook returns the value that matches the current viewport width, keeping the responsive logic out of the render tree and making the component props declarative and type‑safe.
How the hook works
The hook accepts either an array ordered by Chakra’s default breakpoint names (['xs', 'sm', 'md', 'lg', 'xl', '2xl']) or an object where keys are those names. It reads the theme’s breakpoint values and returns the entry that corresponds to the current width. If no match is found, it returns the first value (xs) – a useful fallback during server‑side rendering.
Worked example: a responsive Card
Below is a Card component whose padding, font size, and maxWidth change at sm, md, and lg breakpoints. The example uses Chakra UI v2.6.
import { Box, Text, useBreakpointValue } from '@chakra-ui/react';
function ResponsiveCard() {
// padding: xs -> 2, sm -> 4, md -> 6, lg -> 8
const padding = useBreakpointValue([2, 4, 6, 8]);
// fontSize: xs -> 'sm', sm -> 'md', md -> 'lg', lg -> 'xl'
const fontSize = useBreakpointValue({
xs: 'sm',
sm: 'md',
md: 'lg',
lg: 'xl',
});
// maxWidth: xs -> '100%', sm -> '600px', md -> '800px', lg -> '960px'
const maxWidth = useBreakpointValue([
'100%',
'600px',
'800px',
'960px',
]);
return (
This card adapts its padding, text size, and width as the viewport grows.
);
}
// Usage
//
As the browser width crosses each breakpoint, the hook updates the returned values, and the Card’s props change accordingly – no media queries needed in the JSX.
Trade‑off: reliance on default breakpoint names
The hook assumes the theme’s breakpoint keys are exactly xs, sm, md, lg, xl, 2xl. If you customize breakpoints (e.g., add a 3xl or rename sm to small), you must extend the theme and ensure the hook receives the same keys. A mismatch leads to undefined values and unexpected layout shifts.
To mitigate, create a small wrapper that reads the breakpoint names from the theme:
import { useBreakpointValue, useTheme } from '@chakra-ui/react';
function responsive(values) {
const theme = useTheme();
const breakpoints = Object.keys(theme.breakpoints);
// If values is an array, assume it matches breakpoints order
if (Array.isArray(values)) {
const obj = {};
breakpoints.forEach((key, i) => {
obj[key] = values[i];
});
return useBreakpointValue(obj);
}
// If values is already an object, just pass it through
return useBreakpointValue(values);
}
Now you can call responsive([2,4,6,8]) and the wrapper aligns the array with whatever breakpoints the theme defines.
Actionable closing
- Adopt
useBreakpointValue for layout props likep,m,fontSize,maxW, andw. - Wrap the hook in a utility (as shown) if you plan to customize breakpoints.
- Test responsiveness by rendering the component inside
ColorModeProviderand resizing the preview pane; verify that the values change at the expected widths. - When using SSR, be aware that the initial value is the first breakpoint (xs). If this causes a hydration mismatch, consider using
useEffectto set a client‑only placeholder or accept the brief flash.
By moving breakpoint logic into a hook, your JSX stays clean, your design tokens stay centralized, and updating a responsive value requires editing a single line.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.