Responsive Styles
Chakra UI supports responsive styles out of the box. Instead of manually adding
@media
queries and adding nested styles throughout your code, Chakra UI allows
you to provide object and array values to add mobile-first responsive styles.
We use the
@media(min-width)
media query to ensure your interfaces are mobile-first.
Responsive syntax relies on the breakpoints defined in the theme object. Chakra UI provides default breakpoints, here's what it looks like:
const breakpoints = {sm: '30em',md: '48em',lg: '62em',xl: '80em','2xl': '96em',}
To make styles responsive, you can use either the array or object syntax.
The Array syntax#
All style props accept arrays as values for mobile-first responsive styles. This is the recommended method.
Let's say you have a Box
with the following properties:
<Box bg='red.200' w='400px'>This is a box</Box>
To make the width
or w
responsive using the array syntax, here's what you
need to do:
<Box bg='red.200' w={[300, 400, 500]}>This is a box</Box>
To interpret array responsive values, Chakra UI converts the values defined in
theme.breakpoints
and sorts them in ascending order. Afterward, we map the
values defined in the array to the breakpoints
// These are the default breakpointsconst breakpoints = {sm: '30em',md: '48em',lg: '62em',xl: '80em','2xl': '96em',}// Internally, we transform to thisconst breakpoints = ['0em', '30em', '48em', '62em', '80em', '96em']
Here's how to interpret this syntax:
300px
: From0em
upwards400px
: From30em
upwards500px
: From48em
upwards
To skip certain breakpoints, you can pass
null
to any position in the array to avoid generating unnecessary CSS.
The Object syntax#
You can also define responsive values with breakpoint aliases in an object. Any undefined alias key will define the base, non-responsive value.
Let's say you have a Text
that looks like this:
<Text fontSize='40px'>This is a text</Text>
To make the fontSize
responsive using the object syntax, here's what you need
to do:
<Text fontSize={{ base: '24px', md: '40px', lg: '56px' }}>This is responsive text</Text>
Remember, Chakra UI uses the min-width media query for responsive design. The breakpoints are:
sm = 30em
,md = 48em
,lg = 62em
,xl = 80em
Here's how to interpret this syntax:
base
: From0em
upwardsmd
: From48em
upwardslg
: From62em
upwards
More Examples#
This works for every style prop in the theme specification, which means you can change the style of most properties at a given breakpoint.
<><Boxheight={{base: '100%', // 0-48emmd: '50%', // 48em-80em,xl: '25%', // 80em+}}bg='teal.400'width={['100%', // 0-30em'50%', // 30em-48em'25%', // 48em-62em'15%', // 62em+]}/>{/* responsive font size */}<Box fontSize={['sm', 'md', 'lg', 'xl']}>Font Size</Box>{/* responsive margin */}<Box mt={[2, 4, 6, 8]} width='full' height='24px' bg='tomato' />{/* responsive padding */}<Box bg='papayawhip' p={[2, 4, 6, 8]}>Padding</Box></>
Under the hood#
This shortcut is an alternative to writing media queries out by hand. Given the following:
<Box width={[1, 1 / 2, 1 / 4]} />
It'll generate a CSS that looks like this
.Box {width: 100%;}@media screen and (min-width: 30em) {.Box {width: 50%;}}@media screen and (min-width: 48em) {.Box {width: 25%;}}
The equivalent of this style if you passed it as an object.
Customizing Breakpoints#
In some scenarios, you might need to define custom breakpoints for your
application. We recommended using common aliases like sm
, md
, lg
, and
xl
.
To define custom breakpoints, just pass them as an object into the theme.
Note: Ensure the css unit of your breakpoints are the same. Use all
px
or allem
, don't mix them.
// 1. Import the utilitiesimport { extendTheme } from '@chakra-ui/react'// 2. Update the breakpoints as key-value pairsconst breakpoints = {sm: '320px',md: '768px',lg: '960px',xl: '1200px','2xl': '1536px',}// 3. Extend the themeconst theme = extendTheme({ breakpoints })// 4. Now you can use the custom breakpointsfunction Example() {return <Box width={{ base: '100%', sm: '50%', md: '25%' }} />}
Note: If you're using pixels as breakpoint values make sure to always provide a value for the
2xl
breakpoint, which by its default pixels value is "1536px".
Demo#
Here's a simple example of a marketing page component that uses a stacked layout on small screens, and a side-by-side layout on larger screens (resize your browser to see it in action):
<Box p={4} display={{ md: 'flex' }}><Box flexShrink={0}><ImageborderRadius='lg'width={{ md: 40 }}src='https://bit.ly/2jYM25F'alt='Woman paying for a purchase'/></Box><Box mt={{ base: 4, md: 0 }} ml={{ md: 6 }}><TextfontWeight='bold'textTransform='uppercase'fontSize='sm'letterSpacing='wide'color='teal.600'>Marketing</Text><Linkmt={1}display='block'fontSize='lg'lineHeight='normal'fontWeight='semibold'href='#'>Finding customers for your new business</Link><Text mt={2} color='gray.500'>Getting a new business off the ground is a lot of hard work. Here are fiveideas you can use to find your first customers.</Text></Box></Box>