Finally Making Sense of Responsive Screens (ReactJS/NextJS + Chakra UI)

How I made my website responsive without learning about CSS.

Irtiza Hafiz
Level Up Coding

--

I made the mistake of asking my UX Designer to only design the desktop version of my newly revamped website. Not the mobile version.

She did a tremendous job. I was thoroughly impressed with her design (if you are looking for a UX designer, please check out her Instagram)

It took me 3 days to build the desktop version. It looked great! Without any thought, I shared the link with my friends and family.

And that’s when I realized…the website looked horrendous on mobile.

Hence, began my arduous journey to make my website (built with ChakraUI) responsive. Or that’s what I thought until I realized how seamless it is to make websites and apps responsive in ChakraUI.

In this blog post, I will show you how you can make everything responsive using ChakraUI.

Here’s a quick lookahead:

- What do I mean by Responsive Screens?
- Breakpoints
- ChakraUI Array Syntax
- ChakraUI Object Syntax
- Padding
- Font Sizes
- Grids
- Stacks
- Hiding Components based on screen size

Let’s get started.

Responsive Screens

Before I explain what I mean by responsive screens, let me show you how my website looks on the desktop.

The larger screen real estate that desktops and laptops give me, allows me to do the following:

  • Put my headline and avatar side-by-side
  • Show all my blogs in a 3-column grid layout
  • Show my popular blog posts beside all my other blog posts

Looking at my “credit cards” page, you will see a similar pattern.

Once again, with so much screen space, I can use a 3-column grid to show all my credit cards.

Now, think about the limitations that a small mobile phone screen would impose on me. Even displays from “bigger” phones, such as the iPhone 14 Pro Max, pale in comparison to laptops and monitors.

Just a couple of limitations off the top of my head:

  • Everything needs to stack vertically; almost no side-by-side components possible.
  • Grids with multiple columns need to collapse down to a single column
  • Margins and paddings will have to be limited given the lack of screen space
  • Anything that stacks horizontally will need to stack vertically
  • Font sizes need to scale with screen size

To my surprise, I was able to achieve all the above (and more), after reading through ChakraUI’s documentation for 15 minutes only.

I will give you a few of the highlights with examples in this blog post. However, if you are serious about learning how to make responsive apps and websites using ChakraUI, I would strongly recommend reading the official docs.

Fundamental Concept — Breakpoint

Without going too deep into technical jargon, I will define breakpoint as:

Screen size thresholds where you can trigger style changes.

In ChakraUI, breakpoints are defined as follows:

const breakpoints = {
base: '0em', // 0px
sm: '30em', // ~480px
md: '48em', // ~768px
lg: '62em', // ~992px
xl: '80em', // ~1280px
'2xl': '96em', // ~1536px
}

One way to look at this from a more functional point of view:

  • base/sm — mobile screens
  • md — tablet screens
  • lg — laptop/monitor screens
  • xl / 2xl — TV screens

Don’t worry, you don’t have to define styles at every screen threshold.

Instead, you can just define one for mobile and one for larger screens. It will become clearer with the examples below.

Before we get into examples, however, let’s see how we can style the same component differently based on screen sizes using the above breakpoints.

2 Syntaxes — Arrays & Objects

Here’s a simple Box component using ChakraUI. By default, its width is set to 400px.

<Box bg='red.200' w='400px'>
This is a box
</Box>

Let’s say we want to make the width property dynamic based on the user’s screen size. Here’s how you do it.

<Box bg='red.200' w={[300, 400, 500]}>
This is a box
</Box>

Focus on the array: w={[300, 400, 500]}.

Here’s one way of reading it: (refer to the Breakpoint section above)

  • 300px: From 0px (base) upwards
  • 400px: From 480px (sm) upwards
  • 500px: From 768px (md) upwards

In more concrete terms, you can interpret in terms of “category of devices”:

  • Box width 300px — Mobile phones
  • Box width 400px — Tablets
  • Box width 500px — Laptops and larger screens

If you don’t want to get into the trouble of defining arrays, you can use ChakraUI’s object syntax to achieve the same thing:

<Box bg='red.200' width={{ base: '300px', sm: '400px', md: '500px' }}>
This is a box
</Box>

Whichever syntax you choose, you essentially define your style for 3 different breakpoints.

Padding & Font Sizes

Two of the most common cases of responsive styles are:

  • Less padding in mobile devices compared to other screens
  • Smaller font sizes in mobile devices compared to other screens

When it comes to font sizes of my Heading component, I did the following:

<Heading color="#75c682" fontSize={["4xl", "5xl", "7xl"]}>
Hi! I am Irtiza.
</Heading>

So, following the logic in the previous section:

  • On mobile phones — font size is set to 4xl
  • On tablets and smaller laptops — font size is set to 5xl
  • On regular laptops and monitors — font size is set to 7xl

That means the font size of my heading increases with screen size.

I did a very similar thing for padding:

<VStack padding={[5, 8]} borderRadius={[28, 16]}/>

Here, I only care about “mobile” and “not mobile”. That’s why I define a pair of styles for each padding and border radius.

Stacks & Grids

It gets more interesting when you apply the same concept to Stacks and Grids.

Let’s look at Stacks first.

My website banner contains 2 separate components:

  • Text components for “Hi! I am Irtiza” and “An Engineering Manager by day, and a Blogger and YouTuber by night.”
  • Avatar or Image component

On mobile devices, I want them to vertically stack, while on larger screens I want them to stack horizontally.

Here’s how I achieved that.

<Stack direction={["column", "row"]}>
<VStack>
<Heading color="#75c682" fontSize={["4xl", "5xl", "7xl"]}>
Hi! I am Irtiza.
</Heading>
<Heading color="#efe073" fontSize={["xl", "3xl", "4xl"]}>
An Engineering Manager by day, and a Blogger and YouTuber…
</Heading>
</VStack>
<Image
src="/irtiza-avatar-ayesha.png"
alt="Irtiza Hafiz's avatar"
width={600}
height={400}
></Image>
</Stack>

Focus on: direction={[“column”, “row”]} on the Stack component. On smaller screens, the direction is column while on larger screens it is row.

This results in:

Similarly, for Grids I can achieve the following with only a few lines of code:

  • On Mobile Screens: 1-column
  • On Larger Screens: 3-columns
<Grid
gap={5}
templateColumns={{ base: "repeat(1, 1fr)", lg: "repeat(3, 1fr)" }}
/>

Hiding Components Based on Screen Sizes

I will wrap up the blog post by talking about something a little more complex — hiding UI elements based on screen sizes.

I want you to compare the two images side-by-side below.

If you haven’t noticed it already, here are the differences:

  • On larger screens: I show categories and popular content
  • On mobile screens: I show a 1-column grid of all blog posts, without both categories and popular content

So, based on screen size, I am hiding certain UI elements.

How am I doing that?

Here’s my Category component that holds the pills you see above on the larger screen:

export default function Categories({ categoryCounts }) {
return (
<HStack spacing={12} display={["none", "flex"]}>
//…more components
</HStack>
);
}

With display={[“none”, “flex”]}I am hiding the component for mobile screens while showing it for larger screens.

Such is the power of ChakraUI’s syntactical sugar. With a few lines, you can do very powerful things.

Closing Thoughts

I hope I have succeeded in showing you how you can easily design your website or web app for both smaller (mobile) and larger (laptop or monitor) screens.

If you have made it this far, I hope you found this valuable.

Feel free to follow me on Medium, subscribe to my website, or follow me on YouTube.

--

--