Finally Making Sense of Responsive Screens

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 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.

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.

Irtiza Hafiz

;