Typography and spacing in CSS
PSA: If you’re here for my posts about life and minimalism you can skip this one.
If there’s one thing that I really love to do while I code websites it's to come up with new solutions to handle spacing and typography. My designs are usually quite simple and I like to build simple frameworks for my projects. I’ve never been a fan of Bootstrap and the other CSS frameworks because they usually have way more stuff than I normally need for any given site.
Responsive typography
One of the topics that intrigues me the most is the idea of responsive typography. Plenty of good posts on the web on the subject if you’re interested. The concept is pretty simple: you have a minimum font size at a certain viewport width, a maximum at another viewport width and in between you scale the font in relation to the current viewport size. Something like this:
html {
font-size: 16px;
}
@media screen and (min-width: 320px) {
html {
font-size: calc(16px + 6 * ((100vw - 320px) / 680));
}
}
@media screen and (min-width: 1000px) {
html {
font-size: 22px;
}
}
This one is from a CSS Tricks article and uses media queries to fix the font size. One day I started messing around with SASS to find a solution that worked without the media queries and I came up with this monstrosity
calc((#{$min-font-size} + ((100vw - #{$min-screen-size}) / (#{pure($max-screen-size)} - #{pure($min-screen-size)}) * (#{pure($max-font-size)} - #{pure($min-font-size)})))
Yes, I agree. That’s ugly. And probably stupid. But hey, I was having fun. This one uses a few variables to set the min and max values for both font size and screen size and as ugly as it was, it was doing its job. Needless to say, it wasn’t easy to use especially if you want to combine it with a typographic scale, another of the things I like to use.
Enter AKU
This is when my AKU framework comes in. I named it AKU because I was looking for a short word that started with A to have the folder at the top of the list and AKU was a good candidate. Anyway, names aside, AKU is a very simple framework I use in pretty much every project these days. It’s written in SASS and right now includes just 4 files:
aku/
typography/
settings.sass
type.sass
reset.sass
variables.sass
Reset.sass
This is a custom version of one of the main reset files. There’s nothing noteworthy in there, it’s just to reset the styles and not have to deal with browsers’ inconsistencies.
Variables.sass
This is where I store all the variables I use in a project. I never use more that 15 of 20 of them and that includes colors, z-index values, animations settings and font families.
The typography folder
This is where things get interesting. The two files in the typography folder are arguably the most important files in my CSS setup. The settings.sass
file contains the main typography settings and, in its simplest form, looks like this:
\:root
font-size : 25px
font-family : "Iowan" , serif
font-weight : 400
I wrote “simplest form” because depending on the site I can have multiple media queries to adjust the typography based on the viewport but the concept is the same. As for the other file, type.sass
, it contains 2 SASS Mixins. One is a simple utility mixin to set the correct antialias when I have light text on dark background and it looks like this:
@mixin aku-alias
-webkit-font-smoothing : antialiased
-moz-osx-font-smoothing : grayscale
The other is my main typography mixin.
@mixin aku-type($size : "normal")
$baseSize : 0.6rem // Base Font Size 15/25
$baseRatio : .8 , 1 , 1.25 , 1.563 , 1.953 , 2.441
// Normal Font Size
@if ($size == "normal")
font-size : $baseSize * nth($baseRatio , 2)
font-family : inherit
line-height : 1rem
This is a compact version, the complete mixin has 6 identical @if
rules, one for each ratio but they all look pretty much the same. In some of them I can have extra padding to reach a full height value, based on my typography settings. Now you might be thinking ”What the hell does that even mean?”.
To explain that, let’s go back to the setting.sass
file. In there, as you can see, I set the font-size
for the :root
. But actually, this has nothing to do with the font size. This is the base value for the line-height
that in turn will establish the height of my typographic grid. If you wanna read more about typographic grids these two are very good articles.
Why not just using line-height
you ask? Because by using font-size
on the root element I can also fix the value of the rem
unit. Which means that 1rem
is equal to 1 baseline unit, no matter how much a base line unit actually is. So if I write this...
h1
+aku-type(large)
margin-bottom : 1rem
...I know I’ll have 1 baseline unit of space from the title to whatever comes after it. To work with baselines I use a great Chrome Extension called Baseliner. It a simple tool that does an excellent job.
You’re probably thinking why even waste time doing all this. Well for start because it’s fun. But also because it allows me to quickly change the aspect of the site by simply tweaking a few values inside the main sass files rather than going through the entire project. If, for example, I want to use a different typographic scale, with a different ration, I can simply update this one line inside type.sass
$baseRatio : .8 , 1 , 1.25 , 1.563 , 1.953 , 2.441
Do I want to increase the font size across the entire site after a certain viewport width? Easy...
@media (min-width : 600px)
font-size : 28px
And this will not only increase the font size but it will also increase all the spaces since everything is set using rem and rems are tied to the font-size.
Some Issues
As every framework, there are tradeoffs. You’re tying together layout and typography and not everyone likes that. I’m big fan because I like minimalist layout but it’s not always ideal. You’re also limited to one type scale because right now there’s no way to change that on the fly. It can be done but that’s not something I personally need.
So there, that’s how I’m currently dealing with typography in CSS. I’m not used to write this kind of posts so if you have questions feel free to ask and I’ll get back to you hopefully with a decent answer.