We're celebrating a new year and new skills, by offering a 21% discount off all courses and collections at checkout! ✨

How to make reactive type as seen on the Airbnb Cereal site


June 5th 2018



Posted by

Rik Lomas

On the new showcase for Airbnb's new typeface, Cereal, there's a great way that they show off the different sizes and weights of the face by making individual letters respond to mouse movements. We talk about how to achieve this effect (and more) using a few lines of Javascript and a little math.

View demo


(lively music)- [Rik] One of the most requested thingsI've had in the last week is all aboutthis new site by Airbnb.It's all to launch their new Cereal typeface,a new replacement for Circular,and as you can see, as I move around this page,the letters get bigger and the weight gets heavieras you kind of move closer to each letter.So I'm gonna show you how to makea quick version of this one.I'm gonna start with a very simple version of this.How do I move around the pageand make my letters change sizeas I move the mouse around?(lively music)So the first thing to do is to pick a typefacewith a lot of weights.Now, I've just gone on Google Fontsand just put the number of styles up to about 18,and the one that we're gonna use is actually Fira Sans.It works pretty well.And the way that you do this isyou can just select this font,and when this pops up, there it is,I'm just gonna customize and add inall of these different weights.So I don't need any of the italics.I'm just gonna get off those.Usually, there's two options to embed fonts.I like to do the import and select the middle bit,and add it to my project.So the way that we start off our projectis fairly straightforward.In my index.html, I've got one section tagwith a lot of divs inside itand each div has a letter.In my style sheet,I've got my font at the top of the pagewhich is just from Google Fonts.I've set it up,and the maximum font size I'm gonna pickis actually 80 pixels and each letteris gonna be 100 by 100 so I've gota line height of 100 pixels.It's in the middle of it as well.The background color is blackand the text color itself is white.These kinda four styles are just to move thisinto the middle of the page,moving that section tag straight into the middleof the body itself.Then, in the section tag, I've got a width of 1200 pixels,because it's a 12-column gridand I'm using the CSS grid to make ita 12-column by 12, so 12 fractions.And then each auto row,if you add any more lettersit would just be in the 100 pixels.Now the div is a weight 100,so the lightest font first.Now the way that Airbnb are doing it isnot by changing the font size,but actually to change the scale of the font instead.So, we're gonna start off with a smaller font on load.And to do that I'm just gonna add a transform scale,and we'll make it 20% of the default.So what we're gonna do iswhen we move over this font,we can set some Javascript,so when we move the mouse on the page,change not just the scale,but also the font weight as well, these two things.(lively music)So the first thing you want to do isactually see how far away my mouse isfrom the cursor on each page.Then we'll do some kind of scoring system,and then we'll size things up.Now I just want to make this a little bit easierfor ourselves, just to see what's going on.So the first thing we're actually gonna do isremove this scale by just commenting it out.You can do this quite quickly in the editorwith Command + /I'm also gonna make the default font size,or the maximum font size, just 40 for now.We'll kind of put it back up later.But we'll get something like this.You can kinda see the grid systemkind of laid out like that.Now, because I'm doing this on mouseover,I need to do this using some Javascript.And the way that we do that iswe need to, first of all, we need to make a Javascript file.Just, we'll call it cereal.js.And there we go, it's an empty one at the moment.We need to add this to our index.html.Now I'm gonna do this at the bottombecause we need to load it after all HTML.And that's cereal.js as well.So let's think about how this cereal.js works.Whenever we move the mouse on the page,we need to kind of work out how far away the mouse isfrom each individual div tag.And the div tag is from just here, each letter in here.Now, how do we think about this using actual Javascript?So, when is always a good thing to start with.When we are moving the mouse on the page, do something.So the way we write that in Javascript,is in document, because that's the page.We want to add an event listener.Now in brackets we want to add two things.What thing we're listening out for,and then what we do with it.What we're listening out for is a mousemoveand then comma, what we're gonna do.Well, we need to run a function.So function, round brackets, curly brackets.Now, we're gonna pass one thing into the function,which is called an event.Now again, we don't need to,we can call this whatever we want.We're not using it at the moment,which is why it's given that little yellow line.But we want to do something with the event.So with these curly brackets,I'm just gonna write some code in here with that event.So I'm just gonna open up these curly bracketsto make it a little bit easier to read.And I'm gonna save two things from the event.Where we are across the page,and where we are up and down the page.So I'm gonna save the constant of x,and from this event,this kind of event that's been passed in,we're gonna do pageX.

