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.
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.
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.
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.
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.
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)" }}
/>
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 in 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.
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.