Breakpoints

Devup UI uses a mobile-first responsive design system with 6 breakpoints. Use arrays to apply different styles at different viewport widths.

Breakpoint Ranges

IndexBreakpointRangeDevice
0xs0px - 479pxMobile (portrait)
1sm480px - 767pxMobile (landscape)
2md768px - 991pxTablet
3lg992px - 1279pxSmall desktop
4xl1280px - 1599pxDesktop
52xl1600px+Large desktop

Basic Usage

Pass an array to any style prop. Each index corresponds to a breakpoint:

1<Box bg={['red', 'blue', 'green', 'yellow', 'purple', 'orange']} />
1<Box bg={['red', 'blue', 'green', 'yellow', 'purple', 'orange']} />

This results in:

  • 0-479px: red background
  • 480-767px: blue background
  • 768-991px: green background
  • 992-1279px: yellow background
  • 1280-1599px: purple background
  • 1600px+: orange background

Using null to Skip Breakpoints

Use null to skip a breakpoint and keep the previous value:

1<Box bg={['red', null, 'green', null, 'purple']} />
1<Box bg={['red', null, 'green', null, 'purple']} />

This results in:

  • 0-767px: red (index 0, then null inherits)
  • 768-1279px: green (index 2, then null inherits)
  • 1280px+: purple

Shorter Arrays

Arrays shorter than 6 elements apply styles up to their length:

1// Only define mobile and desktop
2const example = <Box fontSize={['14px', null, null, null, '18px']} />
3
4// Shorthand: mobile and tablet only
5const example2 = <Box p={[2, 4]} />
1// Only define mobile and desktop
2const example = <Box fontSize={['14px', null, null, null, '18px']} />
3
4// Shorthand: mobile and tablet only
5const example2 = <Box p={[2, 4]} />

Responsive Layout Example

1<Flex direction={['column', null, 'row']} gap={[2, null, 4]}>
2  <Box p={[2, null, 4]} w={['100%', null, '50%']}>
3    Left content
4  </Box>
5  <Box p={[2, null, 4]} w={['100%', null, '50%']}>
6    Right content
7  </Box>
8</Flex>
1<Flex direction={['column', null, 'row']} gap={[2, null, 4]}>
2  <Box p={[2, null, 4]} w={['100%', null, '50%']}>
3    Left content
4  </Box>
5  <Box p={[2, null, 4]} w={['100%', null, '50%']}>
6    Right content
7  </Box>
8</Flex>
  • Mobile (0-767px): Stacked vertically, full width, small padding/gap
  • Tablet+ (768px+): Side by side, 50% width each, larger padding/gap

Responsive Typography

Combine with typography for responsive text:

1<Text
2  fontSize={['24px', null, null, null, '48px']}
3  lineHeight={[1.3, null, null, null, 1.2]}
4>
5  Responsive Heading
6</Text>
1<Text
2  fontSize={['24px', null, null, null, '48px']}
3  lineHeight={[1.3, null, null, null, 1.2]}
4>
5  Responsive Heading
6</Text>

Or use responsive typography from devup.json:

1{
2  "theme": {
3    "typography": {
4      "h1": [
5        { "fontSize": "32px", "fontWeight": 800 },
6        null,
7        null,
8        null,
9        { "fontSize": "48px", "fontWeight": 800 }
10      ]
11    }
12  }
13}
1{
2  "theme": {
3    "typography": {
4      "h1": [
5        { "fontSize": "32px", "fontWeight": 800 },
6        null,
7        null,
8        null,
9        { "fontSize": "48px", "fontWeight": 800 }
10      ]
11    }
12  }
13}
1<Text typography="$h1">Responsive Heading</Text>
1<Text typography="$h1">Responsive Heading</Text>

Responsive with Pseudo Selectors

Combine responsive arrays with pseudo selectors:

1// Different hover colors per breakpoint
2const example = <Box _hover={{ bg: ['blue', null, 'purple'] }} />
3
4// Alternative syntax
5const example2 = <Box _hover={[{ bg: 'blue' }, null, { bg: 'purple' }]} />
1// Different hover colors per breakpoint
2const example = <Box _hover={{ bg: ['blue', null, 'purple'] }} />
3
4// Alternative syntax
5const example2 = <Box _hover={[{ bg: 'blue' }, null, { bg: 'purple' }]} />

Common Patterns

Show/Hide Elements

1// Hide on mobile, show on desktop
2const example = (
3  <Box display={['none', null, null, null, 'block']}>Desktop only content</Box>
4)
5
6// Show on mobile, hide on desktop
7const example2 = (
8  <Box display={['block', null, null, null, 'none']}>Mobile only content</Box>
9)
1// Hide on mobile, show on desktop
2const example = (
3  <Box display={['none', null, null, null, 'block']}>Desktop only content</Box>
4)
5
6// Show on mobile, hide on desktop
7const example2 = (
8  <Box display={['block', null, null, null, 'none']}>Mobile only content</Box>
9)

Responsive Grid

1<Grid
2  gap={[2, null, 4]}
3  templateColumns={['1fr', null, 'repeat(2, 1fr)', null, 'repeat(4, 1fr)']}
4>
5  <Box>Item 1</Box>
6  <Box>Item 2</Box>
7  <Box>Item 3</Box>
8  <Box>Item 4</Box>
9</Grid>
1<Grid
2  gap={[2, null, 4]}
3  templateColumns={['1fr', null, 'repeat(2, 1fr)', null, 'repeat(4, 1fr)']}
4>
5  <Box>Item 1</Box>
6  <Box>Item 2</Box>
7  <Box>Item 3</Box>
8  <Box>Item 4</Box>
9</Grid>
  • Mobile: 1 column
  • Tablet: 2 columns
  • Desktop: 4 columns

Responsive Spacing

1<Box m={[2, null, 4]} p={[2, null, 4, null, 6]}>
2  Content with responsive padding and margin
3</Box>
1<Box m={[2, null, 4]} p={[2, null, 4, null, 6]}>
2  Content with responsive padding and margin
3</Box>

Remember: numeric values are multiplied by 4. So p={[2, null, 4]} becomes padding: 8px on mobile and padding: 16px on tablet+.

Best Practices

  1. Mobile-first: Start with mobile styles at index 0
  2. Use null wisely: Skip breakpoints that don't need changes
  3. Keep it simple: Not every prop needs 6 values
  4. Test thoroughly: Check all breakpoints during development
  5. Consider performance: Responsive values generate more CSS - use judiciously