Now this is given to us by the browser itself.And with pageX is also a pageY, event.pageY.

Now I've saved them to two different constants.Now constant because they don't change.We keep them as they are within this mouse movement.Whenever this runs,this kind of function runs every single time.Now what do we want to do with these things?Well, it depends on where the divs are.Now each div is gonna give a different resultevery time we move the mouse on the page.So, within this function,we're gonna then select in the page itselfall the div tags.So .querySelectorAllbecause we wanna do it for every single div tag.How do we select them?In brackets and then quotes, div.Now again, this works like CSS,so it could just be section space divif you want to be a bit more particular.I'm just gonna keep it as every div tag on the page.Now, because each one is gonna do a different thing,because it's different distances away,we want to do things for each.

Each, if I can spell correctly.And then in brackets,we want to do something for each thing.What is each thing gonna be called?Well, let's give it a name, we're gonna call it div.And this is gonna do something with each div.So in these curly brackets againI'm just gonna open them upto make it a little bit easier to read.We want to calculate how far the cursor isfrom the center of each div.Now each div is 100 by 100,because that's what we set up is CSS.So what I'm gonna do is save thisto another constant called dx.Now dx is just div x, I just called it that because each.I can separate from the x of the cursor itself.And this is gonna equal to,well, where is the div from the left hand side?offsetLeft.Now I don't wanna do the offsetLeftbecause I want to find the center across the page.And it's 100, so I'm just gonna add 50 to it.But then I also want to take away the cursorbecause I want to find that distance.So this is where it is from the left of the page.But then I want to find itthe distance from the cursor itself.I want to do the same thing up and down the page.So this one should look fairly familiar.This is div.offsetTop with a capital T.We're gonna add 50 because it's 100 by 100.And then minus y.

Now this is gonna get it across and up and down the page.We want to find the actual distance diagonally.Now you might remember this from just Pythagoras' Theorem.

A squared plus b squared is c squared.So we're gonna do the same thing.Now this is just a little bit of math kind of trigonometry.Were gonna save this to another constant called dist.Distance, how far away is the cursor from the middle?So this is gonna equal toour a squared plus b squared equals c squared.We don't see squared, we want it to kind of have square rootso we're gonna do Math.sqrt first of all.So we do dx times dx, which is our a squared,plus dy times dy, which is our b squared.

So a squared plus b squared.And then we square root it to get our distance.Now this isn't doing anything on the page right now,so if you actually look at it,nothing happens at the moment.So let's make something happen with it.Let's actually write this out.So how do we write this out?How do we show it on the page?I can just change the div.innerHTML.We're changing the HTML of this.And this is gonna equal to distance.So we're just gonna print out the distance on the page.You can see there's lots of really large numbers herebecause it's kind of doing a lot of trigonometry.So it's giving a lot of decimal places.So how do we make this actuallya little bit more of a rounded number?We're just gonna add Math.round around this.

So Math.round and then brackets, distance.So what this will give us nowis actually a nice round number.So if I'm near the center of this,you can see that it's going to zero, one, twos.And the further I am, the bigger that number gets.So the next thing we...

So the next part we'll do is actually assign this a score.(lively music)Now, apologies if you don't like math.This is gonna be the most math that we do.So what I'm trying to do next isI want to assign the score how far away we arefrom the cursor to a number between zero and one.Now the reason it's zero and one isbecause the scale goes between zero and one.We could make it go to two or 100.Now 100 times that is kind of crazy.We just want it to be number one is the top or nearest pointand zero as it trends away.So I've basically made this kind of equation.It's an exponential.

So exponential minus 0.003x.

Now again, don't worry too much about this.It's just the kind of curvethat we've made in math and Grapher.This is a kind of mock-up.We could actually change this number,depending on how far or how quicklyor how slowly you want to move away.So for instance, if I change this numberto not three but two,that takes it a longer distance away.If I make this even bigger, so .6,this kind of goes between that,makes that curve a lot tighter.Now how do you do this in Javascript?So what I'm gonna do next isturn this distance that we have on the pageinto a score between zero and one.So below here, I'm just gonnahave a constant called score.Now this is gonna equal tothis number that I've just made in Grapher.So, Math.exp exponential is the distance times 0.003.

Now again, we can change this curve if you want to.We can use a different kind of mathematical score.I'm not gonna go too in-depth in this.It is a little bit more math.What I want to do next is show the score.So instead of this being the distance,instead I'm gonna do this as the score.

