Cross-Browser Responsive Design and Typography with pure CSS.

Ever wondered why there is so much emphasis on responsive design? Responsive design doesn’t just mean compatibility between desktop view and mobile view! Today’s computer market has a wiiiide variety of resolutions on laptops and your design varies extensively on each one of them. A good responsive design makes a HUGE difference in user experience here — especially when you are developing a customer-facing product page. It’s like they say — “First impression is the best impression”!

I am Krishna and I am back with this article on how to make your pages totally responsive — from the “Welcome to…” statement all the way to every other icon in your website/app.

Agenda —

  1. Learn what the :root selector in CSS is and about its importance here.
  2. How do we set the font-size and WHY specifically the font-size.
  3. How to calculate and set the other sizes and how it is affected.
  4. Finally, responsive.
  5. A small demo (CodePen embed) showcasing how effective it is.

Scenario —

This has been a major problem for everybody who gets a great design done looking at every pixel in the design and calculating where the folds start and ends. But this is often not delivered when it is developed because of the varied screen resolutions — some times the content extend past the fold and some others, the content falls short of the folds exposing the content that the user had to scroll down to see.

So how DO you fix this? Let’s start with the :root selector. The :root selector basically matches the document's root element — this is usually the <html> tag. It affects the complete DOM and all of its inherited properties. Usually, the browser default for the root font-size is 16px. So we’ll let it be and see how we can work this out in our favour. Here’s a setting for the root font-size.

//globalStyles.scss:root {
font-size: 16px; //Fallback for browsers that doesn't support vw
font-size: 0.85vw;

We specifically update the font-size because the rest of the places in our app, we will be using the rem unit to measure all sizes.

The rem unit is a representation of the font-size of the root selector. To know more in detail about the rem unit, refer to the MDN document here.

As you are aware of it, default font-size = 16px, but why another font-size in vw you may ask. This is optional but I’d prefer it this way as it scales your fonts and other elements based on the desktop screen resolutions as well. Even then, why 0.85? This is because 1vw = 100th part of your screen’s window.width — so 16px * (100/window.innerWidth) which sums up to 0.85vw (on my screen. Don’t worry, I will link a small tool called flexel for you to work conversions with). Once this is set, we need to adjust the same settings for responsive screen size. Adding to the above code —

//globalStyles.scss// Desktop Screen
:root {
font-size: 16px;
font-size: 0.85vw;
// Tablet Screen
@media only screen and (min-width: 768px) and (max-width: 1200px) {
:root {
font-size: 18px;
font-size: 1.5vw;
// Mobile Screen
@media only screen and (max-width: 768px) {
:root {
font-size: 20px;
font-size: 2.17vh;

If you look at the mobile media query above, the font-size is set in vh because the height is larger compared to the width. However, if you are uncomfortable with this convention, you may set this to a larger vw number that would make the text legible on all screens.

Extending this implementation further —

For different break-points, you can refer to this w3schools documentation. EVEN better — you can improve this further by adding orientations! — refer to this w3schools documentation.

Summary —

To summarise all that we have done till now, we have written media queries for mobile and tablet screen variations and we have set a root font-size for all three cases. The vw font-size makes the other sizes smoothly scale as your resolution increases / decreases and the px font-size right above is a fallback for those browsers that doesn’t support vw / vh yet (minimal).

This sets up our base for the app to scale accordingly. All that is left now is for us to code with the rest of the length, breadth and size attributes in the rem unit. With the above code,

16px = 1rem => 1px = 1/16 = 0.0625rem

This is the conversion we will use to convert all our px to rem — be it width, height, border, font-size, padding, margin or whatever else. Here’s a small tool that will allow you to enter your pixel number and output the rem equivalent — TheCodeAddict/Flexel.

Now try resizing your browser and adjust your pixels/viewport sizes accordingly to fit your need.

Gotchas —

  1. The coolest part about this implementation is that whenever someone says that the text is illegible, all you have to do is manipulate the font-size in your :root selector and it will reflect throughout the app.
  2. This is a cross-browser compatible solution with fallback values meaning your code and design is consistent across all browsers and users. “Users are happy = we are happy”!
  3. You can add as many media queries for screen sizes — like for example, a 21.5 inch iMac has a godly resolution of 5120 x 2880. Like I swear a 0.85vw font-size is gonna look like an apple under a magnifying glass (ba dum tssss)😂. You might wanna tone it down a bit by adding another media query with probably a 0.5–0.6vw font-size.
  4. This will not affect any other units like % or if you have had to add a px unit in-between for implementation purposes.
  5. You can do the conversions with this tool — TheCodeAddict/Flexel.
  6. Last but not the least — It is a Pure CSS solution… You gotta ❤️ them.

Here’s a final CodePen embed demo as promised :)

I hope I could adequately explain this topic and make development easier. I am sure there are a lot of stuff that could be improved here and I am all ears for that. Please let me know your thoughts and implementation methods in the comments! May 2021 bring joy to you all, peace out and CHEERS!

ReactJS, NextJS, NodeJS and every other JS! It’s like a never ending learning journey. 😎