Relative CSS reset

Submitted by daniel on Wed, 18/02/2015 - 15:16

When starting a new project that needs to be themed it is not uncommon to use a css reset. One of the early pioneers here was Eric Meyer.

The basic reason is that all browsers have presentation defaults, but no browsers have the same defaults.  (Okay, no two browser families—most Gecko-based browsers do have the same defaults.)  For example, some browsers indent unordered and ordered lists with left margins, whereas others use left padding.  In past years, we tackled these inconsistencies on a case-by-case basis; for example, making sure to always set both left padding and left margin on lists.

SInce 2007, perhaps not suprisingly, browser stables still have different defaults and browser resets still have a role in theming your site or project consistently cross browser.

One area that does seem to have progressed considerably is the use of media queries to provide responsive design. Essentially this is where we take  a 'mobile first' approach to design and then use media queries to provide a responsive layout where we make more use of the desktop 'real estate' available. So for example we could offer a grid like layout that shows more columns, provide a different menu/ui etc.

One thing developers will often be asked to do is 'can we make the text size smaller' on smaller devices. This is course is possible using media queries, however, changing the size of various elements to 'fit' better on a smaller device can be like opening up a can of worms and before you know it you are spending an awful lot of your time adjusting various elements to work on a variety of screen sizes, and then testing on a variety of devices etc and making further adjustments that perhaps are compromising on a designers original vision as you may also change the relationships or intended impact  between various sized items.

Well, one solution is to use relative font sizes. Here we have the power to set things to be smaller across the board. Now relative font sizes are nothing new. Browsers and developers have been using em's for some time. Typically most browsers interpret em's as relative to the parent. So we can change things and they should cascade down to the element you want. Using ems is similar to using % to set things relative to their parent in the dom. However you can also get undesirable effects with using em's such as compounding. This is likely if you are using nested elements. Yet again we have a situation that is far from ideal where we may have to overide or set a series of values using the relative font size that is set in em's and media queries.

Welcome to Rem's.

The rem unit is similar to em's in that they are relative, but rather than being relative to their parent, they are relative to the root element in the dom (the html tag). Therefore we can set the sizes for all elements in rems and they do not suffer from compounding issues (as mentioned with em's), 

SO typically 1 rem is usually set at 16 px in most browsers. However as you probably know you can  change this with CSS to be any value you like. So for example you could set to say 14 px, and everything that you have sized in rem will be relative to that. i.e. if you set a h3 to be 2rem, and you set the root element to be say 14px, the h3 will be rendered at 2 x 14px = 28px.


One benefit of this approach is a client or designer can say, well we would like to have text smaller on a smaller device, and bigger on a larger device. Voila. We can simply modify the size of the root element to be larger or smaller with media queries, and all elements that are set using our rem unit will adjust accordingly. So rather that having to reset or get a load of elements to respond on a site that could take a while and cause some undesirable results, we simply set the root element and everything will nicely cascade.

Why would we want smaller text on a smaller device? Well this is up for discussion. Chances are your device may make some adjustments to text size already. This can be overome using the following:

/* bespoke resets here */

* {
  -webkit-text-size-adjust: none;
  -moz-text-size-adjust: none;
  -webkit-text-size-adjust: none;
  -ms-text-size-adjust: none;
  font-size-adjust: none;

There is certainly an argument to suggest that to make the most of the available viewport, we can adjust the size of elements accordingly. SO on a smaller device, making the text smaller makes arguably makes more use of the limited real estate available and can prevent undesrable wrapping of text etc. Where as on a large viewport, where we have a large resolution screen, we would arguablly want to make the text larger to make it more readable expecially if viewed at a high resolution.

These adjustments do not have to be limited to font sizes. We can set margins and padding etc using the relative units and they will appear smaller on a smaller device and larger on a larger device, the same as text etc. This may lead to some considerations when choosing say the default sizes, margin, padding etc so that they do not appear too small when readjusted for a smaller screen! This may look better than say using % which can often look too small on a small screen or too big on a large screen.

Relative Reset

So this approach raises an issue of the role of a reset. As mentioned before we want to size everything using rems. However my favourite css reset, resets everything in pixels. Well while this is useful for browsers that still do not support rems (ie8 and older), it means that I am essentially overiding the reset in order to get all my elements to respond to the root element. My solution therefore is to modify the meyer reset to support rems, by redeclaring all values set in pixels to also be set in rems. This means we have a nice fallback for ie8 and older browsers that do not support rems, but we are keeping our back end developers happy by removing any unnecessary repetition!

SO here it is, my version of meyer remixed that provides a relative reset for the 'media query' age. Please feel free to reuse or modify for your purposes.

/* Daniel Lobo's relative reset based on meyer.

This resets all base units to use rem

One benefit of this approach is that we 

can use media queries to make all elements 

either larger or smaller depending on 

the viewport by setting the size of the root 

element  i.e. html {font-size: 12px;} 

    License: none (public domain)

    There are a few extra bits as well that 

    can be useful. More details below.



/* rems are relative to the root element or to be exact 'html' */

/* of interest is that the reset, resets everything in pixels.

    perhaps this should be reset in relative units? i.e. rems 

    makes difference on larger and smaller `viewports

    can adjust root element i.e. html (not body) */





del, dfn, em, ins, kbd, q, s, samp,


b, u, i, center,

dl, dt, dd, ol, ul, li,

fieldset, form, img, label, legend,

table, caption, tbodsy, tfoot, thead, tr, th, td,

article, aside, canvas, details, embed, 

figure, figcaption, footer, header, hgroup, 

menu, nav, output, ruby, section, summary,

time, mark, audio, video {

margin: 0;

padding: 0;

border: 0;

font-size: 16px; /* for older versions of ie */

font-size: 1rem;

font: inherit;

vertical-align: baseline;



img {

  -ms-interpolation-mode: bicubic;

  /* vertical align required as outlined here */

  /* */

  vertical-align: bottom;




/* HTML5 display-role reset for older browsers */

article, aside, details, figcaption, figure, 

footer, header, hgroup, menu, nav, section {

display: block;



body {

line-height: 1;



ol, ul {

list-style: none;



blockquote, q {

quotes: none;



blockquote:before, blockquote:after,

q:before, q:after {

content: '';

content: none;



table {

border-collapse: collapse;

border-spacing: 0;



/* apply a natural box layout model to all elements 






*:after {

  -moz-box-sizing: border-box; 

  -webkit-box-sizing: border-box; 

  box-sizing: border-box;




a {

  font-size: inherit;



/* bespoke resets here */

* {
  -webkit-text-size-adjust: none;
  -moz-text-size-adjust: none;
  -webkit-text-size-adjust: none;
  -ms-text-size-adjust: none;
  font-size-adjust: none;





Add new comment