I wanna just fix it to two decimal places for now.toFixed for two decimal places.So let's see how that looks.So now as I go closer to this,you can see that number goes up to basically one.And if I'm over here, it changes down.So it depends on where we are on the page.So I've basically given this a score.(lively music)Now we don't want to actually change the text of this,so we can actually get rid of this line.I'm just gonna comment it outby putting two slashes at the start.And what we actually wanna do ischange this based on the transform.So down here we have transform: scale(0.2)which is the score that we actually just made.Now the way that we're gonna do this iswe're gonna change the style of each individual div.So in each individual div, we're gonna do .styleand change the transform.

Now this is gonna equal to,well let's just for now make it .2.Scale is, in brackets, 0.2.

So now if we move the mouse anywhere on the page,it will just go to 20% scale.You can see it got us instantly smalleras soon as we moved the mouse.But we don't want it to be 0.2.We want it to be based onthe score that we've just calculated.So instead of 0.2, just gonna get rid of it.And I'm gonna put in quotes here,so we've got two parts at the moment,scale plus something.This stays the same, and this stays the same.But we want to add in score and add that to the end.This bit stays the same, this bit changes,but this bit stays the same at the end too.So now as we go around the page,you can start to see the scale kind of taking effect.

Now, I can actually change this fontback to the maximum size.So the maximum size that I actually wantedwas not font size 40 but actually 80,which is the maximum size on the page.So now you can see, as we scroll around the page,when I get near to this, this goes to 80 pixels,and as I move away, it goes to zero.(lively music)Now on the Airbnb site,there's actually the font weight changes as well,not just the size of this too.Now, how do we think about that?Well, if we look at our font, there's actually onlynine different versions we can pick from.100, 200, all the way up to 900.So we don't have this kind of flexible scalewhere we have on the graph.So there are different kind of set pointsthat we need to kind of work with here.Not just kind of a number.So how do we think about this?Now, below here, I'm just gonna set my style of the div,the fontWeight, notice the capital W there.Now we'll set it to just be 100 for now.By default, it is 100 because we set that in CSS.Now the maximum it can be is 900.100 plus 800.

So now, we can see the font weight is really heavy.What we want to do is basically calculatethe weight based on the score.But there's only nine different variations we can pick from.So we want to have this number oneplus number eight in here as well.So I'm gonna turn this 800 into two things.So I'm gonna put in brackets, which is 100 times eight.So basically there's one stepplus eight more steps it can be.Now, it's not gonna be eight in the end.It's actually gonna be dependent on the score.Now if we just times it by eight times score,because it's between zero and one,what we should see at the moment is this kind of effect.You can see that was a pretty kind of straightforward thing.Now what we're trying to do here is saywhat is the minimum version,then what is the maximum version it could be,but times it by the score.Now just to be kind of very explicit with this,what I actually wanna do in the long term,and this kind of will work in the browser either way,is I just wanna kind of set it to the nearest one.So it's not 102, for instance, that's not a font weight.It's 100 or 200.I'm just gonna make this bit herego to the nearest one.So we're gonna round this end bit here.So just put round here.So it's going to the nearest one.But what this will do isthe same thing as what we've just seen.We can have this weight kind of changing automatically.Now there's other things I can justquickly put in here as variations.Maybe we want to add a little bit of delay to that.So notice on the Airbnb siteit kind of fades in a little bit.How do they do that?Now it's pretty simple.In the style.css for each div,they're also adding in the transition.So transition in here.And they're only doing it on the transform the scale itself.So on the transform, we'll just add in let's say one second.Just to see how long that will take.And there you can see it takes a while for this one.Maybe it's too slow,maybe we'll kind of change that to .2..2 might work pretty well.So let's see now.

There you can go, you can see a slight delay on this.And you can change this to be whatever you want.Now if you do want to kind of have a play around with this,things to play around with arethe font size and the size of the grid,and the way that you actually calculate things as well,which is just in here.Now if you wanna make this a kind of bigger thing,so maybe I'll do .005,you can see now it's a bit more ofa kind of magnifying effect.If I make this a little bit bigger, oh sorry, smaller,that should be a bit more of a broader effect.You can see there's not much of a differencebetween the two sides.And it's up to you.You can change how this works.It's a very flexible system.We did a little bit of math in there.A little bit of Pythagoras' Theorem.But we've made something that's fairly simplewith just 15 lines of Javascript.

If you liked this video, you'd really loveour Foundation HTML, CSS, and Javascript course.(lively music)

Want more? Sign up for our newsletter for more articles, resources, and fresh inspiration