overview
Text-relative sizes in a web project
A simple helper for easy calculation of rem units
Jan 12th, 2020
It is often overlooked when building websites that not everyone wants text to be the same size. This could be for several reasons, but the idea is that we should build our web apps in such a way that text size is user-changeable.
When I first started doing web development around 2013, the people I knew were divided into two camps. Some were in favor of using the em
-unit (defines a size relative to the parent element font size) or rem
-unit (defines a size relative to the root element font size) everywhere. Others (like me at the time) preferred using text size defined using pixels (px
). For me, the reason was primarily because of being used to reason in pixel sizes. For instance - if the root element font size is 16px
and we want an element to have a font size of 22px
, this requires a value of 1.375rem
. Visually we get the same result (given a root font size of 16px
), but the value 1.375rem
is not intuitive to me.
Recently, I've come up with a simple technique to define sizes in terms of rem
-units but written in terms of pixels (assuming a root font size of 16px
). This technique can be adapted for whatever CSS solution is in use, but the following examples use https://github.com/zeit/styled-jsx.
function px(v) {
return v / 16 + "rem";
}
function Component(props) {
return (
<header>
{props.children}
<style jsx>{`
header {
font-size: ${px(24)};
margin: ${px(8)} ${px(2)};
}
`}</style>
</header>
);
}
If we look at the style, we can see the transform that occurs:
function px(v) {
return v / 16 + "rem";
}
const css = `
header {
font-size: ${px(24)};
margin: ${px(8)} ${px(2)};
}
`;
/* css is now:
header {
font-size: 1.5rem;
margin: 0.5rem 0.125rem;
}
*/
While one could now use this helper for all dimensions in a web app, I find it to be the most useful for dimensions only related to text display. It makes little sense, at least to me, to define a border-radius
in such a way that the user-specific font size affects it. However, defining spacing and margins for text elements make much more sense. This then preserves spacing even if text becomes larger or smaller.