blog post

Building Responsive Design Using em and rem CSS Units


Responsive design ensures that web content looks good and functions well, no matter the screen size. Such design is a must-have in modern web applications.

In today's post we will learn the power of CSS em and rem units to create flexible, responsive web designs. We will dive into the mechanics of these relative units and see their importance in modern responsive web development.

Understanding em and rem CSS Units

em units: are relative to the font-size of their immediate parent element. If a parent element has a font-size of 16px, 1em within a child element would also be 16px. The parent font size is multiplied by the number used with em unit. For example, if parent element has font-size of 16px, 1.5rem of the child will be equal to 24px.

rem (root em) units: are relative to the font-size of the root element (html), which makes them consistent throughout the whole HTML document. If the root font-size is 20px, 1rem would always be 20px, regardless of parents and where it is used in the document. By default, an HTML page has font-size equal to 16px, if other is not specified. The root font size is multiplied by the number used with rem unit. For example, if root element has font-size of 20px, 1.5rem of the child will be equal to 30px.

Both em and rem units offer advantages that make them ideal for responsive design:

  • Scalability: Adjusting the root element's font-size dynamically adjusts all rem-based measurements, making it incredibly efficient to scale an entire website on different screens.
  • Flexibility: em allows for component-specific scaling, which is useful when building modular designs where each component's scaling factor might need to be different.
  • Maintainability: Using relative units means you can change the size of an entire section of your website by changing a single value.

How to Use em and rem CSS Units

Let's explore different use cases where em and rem CSS units are useful.

Building a Fluid Typography System

One of the most common uses of rem is to establish a fluid typography system. By setting the base font-size on the root element, you can control all typography through relative rem units.

html { font-size: 24px; } h1 { font-size: 2rem; /* 48px */ } button { font-size: 1.5rem; /* 36px */ }

Responsive Spacing and Layout

Both em and rem can be used for responsive spacing and layout. em is particularly useful for padding and margins that should scale with the text size within a parent, ensuring that the spacing of elements looks balanced at any text size.

p { /* Margin that scales with the paragraph's font size */ margin-bottom: 1em; } .container { /* Padding that is consistent to the root, regardless of nesting */ padding: 2rem; }

Media Queries

Using em in media queries can help create more naturally scaling breakpoints. Since rem units scale based on the font size of the HTML document, they adjust based on the user's default browser settings, enhancing accessibility.

@media (max-width: 40em) { body { font-size: 1.4rem; } }

In most of use-cases rem units are preferred over em, because they allow to create more predictable and consistent designs as they are based on the base font size.

Comparing rem Units With Viewport CSS Units

Using rem units in CSS is particularly advantageous for maintaining readability and consistent UI component sizes across a wide range of devices, from very small to very large screens. This contrasts with viewport units (vw, vh, vmin, vmax), which, while useful in some contexts, can lead to less predictable and sometimes extreme sizing of text and elements on very large or very small screens. Here's why rem unit is so effective.

Advantages for Text Readability

  • Consistency Across Devices: Since rem sizes are calculated based on the root element, they remain consistent across all elements. This consistency helps in maintaining the same proportions of text, which is critical for readability, especially on very small screens like mobile phones or very large screens like TVs or large monitors.
  • Accessibility: Users often adjust their browser's default font size setting if they have difficulty reading smaller text. Since rem units are based on this setting, increasing the font size in browser settings will proportionally increase the size of all text sized in rem on the website. This is more accessible than viewport units, which do not respond to user font size settings.

Advantages for UI Components

  • Scalable Components: Buttons and other UI components sized with rem units scale based on the root font size. This scaling ensures that components are neither too small to be functional nor too large to fit the screen, maintaining usability across devices.
  • Flexibility and Control: You can adjust the root font size using a single CSS rule in a media query to scale all rem-based sizes up or down based on the screen size. This global adjustability offers much finer control compared to viewport units, which scale based on the size of the viewport and can lead to overly large or small sizes in extreme scenarios.
  • Predictability: Unlike viewport units that can cause extreme variations in element sizing (e.g., a button becoming excessively large on a desktop or too small on a mobile phone), rem units provide a more predictable and harmonious scaling method.

Example of using rem for creating a responsive button:

html { font-size: 20px; } .button { /* 24px on default, scales with root font-size */ font-size: 1.5rem; /* padding scales with the font-size */ width: 20rem; padding: 0.8rem 1.6rem; }

And now let's build a web component that is fully built with rem CSS units:

<div class="subscription-container"> <div class="padding-container"> <h3 class="heading">Manage subscription</h3> <div class="text-container"> <p>Feel free to update your subscription type anytime to select the topics that resonate with you the most.</p> </div> <div class="button-container"> <button type="button" class="button-style">Change plan</button> </div> </div> </div>


First, to create such beautiful styles we need to define CSS classes for containers:

html { font-family: Inter, Roboto, sans-serif, Verdana; width: 100vw; height: 100vh; } .subscription-container { background-color: #ffffff; box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06); border-radius: 0.5rem; } .padding-container { padding: 1.25rem 1rem 1.5rem; }

Second, we need classes for text blocks:

.heading { font-size: 1.3rem; font-weight: 600; line-height: 1.5rem; color: #1a202c; } .text-container { max-width: 40rem; margin-top: 0.5rem; font-size: 1rem; color: #718096; }

And finally button styles:

.button-container { margin-top: 1.25rem; } .button-style { display: inline-flex; align-items: center; border-radius: 0.375rem; background-color: #6366F1; padding: 0.5rem 1.75rem; font-size: 1rem; font-weight: 600; color: #ffffff; box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.05); transition: background-color 0.3s; border: none; width: 10rem; }

There are multiple popular CSS libraries that are built on top of rem CSS units, for example:

  • Tailwind CSS - This utility-first CSS framework uses rem units for most of its spacing, sizing, and typography utilities. Tailwind's use of rem allows for consistent and predictable results across different devices and respects user settings in browsers.
  • Bootstrap - From version 4 onwards, Bootstrap shifted from pixels to rem units for defining most dimensions, spacings, and sizes. This change was made to enhance accessibility and to provide a more consistent scaling experience.
  • Foundation - Similar to Bootstrap, Zurb's Foundation framework also uses rem units extensively in its components and utilities. This is part of its approach to create more accessible and mobile-friendly web designs.
  • Bulma - Bulma is another modern CSS framework that relies on rem units for its design philosophy. The framework uses rem for components sizing, spacing, and is highly appreciated for maintaining vertical rhythm.

Hope you find this blog post useful. Happy coding!

After reading the post consider the following:

  • Subscribe to receive newsletters with the latest blog posts

  • Download the source code for this post from my github (available for my sponsors on BuyMeACoffee and Patreon)

If you like my content - consider supporting me

Unlock exclusive access to the source code from the blog posts by joining my Patreon and Buy Me A Coffee communities!