About The Author

Rachel Andrew is not only Editor in Chief of Smashing Magazine, but also a web developer, writer and speaker. She is the author of a number of books, including …
More about

In a new series, Rachel Andrew breaks down the CSS Grid Layout specification. This time, we take a look at how to use the grid lines to place items.

In the first article in this series, I took a look at how to create a grid container and the various properties applied to the parent element that make up your grid. Once you have a grid, you have a set of grid lines. In this article, you will learn how to place items against those lines by adding properties to the direct children of the grid container.

We will cover:

  1. The placement properties grid-column-start, grid-column-end, grid-row-start, grid-row-end and their shorthands grid-column and grid-row.
  2. How to use grid-area to place by line number.
  3. How to place items according to line name.
  4. The difference between the implicit and explicit grid when placing items.
  5. Using the span keyword, with a bit of bonus subgrid.
  6. What to watch out for when mixing auto-placed and placed items.

Basic Concepts Of Line-Based Positioning

To place an item on the grid, we set the line on which it starts, then the line that we want it to end on. Therefore, with a five-column, five-row grid, if I want my item to span the second and third column tracks, and the first, second and third row tracks I would use the following CSS. Remember that we are targetting the line, not the track itself.

.item {
  grid-column-start: 2;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 4;

This could also be specified as a shorthand, the value before the forward slash is the start line,m the value after is the end line.

.item {
  grid-column: 2 / 4;
  grid-row: 1 / 4;

On CodePen you can see the example, and change the lines that the item spans.

See the Pen Grid Lines: placement shorthands by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Grid Lines: placement shorthands by Rachel Andrew (@rachelandrew) on CodePen.

Note that the reason our box background stretches over the entire area is because the initial values of the alignment properties align-self and justify-self are stretch.

If you only need your item to span one track, then you can omit the end line, as the default behavior is that items span one track. We see this when we auto place items as in the last article, each item goes into a cell – spanning one column and one-row track. So to cause an item to span from line 2 to 3 you could write:

.item {
  grid-column: 2 / 3;

It would also be perfectly correct to miss off the end line:

.item {
  grid-column: 2;

The grid-area Shorthand

You can also place an item using grid-area. We’ll encounter this property again in a future article, however, when used with line numbers it can be used to set all four lines.

.item {
  grid-area: 1 / 2 / 4 / 4;

The order of those line numbers is grid-row-start, grid-column-start, grid-row-end, grid-column-end. If working in a horizontal language, written left to right (like English), that’s top, left, bottom, right. You may have realized this is the opposite of how we normally specify shorthands such as margin in CSS – these run top, right, bottom, left.

The reason for this is that grid works in the same way no matter which writing mode or direction you are using, and we’ll cover this in detail below. Therefore, setting both starts then both ends makes more sense than mapping the values to the physical dimensions of the screen. I don’t tend to use this property for line-based placement, as I think the two-value shorthands of grid-column and grid-row are more readable when scanning through a stylesheet.

Lines On The Explicit Grid

I mentioned the explicit versus the implicit grid in my last article. The explicit grid is the grid that you create with the grid-template-columns andgrid-template-rows properties. By defining your column and row tracks, you also define lines between those tracks and at the start and end edges of your grid.

Those lines are numbered. The numbering starts from 1 at the start edge in both the block and inline direction. If you are in a horizontal writing mode, with sentences which begin on the left and run towards the right this means that line 1 in the block direction is at the top of the grid, and line 1 in the inline direction is the left-hand line.

Item is shown in position with the Firefox Grid Inspector highlighting the lines
The item placed on the grid

If you are working in a horizontal RTL language – as you might be if working in Arabic – then line 1 in the block direction is still at the top, but line 1 in the inline direction is on the right.

The item is now placed from the right-hand side of the grid
The same placement with direction: rtl

If you are working in a Vertical Writing Mode, and in the image below I have set writing-mode: vertical-rl, then line 1 will be at the start of the block direction in that writing mode, in this case on the right. Line 1 in the inline direction is at the top.

The entire grid is now rotated 90 degrees
The same placement in writing-mode: vertical-rl

Therefore, grid lines are tied to the writing mode and script direction of the document or component.

The end line of your explicit grid is number -1 and lines count back in from that point, making line -2 the second from the last line. This means that if you want to span an item across all tracks of the explicit grid you can do so with:

.item {
  grid-column: 1 / -1;

Lines On The Implicit Grid

If you have created implicit grid tracks then they also count up from 1. In the example below, I have created an explicit grid for columns, however, row tracks have been created in the implicit grid, where I am using grid-auto-rows to size these to 5em.

The item with a class of placed has been placed to span from row line 1 to row line -1. If we were working with an explicit grid for our two rows, then the item should span two rows. Because the row tracks have been created in the implicit grid, line -1 resolved to line 2, and not line 3.

See the Pen Grid Lines: explicit vs. implicit grid by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Grid Lines: explicit vs. implicit grid by Rachel Andrew (@rachelandrew) on CodePen.

There is currently no way to target the last line of the implicit grid, without knowing how many lines you have.

Placing Items Against Named Lines

In the last article I explained that in addition to line numbers, you can optionally name lines on your grid. You name the lines by adding a name or names inside square brackets between your tracks sizes.

.grid {
  display: grid;
  grid-template-columns: [full-start] 1fr [main-start] 2fr 2fr [main-end full-end];

Once you have some named lines, you can swap out the line number for a name when placing your items.

.item {
  grid-column: main-start / main-end;

See the Pen Grid Lines: naming lines by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Grid Lines: naming lines by Rachel Andrew (@rachelandrew) on CodePen.

If your line has several names, you can pick whichever one you like when placing your item, all of the names will resolve to that same line.

Note: There are some interesting things that happen when you name lines. Take a look at my article “Naming Things In CSS Grid Layout” for more.

What Happens If There Are Multiple Lines With The Same Name?

You get some interesting behavior if you have multiple lines that have the same name. This is a situation that could happen if you name lines within repeat() notation. In the example below I have an 8 column grid, created by repeating 4 times a pattern of 1fr 2fr. I have named the line before the smaller track sm and the larger track lg. This means that I have 4 lines with each name.

In this situation, we can then use the name as an index. So to place an item starting at the second line named sm and stretching to the third line named lg I use grid-column: sm 2 / lg 3. If you use the name without a number that will always resolve to the first line with that name.

See the Pen Grid Lines: naming lines by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Grid Lines: naming lines by Rachel Andrew (@rachelandrew) on CodePen.

Using The span Keyword

There are situations where you know that you want an item to span a certain number of tracks, however, you don’t know exactly where it will sit on the grid. An example would be where you are placing items using auto-placement, but want them to span multiple tracks rather than the default 1. In this case, you can use the span keyword. In the example below, my item starts on line auto, this is the line where auto-placement would put it, and it then spans 3 tracks.

.item {
  grid-column: auto / span 3;

See the Pen Grid Lines: span keyword by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Grid Lines: span keyword by Rachel Andrew (@rachelandrew) on CodePen.

This technique will become very useful once we have wide support of the subgrid value for grid-template-columns and grid-template-rows. For example, in a card layout where the cards have a header and main content area in which you want to align with each other, you can cause each card to span 2 rows, while still allowing for the usual auto-placement behavior. The individual cards will use subgrid for their rows (i.e. getting two rows each). You can see this in the below example if you use Firefox, and read my article CSS Grid Level 2: Here Comes Subgrid to learn more about subgrid.

See the Pen Grid Lines: span keyword and subgrid by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Grid Lines: span keyword and subgrid by Rachel Andrew (@rachelandrew) on CodePen.


A grid of cards with the Firefox Grid Inspector showing they each sit over two rows of the grid
The example in Firefox using the Grid Inspector

Layering Items With Line-Based Placement

Grid will auto-place items into empty cells on the grid, it won’t stack items into the same cell. However, by using line-based placement you can put items into the same grid cell. In this next example, I have an image that spans two-row tracks, and a caption which is placed in the second track and given a semi-transparent background.

See the Pen Grid Lines: card with layered elements by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Grid Lines: card with layered elements by Rachel Andrew (@rachelandrew) on CodePen.

Items will stack up in the order that they appear in the document source. So in the above example, the caption comes after the image and therefore displays on top of the image. If the caption had come first then it would end up displaying behind the image and we wouldn’t be able to see it. You can control this stacking by using the z-index property. If it was important for the caption to be first in the source, then you can use z-index, with a higher value for the caption than the image. This would force the caption to display on top of the image so that it can be read.

Mixing Line-Based And Auto-Placement

You need to take a little extra care if you are mixing placed items with auto-placed ones. When items are fully auto-placed in grid, they will place themselves sequentially onto the grid, each finding the next available empty space to put themselves into.

See the Pen Grid Lines: auto-placement by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Grid Lines: auto-placement by Rachel Andrew (@rachelandrew) on CodePen.

The default behavior is always to progress forwards, and to leave a gap if an item does not fit on the grid. You can control this behavior by using the property grid-auto-flow with a value of dense. In this case, if there is an item that fits a gap already left in the grid, it will be placed out of source order in order to fill the gap. In the example below using dense packing, item 3 is now placed before item 2.

See the Pen Grid Lines: auto-placement and dense packing by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Grid Lines: auto-placement and dense packing by Rachel Andrew (@rachelandrew) on CodePen.

Note that this behavior can cause problems for users who are tabbing through the document as the visual layout will be out of sync with the source order that they are following.

Auto-placement works slightly differently if you have already placed some items. The placed items will be positioned first, and auto-placement will then look for the first available gap to start placing items. If you have left some whitespace at the top of your layout by way of an empty grid row, then introduce some items which are auto-placed, they will end up in that track.

To demonstrate in this final example I have placed with the line-based positioning properties, items 1 and 2 leaving the first row empty. Later items have moved up to fill the gaps.

See the Pen Grid Lines: auto-placement mixed with placed items by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Grid Lines: auto-placement mixed with placed items by Rachel Andrew (@rachelandrew) on CodePen.

This behavior is worth understanding, as it can mean that items end up in strange places if you introduce some new elements to your layout which haven’t been given a placement on the grid.

Wrapping Up

That is pretty much all you need to know about grid lines. Remember that you always have numbered lines, no matter how else you are using grid you can always place an item from one line number to another. The other methods we will look at in future articles are alternate ways to specify your layout, but are based on the grid created by numbered lines.

Smashing Editorial(il)


When writing code for the web, eventually you’ll need to do some process that might take a few moments to complete. JavaScript can’t really multitask, so we’ll need a way to handle those long-running processes.

Async/Await is a way to handle this type of time-based sequencing. It’s especially great for when you need to make some sort of network request and then work with the resulting data. Let’s dig in!

Promise? Promise.

Async/Await is a type of Promise. Promises in JavaScript are objects that can have multiple states (kind of like the real-life ones ☺️). Promises do this because sometimes what we ask for isn’t available immediately, and we’ll need to be able to detect what state it is in.

Consider someone asks you to promise to do something for them, like help them move. There is the initial state, where they have asked. But you haven’t fulfilled your promise to them until you show up and help them move. If you cancel your plans, you rejected the promise.

Similarly, the three possible states for a promise in JavaScript are:

  • pending: when you first call a promise and it’s unknown what it will return.
  • fulfilled: meaning that the operation completed successfully
  • rejected: the operation failed

Here’s an example of a promise in these states:

Here is the fulfilled state. We store a promise called getSomeTacos, passing in the resolve and reject parameters. We tell the promise it is resolved, and that allows us to then console log two more times.

const getSomeTacos = new Promise((resolve, reject) => {
  console.log("Initial state: Excuse me can I have some tacos");

  .then(() => {
    console.log("Order some tacos");
  .then(() => {
    console.log("Here are your tacos");
  .catch(err => {
    console.error("Nope! No tacos for you.");
> Initial state: Excuse me can I have some tacos
> Order some tacos
> Here are your tacos

See the Pen

Promise States
by Sarah Drasner (@sdras)

on CodePen.

If we choose the rejected state, we’ll do the same function but reject it this time. Now what will be printed to the console is the Initial State and the catch error:

const getSomeTacos = new Promise((resolve, reject) => {
  console.log("Initial state: Excuse me can I have some tacos");

  .then(() => {
    console.log("Order some tacos");
  .then(() => {
    console.log("Here are your tacos");
  .catch(err => {
    console.error("Nope! No tacos for you.");
> Initial state: Excuse me can I have some tacos
> Nope! No tacos for you.

And when we select the pending state, we’ll simply console.log what we stored, getSomeTacos. This will print out a pending state because that’s the state the promise is in when we logged it!

> Initial state: Excuse me can I have some ?s
> Promise {}
> Order some ?s
> Here are your ?s

What then?

But here’s a part that was confusing to me at first. To get a value out of a promise, you have to use .then() or something that returns the resolution of your promise. This makes sense if you think about it, because you need to capture what it will eventually be — rather than what it initially is — because it will be in that pending state initially. That’s why we saw it print out Promise {} when we logged the promise above. Nothing had resolved yet at that point in the execution.

Async/Await is really syntactic sugar on top of those promises you just saw. Here’s a small example of how I might use it along with a promise to schedule multiple executions.

async function tacos() {
  return await Promise.resolve("Now and then I get to eat delicious tacos!")


Or a more in-depth example:

// this is the function we want to schedule. it's a promise.
const addOne = (x) => {
  return new Promise(resolve => {
    setTimeout(() => { 
      console.log(`I added one! Now it's ${x   1}.`)
    }, 2000);

// we will immediately log the first one, 
// then the addOne promise will run, taking 2 seconds
// then the final console.log will fire
async function addAsync() {
  console.log('I have 10')
  await addOne(10)
  console.log(`Now I'm done!`)

> I have 10
> I added one! Now it's 11.
> Now I'm done!

See the Pen

Async Example 1
by Sarah Drasner (@sdras)

on CodePen.

One thing (a)waits for another

One common use of Async/Await is to use it to chain multiple asynchronous calls. Here, we’ll fetch some JSON that we’ll use to pass into our next fetch call to figure out what type of thing we want to fetch from the second API. In our case, we want to access some programming jokes, but we first need to find out from a different API what type of quote we want.

The first JSON file looks like this- we want the type of quote to be random:

  "type": "random"

The second API will return something that looks like this, given that random query parameter we just got:

  "en":"For all its power, the computer is a harsh taskmaster. Its programs must be correct, and what we wish to say must be said accurately in every detail.",
  "author":"Alan Perlis",

We call the async function then let it wait to go retrieve the first .json file before it fetches data from the API. Once that happens, we can do something with that response, like add it to our page.

async function getQuote() {
  // get the type of quote from one fetch call, everything else waits for this to finish
  let quoteTypeResponse = await fetch(`https://s3-us-west-2.amazonaws.com/s.cdpn.io/28963/quotes.json`)
  let quoteType = await quoteTypeResponse.json()

    // use what we got from the first call in the second call to an API, everything else waits for this to finish
  let quoteResponse = await fetch("https://programming-quotes-api.herokuapp.com/quotes/"   quoteType.type)
  let quote = await quoteResponse.json()

  // finish up

We can even simplify this using template literals and arrow functions:

async function getQuote() {
  // get the type of quote from one fetch call, everything else waits for this to finish
  let quoteType = await fetch(`quotes.json`).then(res => res.json())

    // use what we got from the first call in the second call to an API, everything else waits for this to finish
  let quote = await fetch(`programming-quotes.com/${quoteType.type}`).then(res => res.json())

  // finish up


Here is an animated explanation of this process.

See the Pen

Animated Description of Async Await
by Sarah Drasner (@sdras)

on CodePen.

Try, Catch, Finally

Eventually we’ll want to add error states to this process. We have handy try, catch, and finally blocks for this.

try {
  // I’ll try to execute some code for you
catch(error) {
  // I’ll handle any errors in that process
finally {
  // I’ll fire either way

Let’s restructure the code above to use this syntax and catch any errors.

async function getQuote() {
  try {
    // get the type of quote from one fetch call, everything else waits for this to finish
    let quoteType = await fetch(`quotes.json`).then(res => res.json())

      // use what we got from the first call in the second call to an API, everything else waits for this to finish
    let quote = await fetch(`programming-quotes.com/${quoteType.type}`).then(res => res.json())

    // finish up

  catch(error) {
    console.warn(`We have an error here: ${error}`)


We didn’t use finally here because we don’t always need it. It is a block that will always fire whether it is successful or fails. Consider using finally any time you’re duplicating things in both try and catch. I usually use this for some cleanup. I wrote an article about this, if you’re curious to know more.

You might eventually want more sophisticated error handling, such as a way to cancel an async function. There is, unfortunately, no way to do this natively, but thankfully, Kyle Simpson created a library called CAF that can help.

Further Reading

It’s common for explanations of Async/Await to begin with callbacks, then promises, and use those explanations to frame Async/Await. Since Async/Await is well-supported these days, we didn’t walk through all of these steps. It’s still pretty good background, especially if you need to maintain older codebases. Here are some of my favorite resources out there:


About The Author

Rachel Andrew is not only Editor in Chief of Smashing Magazine, but also a web developer, writer and speaker. She is the author of a number of books, including …
More about

In a new series, Rachel Andrew breaks down the CSS Grid Layout specification. This time, we take a detailed look at what happens when you create a grid container and the various properties that can be applied to the container to shape your grid.

This is the start of a new series here at Smashing Magazine concentrating on CSS Grid Layout. While Grid has been available in browsers since 2017, many developers won’t have had a chance to use it on a project yet. There seem to be a lot of new properties and values associated with CSS Grid Layout. This can make it seem overwhelming. However, quite a lot of the specification details alternate ways to do things, meaning that you don’t have to learn the entire spec to get started. This series aims to take you from grid novice to expert — with lots of practical usage tips along the way.

This initial article will cover what happens when you create a grid container and the various properties that you can use on the parent element to control that grid. You will discover that there are several use cases that are fulfilled only with the properties that you apply to the grid container.

In this article, we will cover:

  • Creating a grid container with display: grid or display: inline-grid,
  • Setting up columns and rows with grid-template-columns and grid-template-rows,
  • Controlling the size of implicit tracks with grid-auto-columns and grid-auto-rows.

Overflow And Data Loss In CSS

CSS is designed to keep your content readable. Let’s explore situations in which you might encounter overflow in your web designs and how CSS has evolved to create better ways to manage and design around unknown amounts of content. Read article →

Creating A Grid Container

Grid, like Flexbox, is a value of the CSS display property. Therefore to tell the browser that you want to use grid layout you use display: grid. Having done this, the browser will give you a block-level box on the element with display: grid and any direct children will start to participate in a grid formatting context. This means they behave like grid items, rather than normal block and inline elements.

However, you may not immediately see a difference on your page. As you haven’t created any rows or columns, you have a one-column grid. Enough rows are being generated to hold all of your direct children, and they are displaying one after the other in that single column. Visually they look just like block elements.

You will see a difference if you had any string of text, not wrapped in an element, and a direct child of the grid container, as the string will be wrapped in an anonymous element and become a grid item. Any element which is normally an inline element, such as a span, will also become a grid item once its parent is a grid container.

The example below has two block-level elements, plus a string of text with a span in the middle of the string. We end up with five grid items:

  • The two div elements,
  • The string of text before the span,
  • The span,
  • The string of text after the span.

See the Pen Grid Container: Direct children and strings of text become grid items by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Grid Container: Direct children and strings of text become grid items by Rachel Andrew (@rachelandrew) on CodePen.

If you inspect the grid using the Firefox Grid Inspector, you can see the five-row tracks that have been created for the items.

A single column grid with five rows
The Grid Inspector is useful to help you see how many rows have been created

You can also create an inline grid by using display: inline-grid; in this case, your grid container becomes an inline-level box. However, the direct children are still grid items and behave in the same way as grid items inside a block-level box (it is only the outer display type). That is why the grid container behaves the way it does above when it is alongside other boxes on the page.

This next example has a grid followed by a string of text, as this is an inline-level grid, the text can display alongside it. Inline-level things do not stretch to take up all the space in the inline dimension in that way that block-level things do.

See the Pen Grid Container: inline-grid by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Grid Container: inline-grid by Rachel Andrew (@rachelandrew) on CodePen.

Note: In the future, we will be able to better describe our layout by using display: block grid in order to create our block-level container, and display: inline grid to create an inline-level container. You can read about this change to the display specification in my article, “Digging Into The DIsplay Property: The Two Values Of Display”.

Columns And Rows

To get something that looks like a grid, we will need to add columns and rows. These are created using the grid-template-columns and grid-template-rows properties. These properties are defined in the spec as accepting a value called a track-list.

These properties specify, as a space-separated track list, the line names and track sizing functions of the grid. The grid-template-columns property specifies the track list for the grid’s columns, while grid-template-rows specifies the track list for the grid’s rows.

Some valid track-list values are as follows:

grid-template-columns: 100px 100px 200px; Creates a three-column grid: The first column is 100px, the second 100px, the third 200px.
grid-template-columns: min-content max-content fit-content(10em) Creates a three-column grid: The first column is the min-content size for that track, the second the max-content size. The third is either max-content unless the content is larger than 10em, in which case it is clamped to 10em.
grid-template-columns: 1fr 1fr 1fr; Creates a three-column grid using the fr unit. The available space in the grid container is divided into three and shared between the three columns.
grid-template-columns: repeat(2, 10em 1fr); Creates a four-column grid with a repeating pattern of 10em 1fr 10em 1fr as the track-list in the repeat statement is repeated twice.
grid-template-columns: repeat(auto-fill, 200px); Fills the container with as many 200px columns as will fit leaving a gap at the end if there is spare space.
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); Fills the container with as many 200px columns as will fit then distributes the remaining space equally between the created columns.
grid-template-columns: [full-start] 1fr [content-start] 3fr [content-end] 1fr [full-end]; Creates a three-column grid: The first and third columns have 1 part each of the available space while the middle column has 3 parts. The lines are named by putting line names in square brackets.

As you can see there are many ways to create a track listing! Let’s have a look at exactly how these all work, with a few tips in terms of why you might use each one.

Using Length Units

You can use any length units, or a percentage to create your tracks. If the size of the tracks adds up to less than is available in the grid container, then by default the tracks will line up at the start of the container and the spare space will go to the end. This is because the default value of align-content and justify-content is start. You can space out the grid tracks, or move them to the end of the container using the alignment properties, which I explain in detail in my article “How To Align Things In CSS”.

See the Pen Grid Container: length units by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Grid Container: length units by Rachel Andrew (@rachelandrew) on CodePen.

You can also use the keywords min-content, max-content and fit-content(). Using min-content will give you a track that is as small as it can be without causing overflow. Therefore, when used as a column size, the content will softly wrap wherever possible. The track becoming the size of the longest word in the column or largest fixed-size element.

Using max-content will cause the content to not do any soft-wrapping at all. In a column, any string of text will unwrap which may cause overflow.

The fit-content keyword can only be used by passing in a value. That value becomes the max that this track will grow to. Therefore, the track will act like max-content with the content unwrapping and stretching out until it hits the value you passed in. At that point, it will start wrapping as normal. So your track may be smaller than the value you pass in, but never larger.

See the Pen Grid Container: min-content, max-content, fit-content() by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Grid Container: min-content, max-content, fit-content() by Rachel Andrew (@rachelandrew) on CodePen.

You can find out more about sizing in Grid and other layout methods in my article “How Big Is That Box? Understanding Sizing In CSS Layout”.

If you end up with tracks that take up more space than you have in your container, they will overflow. If you use percentages then, as with percentage-based float or flex layouts, you will need to take care that the total percentage is not more than 100% if you want to avoid overflow.

The fr Unit

Grid Layout includes a method that can save you calculating percentages for yourself — track sizing with the fr unit. This unit isn’t a length, and therefore can’t be combined with calc(); it is a flex unit and represents the available space in the grid container.

This means that with a track-list of 1fr 1fr 1fr; the available space is divided into three and shared evenly between the tracks. With a track-list of 2fr 1fr 1fr, the available space is divided into four and two parts are given to track one — one part each to tracks two and three.

See the Pen Grid Container: fr by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Grid Container: fr by Rachel Andrew (@rachelandrew) on CodePen.

Something to watch out for is that what is being shared out by default is available space which is not the total space in the container. If any of your tracks contain a fixed-size element or a long word that can’t be wrapped, this will be laid out before the space is shared out.

In the next example, I removed the spaces between the words of ItemThree. This made a long unbreakable string so space distribution happens after the layout of that item has been accounted for.

See the Pen Grid Container: fr with larger content by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Grid Container: fr with larger content by Rachel Andrew (@rachelandrew) on CodePen.

You can mix the fr unit with fixed length tracks, and this is where it becomes very useful. For example, you could have a component with two fixed-sized columns and a center area that stretches:

See the Pen Grid Container: mixing fr units and fixed-size tracks by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Grid Container: mixing fr units and fixed-size tracks by Rachel Andrew (@rachelandrew) on CodePen.

You can have a component with one track set to fit-content(300px) and the other to 1fr. This makes for a component that can have something smaller than 300px in the first track, in which case it only takes the space it needs and the fr unit expands to take up the rest of the space.

If you add something larger (such as an image with max-width: 100%), the first track will stop growing at 300px and the fr unit takes the rest of the space. Mixing the fr unit with fit-content is a way to make some very flexible components for your site.

See the Pen Grid Container: mixing fr and fit-content() by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Grid Container: mixing fr and fit-content() by Rachel Andrew (@rachelandrew) on CodePen.

The repeat() Function

Using repeat() in your track-list can save typing out the same value or values over and over again. For example the following two lines are the same:

grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
grid-template-columns: repeat(12, 1fr);

When using repeat() the value before the column is the number of times to repeat the track-list that comes after the comma. That track-list can be multiple values. This means you can repeat a pattern of tracks.

You can use the repeat() function for part of a track-list. For example, the following line would give you a 1fr track, 3 200px tracks, and a final 1fr track.

grid-template-columns: 1fr repeat(3,200px) 1fr

In addition to a number before the comma to indicate a fixed number of times to repeat the pattern, you can also use the keywords auto-fill or auto-fit. Using one of these keywords means that instead of a fixed number of tracks, your grid container will be filled with as many tracks as will fit.

See the Pen Grid Container: auto-fill by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Grid Container: auto-fill by Rachel Andrew (@rachelandrew) on CodePen.

Using a fixed-length unit means that, unless the container is able to be exactly divided by that size, you will end up with some spare space remaining. In the example above my container is 500px wide, so I get two 200px tracks plus space at the end.

We can use another grid function to make the value a minimum, with any spare space distributed across all of the tracks. The minmax() function takes a minimum and a maximum size. With a minimum of 200px and a max of 1fr, we get as many 200px tracks as will fit and because the max is 1fr, which we already know will share out the space evenly, the extra is distributed across the tracks.

See the Pen Grid Container: auto-fill and minmax() by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Grid Container: auto-fill and minmax() by Rachel Andrew (@rachelandrew) on CodePen.

I mentioned there are two possible keywords: auto-fill and auto-fit. If you have enough content to fill the first row of cells, then these will behave in exactly the same way. If, however, you do not (e.g. if we remove all but one item inside the container above), then they behave differently.

Using auto-fill will maintain the available track sizing even if there is no content to go into it.

See the Pen Grid Container: auto-fill and minmax() with one item by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Grid Container: auto-fill and minmax() with one item by Rachel Andrew (@rachelandrew) on CodePen.

If, instead, you use auto-fit, the empty tracks will be collapsed:

See the Pen Grid Container: auto-fit and minmax() with one item by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Grid Container: auto-fit and minmax() with one item by Rachel Andrew (@rachelandrew) on CodePen.

By using the Firefox Grid Inspector, you can see that the tracks are still there, but have been collapsed to zero. The end line of our grid is still line 3 as we can fit two tracks.

A single grid item fills the container, the grid inspector highlights the column lines
The track is still there but collapsed

Named Lines

My final example above used the named lines approach. When using Grid. you always have line numbers, however, you can also name the lines. Lines are named inside square brackets. You can have multiple names for one line; in that case, a space separates them. For example, in the following track-list, all of my lines have two names.

grid-template-columns: [main-start sidebar-start] 1fr [sidebar-end content-start] 4fr [content-end main-end]

You can name your lines anything that you like, except the word span as that is a reserved word due to being used when placing items on the grid.

Note: In the next article in this series, I’ll be talking more about line-based placement and how named lines are used. In the meantime, read my article on “Naming Things in CSS Grid Layout” to help you learn more on the topic.

The Explicit vs The Implicit Grid

When creating a grid using grid-template-columns and grid-template-rows with a track-list, you are creating what is referred to as the explicit grid. This is the grid you have defined which has the sizing you have chosen for each track.

If you have more items than will fit, or place an item so it falls outside of the bounds of the grid you have created, Grid will create tracks in the implicit grid. These implicit tracks will be auto-sized by default. We saw this implicit grid in action when I declared display: grid on the parent element and grid created rows, one for each item. I didn’t define these rows, but as there were grid items, the row tracks were created to give them somewhere to go.

You can set a size for implicit rows or columns by using the grid-auto-rows or grid-auto-columns properties. These properties take a track-listing, so if you want all implicit columns to be at least 200 pixels tall but grow if there is more content, you could use the following:

grid-auto-rows: minmax(200px, auto)

If you want the first implicit row to be auto-sized, and the second to be min-content sized, and so on (until all of the grid items have been accommodated), you can pass in multiple values:

grid-auto-rows: auto 100px

See the Pen Grid Container: grid-auto-rows by Rachel Andrew (@rachelandrew) on CodePen.

See the Pen Grid Container: grid-auto-rows by Rachel Andrew (@rachelandrew) on CodePen.

Using A Grid With Auto-Placement

Creating a grid (and allowing the browser to auto-place items) gets you a long way in terms of the useful patterns you can achieve. We have not yet looked at placing items on the grid, but many layouts that make use of Grid don’t do any placement. They simply rely on placing the items in source order — one in each grid cell.

If you are new to CSS Grid, then playing with different track sizes and seeing how the items place themselves into the cells you create is a great way to start.

Smashing Editorial(il)


It’s time to change a lot of the dialogue we have in the design industry. It’s time for us to start thinking about the impact our designs have on the world. We’ve spent far too long thinking about how cool something is. Meanwhile, the products we’ve made have changed how elections work, shifted the workforce in multiple industries, raised depression to an all-time high, created safe spaces for hate and vitriol, and have had a significant impact on our natural environment.

“All this, and yet I’m embarrassed to say that I’ve had exceedingly few conversations with designers in which we try to understand our impact on the world.”

For me, the impact of design started to become clear a few years ago when I was introduced to a six-layer framework for how a healthy society functions, by futurist Stewart Brand. It’s helped me understand the context of the work I’m doing in product design and even how different types of design can have different types of impact. I’ll first explain Brand’s framework, called Pace Layering, and then we’ll look at how it applies to design.

Brand proposes that there are six layers to society that can be laid out in concentric circles spinning in orbit around each other:

1. Fashion

2. Commerce

3. Infrastructure

4. Governance

5. Culture

6. Nature

Illustration by Daina Lightfoot

The outside levels spin the fastest and therefore gain the most attention — they’re easy to talk about and understand. Fashion moves fast and changes often. Fashion grabs your attention, but for most people does not provide a huge depth of meaning. Note that Fashion is also always referencing itself. As you move further down to more central circles, they become harder to put words to and take much longer to affect, but provide a great deal of impact on other levels above them.

All six layers operate at different paces, which is a good thing. If Governance were to change at the same speed as Fashion, you can imagine the rapidly changing laws would not have a positive effect.

On a purely philosophical level, the Pace Layering framework helps me understand why I really enjoy things like Fashion, but have a deep connection with Nature that often transcends words and deeply affects me.

How to apply Pace Layering to design

Now that we understand the core framework, let’s apply it to design — in this case, product design; although, I think it could be applied to other disciplines. The goal of applying Pace Layering to design isn’t to provide concrete answers as much as to give you a new way to understand the impact of the work you’re doing.

I’ve mapped some design disciplines to the same framework, expanding it to nine levels:

1. Designing visuals

2. Designing interactions

3. Designing flows

4. Designing whole features or sections of a product

5. Designing apps/products

6. Designing teams

7. Designing businesses

8. Designing society

9. Designing nature

These layers follow a similar dynamic as Brand’s Pace Layers. Visuals and Interaction are on the outer layers — they spin quickly, change often, and grab a lot of attention. For me, this explains why design community platforms like Dribbble are so popular. Dribbble highlights visual and interaction design, but also explains why so many designers dialogue about how many of those designs don’t solve real problems. It also explains why many designers stop using Dribbble as they grow in their careers — their work becomes more complicated and harder to communicate in something so reduced as a quick visual.

Design on the middle layers is much more complicated and less trendy. When done well, it is established, researched, and full of nuance. While it may be easy to change the colours or illustrations in an app, changing a whole flow, or even re-architecting an entire app will take substantially longer. And likewise, while Visuals may have some emotional impact, a new feature in an app may cause a much deeper effect in a person’s life. In my experience, these middle layers are better communicated with something like a good case study. A case study allows us to explain the rationale behind the decisions, the hard work it took to implement them, and the impact of those decisions.

As we move to the deepest layers, things move even more slowly. Here, the conversations are definitely not as trendy, but their impact can be huge. If you are working on building a team, it may take a year or two. If you are building financial tools that give more access to low-income populations, you may have to wait decades to see your work come to fruition. It simply may not be possible for them to move any faster, and yet the depth of their impact is inarguable.

Conversely, you can use this framework to understand why certain digital platforms have been at the centre of controversy. The leading ride-sharing apps used product design to change transportation on a large scale across the globe. These companies move much faster than local governments, and the tension between those layers is palpable. Likewise, some social networks have used product design to collect information and distribute media in a way that has many governments scrambling. Airbnb has used product design to change how people travel. And the change has happened so quickly that it has disrupted what it means to be a local, all around the world.

You can argue about what companies that create products should or shouldn’t be doing, but you can’t argue that they haven’t had an outsized impact on our global society — at a record pace. The impact we have as product designers on those outer layers has never been bigger.

Everything is design

I’ve intentionally used the term “designing” in all of these levels. Our design community often focuses on defining design as a craft, and can have a very limited definition of what those terms mean. That obsession with craft keeps pushing designers toward easy-to-talk-about disciplines that sit on the outer rings and in the process negates disciplines in the inner rings. In fact, I’ve seen many designers refer to some of these transitions as “not designing anymore.” What this means for our careers is a whole other article. But suffice it to say, because product design now has more impact than ever before, we also have a huge new world of job opportunities — jobs that require a much larger level of responsibility.

“I have a huge place in my designer heart for a well-crafted… anything. But honestly, I think we spend very little time thinking about the impact of that craft.”

For my part, I understand the argument that maybe levels six-nine are “not designing anymore,” but until someone gives me a better definition, I’m going to continue pointing out that we use a lot of the same skills, even if we create different artefacts. Even more importantly, I feel like the more designers and design thinking we can incorporate into those deeper levels, the more impact we’ll have on our society. I’d hate to limit those career paths by telling designers that they aren’t a designer if they choose to work on gnarly societal-level design problems.

Transitioning from craft to impact

There’s a funny thing that happens in many design careers. We start on the outer layers and find a lot of joy, and even identity in the craft of design. And we spend years building those skills. I have a huge place in my designer heart for a well-crafted… anything. But honestly, I think we spend very little time thinking about the impact of that craft. It can be a craft for craft’s sake.

But not to be overly negative, I see a lot of designers who continue to expand their craft and simultaneously build their muscle for impact. And then a strange thing happens. At some point, many of us are forced to let go of one of the outer layers in order to keep scaling our impact on the world — for no other reason than we are humans, and we only have so much capacity. We look at the deeper layers and they seem to provide a lot of meaning, but we’ve found our identity (and social affirmation) in the outer layers, and it’s just hard to let them go.

“In the past handful of years, we’ve begun creating products that are used by millions or even billions of people.”

In my experience, I’ve seen the pain of this transition reflected in a lot of people’s career growth, mine included. I think we’re afraid to let go of things like visual design, so we don’t have the mental capacity to think about how to design for this type of impact. But when we let go — when we look to scale our impact in this way — we can start to see just how much power we have as designers. Digital products — specifically, the huge distribution opportunities that have arisen from the internet and app stores — have given us more scale than just about any projects in human history. In just the past handful of years, we’ve begun creating products that are used by millions or even billions of people. Our ability to affect huge-scale change is something we can no longer ignore.

Moving into these more central rings comes with huge responsibility and requires an even larger skillset. It requires new tools and new ways to talk about our projects. We are forced into much more abstract conversations that have a much wider but perhaps less direct impact.

Do I go wide or deep?

This decision to go wide or deep is another one of our great conundrums in design. And it is one of the biggest areas of choice that we have. I really don’t think there is a right or wrong answer here, and I definitely wouldn’t value one decision over the other.

Some designers will choose to spend most of their time in one of the rings. That may be on the outside or on the inside, but they are specializing in a specific discipline (for example, typography, systems design, design ethics, etc). Others will choose to grow into multiple rings, and will likely become specialized in connecting multiple disciplines. We often call these generalists. They have a wide purview, but simply don’t have the time to be exceptionally deep in any one area (eg., product design, design management, CEO, etc.).

The tools for different layers

As we move from layer to layer, our tools likely need to change. On the outer layers, our tools may be Sketch, Principle, Adobe XD, or even dev tools like XCode. As we move to the middle layers, we may start using more tools to communicate how all our designs fit together like Marvel, design systems, a slide deck, and even the *gasp* meeting. We can use Abstract to pull our organization together to work more effectively. And as we move into the inner layers, we may use a lot of those same tools, but we probably shift toward using more things like analytics tools, and headcount planning sheets, and even learning how to use board meetings to accomplish design tasks.

Similar to tools, we also have to change the people we work with as we move to deeper and deeper layers. In the outer layers, we’re probably working directly with other designers who “get the craft” and maybe a few others. But as we move deeper and deeper, the number of different people we work with generally increases greatly (see earlier comment about our limited capacity), and many of them are not designers. In order to have a great impact, we must work with a wide variety of disciplines, many of which don’t understand design at all. Because of this, the ability to understand and represent the value of design to a wide group of people becomes an invaluable tool.

Our social responsibility

Lastly, if we understand that we, as product designers, have a massive potential impact on this world, we must realize that we also have an exponentially larger responsibility than any other time in history.

But what does that mean? It’s easy for us to look at another company, one that has done something we think harms our society, and scream from the rooftops that they’ve got it all wrong. But that’s simply not helpful.

In my experience, most (but not all) of the companies that we think are doing something harmful have really well-intentioned employees. But I’d argue that they are perhaps working at one layer without realizing that their work is having an impact at a different layer. First, we need to be honest with ourselves about the actual impact our designs have on the world. Second, we may need to change how we work.

4 ways to take more responsibility in design

1. Research how people use your product and how it affects their lives.

Many products have unintended consequences. Look at outside metrics that affect your company — like happiness or screen addiction. Don’t become overwhelmed by how daunting the task may sound. Start by listening. Really listen to people — not just what you want to hear.

If you don’t have a lot of resources for research, lean on the research that already exists. For example, one of my new projects has a social component. I don’t need to talk to 400 people to deeply understand what seeing “like” counts does to people’s emotional state. Lots of research has been done on this topic. I read it and made adjustments accordingly.

2. If your product can sway people’s opinion, be honest with yourself about that.

Figure out what role your company has in forming public opinion. This issue is fraught with challenges and you better have good answers. If you can’t take on that responsibility, work on something else. Sometimes there’s simply not a good universal answer for how to regulate something (just look at the controversy regarding political ads on social media and the different approaches that Twitter and Facebook have taken). If there’s no good answer, then maybe don’t get into that topic. Sometimes safer is better for our society. Understanding the impact of your work should come before action.

3. If your platform allows strangers to talk to each other, understand what could go wrong.

Get feedback from people who have experienced hate and discrimination and consider limiting channels for vitriol (comments, DMs, etc.), even if it hurts engagement numbers.

4. Think about whether your product impacts the environment.

Does your product consume a lot of energy? If it asks people to do things in the real world, consider how they interact with their environment. Ask what would happen if your product became wildly successful. An example here may be understanding that your food delivery app has real emissions consequences for our world, so being efficient with routes, or even delivering on bikes, could make a large impact. The larger the organization you work for, the more impact your work will have on the environment.

“The impact we have as designers is expanding to include much more than how things make people feel.”

Where do we go from here?

The impact we have as designers is expanding to include much more than how things make people feel. In this world where our products are used by millions, the problems we are tasked with solving are rarely simple. I hope we can have a broader understanding of how big the design world is, how various design disciplines connect to each other, and what their impact is.

Ultimately, we have way more power than we realize and I’d love for us to think about the type and depth of impact we have on this world. I hope this framework highlights that we actually have a lot more flexibility in the type of work we do and the type of impact we have.

Originally posted on Abstract by Joshua Taylor.


I was at JSConf China earlier this year, which happened in Shanghai from 19–20 Oct. There was fairly decent representation from Singapore I would say.

Wei (whom I probably mention every second blog post I write) was the opening keynote for Day 2, and it was one of the best if not THE best talk of the conference IMHO.

Wei on stage at JSConf China

We also had Yong Jun (another good friend of mine), who gave a workshop on the rather interesting topic of scrolly-telling. He works in the graphics department for Singapore Press Holdings and has lots of experience creating interactive graphics and visualisations.

Yong Jun running workshop at JSConf China

Yong Jun had developed an open-source scrolly-telling library that he used for a lot of his projects and it uses position: sticky for “snapping” content into place.

During the workshop, he posed the question of why just applying position: sticky alone on an element doesn’t work. And this gave me the idea to do another CSS property deep dive ?.

CSS is a team sport

CSS layout is not just one individual CSS property or even module. Everything on the web is a box. And the layout of these boxes are determined the following:

  • box dimensions and type
  • positioning scheme (normal flow, float, and absolute positioning)
  • relationships between elements in the document tree
  • external information (e.g., viewport size, intrinsic dimensions of images, etc.)

From this bit of information alone, we can pick out the following CSS modules (including those in draft status):

The point I’m making here is, if you’d like to be fully equipped to build any layout you can imagine with CSS, I suggest understanding these different CSS modules and how they interact with each other. It definitely helped me out when I did so.

In all fairness, I really dug into all of it when I was preparing for my CSS Day talk back in 2018, which was pretty much 45 minutes about boxes. All talk details on Notist.

Positioning schemes

After boxes are generated, the way they are laid out depends on which positioning scheme they fall into:

  • Normal flow
  • Floats
  • Absolute positioning

Boxies in normal flow

Normal flow is the default, where boxes are laid out one after another, and will not overlap or intrude into each others’ space. All boxes will be on the same stacking context as well.

Boxies with a floated friend

Boxes that are floated are considered out-of-flow. When a box is floated, it is first laid out according to normal flow, but then is taken out the flow and shifted as far to the left or right as possible (depending on the float value).

Content will then flow along the side of the floated box. But the floated boxes still remain on the same stacking context as the non-floated ones.

Boxies with an absolutely positioned friend

An absolutely positioned box is completely removed from normal flow altogether, and its position is assigned with respect to its containing block.

The positioning algorithms used to calculate the position of a box on the page is determined by the position and float properties. I’ll try my best to explain this in a way that makes sense. But first, let’s look at them individually.

The position property

There are several values for this property, with sticky being added in Level 3 of the Positioned Layout Module, and currently supported in most major browsers even though it is still in a working draft status.

position: static

The default position value of any box. This results in the box being laid out in normal flow and the properties of top, bottom, left and right (also known as box offset values) will have no effect because the box is considered not positioned.

Default layout of unpositioned boxes

position: relative

Applying a position of relative to a box makes it positioned, and now the top, bottom, left and right values will have some effect.

The box will initially be laid out according to normal flow, then depending on the aforementioned box offset values, will be offset relative to its normal position.

Relatively positioned box with top and left offsets

If there are other non-positioned boxes next to this positioned box, they will not be affected even if offset values are present. This means there may be the possibility of overlap.

Also, if the offset causes the box to have overflow, this may result in scrolling, which would affect layout. When a box becomes relatively positioned, it becomes the new containing block for its children.

position: sticky

A sticky positioned box works similarly to that of a relatively positioned box. The difference is that the offset is computed to the nearest ancestor with a scrolling box, or the viewport if none such ancestor exists.

This ties in to Yong Jun’s original question of why applying position: sticky alone on a box is insufficient to achieve the sticky effect. The box, without any offsets, behaves as though it was in normal flow, because it is.

Only when the offset values are something other than auto will the box start to behave differently from a relatively positioned box. The wording in the specification comes across slightly cryptic to me, but my understanding is that there is an intersection between the sticky box and its containing box when you apply a box offset value.

Initial position of sticky positioned box

This intersection is called a sticky-constraint rectangle and is used to contain the location of the sticky box. The specification uses the term “projects above/below/outside” but I’m not sure if my understanding is the same as what the specification authors intended.

Position of sticky positioned box after scrolling takes place

What I do know is that when you define an offset value, the offset will never push the sticky box outside its containing block, but the sticky box is free to move within the containing block as the page is scrolled, hence the perception of it being pinned to the relevant edges.

position: absolute

An absolutely positioned box is explicitly offset with respect to its containing block, and the box does not participate in the normal flow at all. Its later siblings will not know about its existence in the greater layout.

Position of absolutely positioned box

Contents of an absolutely positioned box do not flow around any other boxes and may overlap other boxes, and depending on the stack level of the boxes, content may be obscured by the overlap.

position: fixed

A fixed position box behaves similarly to an absolutely positioned box. The key distinction is that the containing block is always the viewport.

Position of fixed positioned box

Box offset values

Traditionally, the box offset values most developers are familiar with are top, bottom, left and right. And I don’t think it’s a generalisation to say that most developers from the West don’t give a second thought to writing modes that are anything other than horizontal top-to-bottom.

But when you use a writing mode that is right-to-left, for example, or vertical writing, then these physical values of top, bottom, left and right make less sense. For example, the top of your content may not be the physical top of the browser viewport.

As someone who grew up exposed to writing systems in different directions from the Western default, this was not hard for me to wrap my head around, but that may not be the case for many folks from the West.

Naming is always hard, especially when it does not exactly correlate with real life / usage expectations / metaphors. At least the terms used are consistent with other CSS properties. You need to know how block and inline behave and have some imagination.

— Ecaterina Moraru (@evalica) November 7, 2019

This is why I appreciate it when influential folks in our industry start talking about these lesser known aspects of web development, especially on the internationalisation side of things, because they have a wider reach and can help something considered obscure become more mainstream.

Logical box offset values

Because the specification is still in Editor’s Draft status, the syntax may change moving forward. Even now, the current browser implementation is different from what is in the specification, so be sure to double-check with MDN: CSS Logical Properties and Values on the most updated syntax.

The matrix of writing directions and their corresponding values for a box’s physical sides and logical sides are as follows (the table has been lifted from the specification as of time of writing):

writing-mode / direction
horizontal-tb vertical-rl vertical-lr
ltr rtl ltr rtl ltr rtl



inset-before inset-before inset-start inset-end inset-start inset-end


inset-end inset-start inset-before inset-before inset-after inset-after


inset-after inset-after inset-end inset-start inset-end inset-start


inset-start inset-end inset-after inset-after inset-before inset-before

The logical top of a container uses inset-before, while the logical bottom of a container uses inset-after. The logical left of a container uses inset-start, while the logical right of a container uses inset-end.

This is probably easier to visualise with a diagram (or live code if your browser supports it). The following is for horizontal-tb:

Mapping for horizontal-tb

Logical box offset values for horizontal-tb with ltrLogical box offset values for horizontal-tb with rtl

The following is for vertical-rl:

Mapping for vertical-rl

Logical box offset values for vertical-rl with ltrLogical box offset values for vertical-rl with ltr

The following is for vertical-lr:

Mapping for vertical-lr

Logical box offset values for vertical-lr with ltrLogical box offset values for vertical-lr with ltr

Wrapping up

I suggest opening this CodePen in a full browser window and playing around with the examples and CSS values to get a feel of how everything fits together (or you could select the 0.5x option in the embed).

See the Pen
Understanding CSS positioning
by Chen Hui Jing (@huijing)
on CodePen.

There are plenty of useful resources that cover CSS positioning, so if my explanation doesn’t work for you, try someone else’s article or the specification directly. It is definitely worth the effort in the long run to figure out this important aspect of CSS layout for yourself.



CSS units have been the subject of several articles here on SitePoint (such as A Look at Length Units in CSS, The New CSS3 Relative Font Sizing Units, and The Power of em Units in CSS). In this article, we increase the count by having an in-depth look at rem units, which have excellent browser support and a polyfill if you need support for old IE.

This article was updated in December, 2019 to reflect the current state of rem unit sizing with CSS. For more on CSS font and text properties, read our book, CSS Master, 2nd Edition.

What Are rem Units?

You might have encountered the term “R.E.M.” before while listening to the radio or your music player. Unlike their musical counterparts, named for the “Rapid Eye Movement” during deep sleep, in CSS rem stands for “root em”. They won’t make you lose your religion nor believe in a man on the moon. What they can do is help you achieve a harmonious and balanced design.

According to the W3C spec the definition for one rem unit is:

Equal to the computed value of font-size on the root element. When specified on the font-size property of the root element, the rem units refer to the property’s initial value.

This means that 1rem equals the font size of the html element (which for most browsers has a default value of 16px).

Rem Units vs. Em Units

The main problem with em units is that they are relative to the font size of their own element. As such they can cascade and cause unexpected results. Let’s consider the following example, where we want lists to have a font size of 12px, in the case where the root font size is the default 16px:

html {
font-size: 100%;

ul {
font-size: 0.75em;

If we have a list nested inside another list, the font size of the inner list will be 75% of the size of its parent (in this case 9px). We can still overcome this problem by using something along these lines:

ul ul {
font-size: 1em;

This does the trick, however we still have to pay a lot of attention to situations where nesting gets even deeper.

With rem units, things are a simpler:

html {
font-size: 100%;

ul {
font-size: 0.75rem;

As all the sizes are referenced from the root font size, there is no more need to cover the nesting cases in separate declarations.

Font Sizing with Rem Units

One of the pioneers of using rem units for font sizing is Jonathan Snook with his Font sizing with REM article, back in May, 2011. Like many other CSS developers, he had to face the problems that em units bring in complex layouts.

At that time, older versions of IE still had large market shares and they were unable to zoom text that was sized with pixels. However, as we saw earlier, it is very easy to lose track of nesting and get unexpected results with em units.

The main issue with using rem for font sizing is that the values are somewhat difficult to use. Let’s see an example of some common font sizes expressed in rem units, assuming, of course, that the base size is 16px:

  • 10px = 0.625rem
  • 12px = 0.75rem
  • 14px = 0.875rem
  • 16px = 1rem (base)
  • 18px = 1.125rem
  • 20px = 1.25rem
  • 24px = 1.5rem
  • 30px = 1.875rem
  • 32px = 2rem

As we can see, these values are not very convenient for making calculations. For this reason, Snook used a trick called “62.5%“. It was not a new discovery, by any means, as it was already used with em units:

body { font-size:62.5%; } /* =10px */
h1 { font-size: 2.4em; } /* =24px */
p { font-size: 1.4em; } /* =14px */
li { font-size: 1.4em; } /* =14px? */

As rem units are relative to the root element, Snook’s variant of the solution becomes:

html { font-size: 62.5%; } /* =10px */
body { font-size: 1.4rem; } /* =14px */
h1 { font-size: 2.4rem; } /* =24px */

One also had to take into account the other browsers that didn’t support rem. Thus the code from above would have actually been written this way:

html {
font-size: 62.5%;

body {
font-size: 14px;
font-size: 1.4rem;

h1 {
font-size: 24px;
font-size: 2.4rem;

While this solution seems to be close to the status of a “golden rule”, there are people who advise against using it blindingly. Harry Roberts writes his own take on the use of rem units. In his opinion, while the 62.5% solution makes calculation easier (as the font sizes in px are 10 times their rem values), it ends up forcing developers to explicitly rewrite all the font sizes in their website.

A third view comes from Chris Coyier of CSS-Tricks. His solution makes use of all three units we encountered so far. He keeps the root size defined in px, modules defined with rem units, and elements inside modules sized with em. This approach makes easier to manipulate global size, which scales the type in the modules, while the module content is scaled based on the module font size itself. Louis Lazaris discussed that latter concept in The Power of em Units in CSS.

In the example below you can see how Chris’s approach would look:

See the Pen One Method for Using ems and rems in CSS by SitePoint (@SitePoint) on CodePen.

In practice, there are major frameworks such as Bootstrap 4 and the Material Design guidelines that use rem units for sizing text content.

A special mention goes to Material-UI, a very popular collection of React components. Not only are they sizing text the same way, but also offer a mechanism to implement the “10px simplification” we mentioned above.

Another recent project, Every Layout, combines em and rem units in a very inspired way. It comes closest to Chris Coyier’s model outline earlier and it uses em units to emphasize inline elements like SVG icons, spans or other similar elements.

As you can see, there is no “silver bullet” solution. The combinations possible are limited only by the imagination of the developers.

The use of em or rem units inside media queries is closely related to the notion of “optimal line length” and how it influences the reading experience. In September 2014, Smashing Magazine published a comprehensive study on web typography called Size Matters: Balancing Line Length And Font Size In Responsive Web Design. Among many other interesting things, the articles gives an estimate for optimal line length: between 45 and 75-85 characters (including spaces and punctuation), with 65 the “ideal” target value.

Using a rough estimate of 1rem = 1character, we can control the flow of text for a single column of content, in a mobile-first approach:

.container {
width: 100%;

@media (min-width: 85rem) {
.container {
width: 65rem;

There is, however, one interesting detail about rem and em units when used as units for media queries: they always keep the same value of 1rem = 1em = browser-set font size. The reason for this behavior is explained in the media query spec (emphasis added):

Relative units in media queries are based on the initial value, which means that units are never based on results of declarations. For example, in HTML, the em unit is relative to the initial value of font-size, defined by the user agent or the user’s preferences, not any styling on the page.

Let’s see a quick example of this behavior:

View Media Query Demo on CodePen

First, in our HTML, we have a element where we will write the width of the viewport:

Document width: px

Next we have two media queries, one with rem units and the other with em units (this uses Sass for simplicity):

html {
font-size: 62.5%; /* 62.5% of 16px = 10px */

@media (min-width: 20rem) {
/* 20*16px = 320px */
background-color: lemonchiffon;
font-size: 200%;
/* 200% of 16px = 32px */

@media (min-width: 30em) {
/* 30*16px = 480px */
background-color: lightblue;
font-size: 300%; /* 300% of 16px = 48px */

Finally, we use a bit of jQuery to display the viewport width on the page, updating the value when the window size changes:


$(window).on('resize', function(e) {

We begin with the 62.5% trick to show that the modified root font size does not have any effect on the values used for the media queries. As we change the width of the browser window we can see that the first media query kicks in at 320px (20 × 16px) while the second one becomes active at 480px (30 × 16px). None of the font-size changes we declared had any effect on the breakpoints. The only way to change the media query breakpoint values is to modify the default font size in the browser settings.

For this reason, it doesn’t really matter if we use em or rem units for media query breakpoints. Zurb Foundation (currently at v6.5.3 at the moment this was written) makes use of em units in the media queries.

The Quest for Accessibility

We’ve seen above that the ability to scale based on the root font size makes rem units very useful for accessibility. Google developers make the recommendation to use relative units for text sizing.

There is an empirical study run by the people behind the Internet Archive showing that there is a significant amount of users who change their default font size in the browser settings. By using rem and other relative units you respect the users’ decisions about the way they want to browse the web.

Using rem Units for Scaling Documents

A third use we can find for rem units is to build scalable components. By expressing widths, margins, and padding in rem units, it becomes possible to create an interface that grows or shrinks in tune with the root font size. Let’s see how this thing works using a couple of examples.

Using rem Units for Scaling Documents Demo #1

In this first example, we change the root font size using media queries. Just like in the previous section, the purpose is to customize the reading experience for the device used. As element padding values and margins are expressed using rem, the entire component scales with the device size.

Let’s see another:

See the Pen Dynamic Sizing of Modules with Rem Units by SitePoint (@SitePoint) on CodePen.

In the second example we do the same alteration using JavaScript. This time the user has control over the size of the interface, adjusting it to fit his needs. Add a way to store these custom values (using either a database, cookies or local storage) and you have the base of a personalization system based on user preferences.


We end here our encounter with CSS rem units. It is obvious that there are many advantages in using these units in our code, like responsiveness, scalability, improved reading experience, and greater flexibility in defining components. Rem units not a universal silver bullet solution but, with careful deployment, they can solve many problems that have irked developers for years. It’s up to each one of us to unlock the full potential of rems. Start your editors, experiment and share your results with the rest of us.

Make the most of your text by understanding what more you could do with text CSS values. In our screencast AtoZ CSS: Text and Typography, we’ll explore text properties, font properties, and more.

It’s not The End of the World as We Know It, rather it’s yet another path on the journey that makes front-end developers “Shiny Happy People“.

Adrian is a front-end developer and UX enthusiast based in Dublin, Ireland. He’s focused on CSS architecture, responsive web design and website performance. He believes in giving back to the community, being involved in running three local meetups and he started speaking at international events. In the off time, he loves playing video games and tinker with custom PC builds.


The proportion for Golden Ratio is 1:1.618. It is a mathematical equation that has found its way into design practices as well. The golden ratio has been scientifically proven beautiful. The best example to understand the importance of the Golden Ratio can be traced back to one of the most famous paintings: the Mona Lisa.  The painting itself uses the golden ratio.

Some other names for Golden Ratio are The Golden Section, Golden Mean, or the German letter “phi”. It is a useful number that helps create beautiful designs. The way Golden Ratio differs from other design practices is that design generally is led by instinct and creativity. Whereas the Golden Ratio has a different approach. It uses mathematical approaches to transform your images, layouts, typography and many more design practices.

The Fibonacci sequence:

This sequence is the sum of two numbers before it. Greeks tossed this practice. It used to help them form a visual pattern to help with their design. After you’re done, turn the sequence into squares and put them side by side and you’ll create a spiral of rectangles. This is known as the Golden Spiral. What’s amazing is that though this is a mathematical equation, there are a lot of natural instances that show the presence of this concept in their structure as well. Natural calamities, flowers and even shells, everything has a hint of the golden ratio. A Fibonacci sequence would look like 1, 1,2,3,5,8,13, 21.

Golden Ratio in Graphic Design:

Golden Ratio adds structure to design, which otherwise has an expressive nature.  An easy hack of applying the golden ratio to any element is multiplying the size of the element by 1.618 for figuring out the size of another element or overlay the Golden Spiral for adjusting their placement.  The golden ratio can be used for typography, images and much more.

1.Using Golden Ratio for Typography:

Understanding the Golden Ratio in Design- Typography

Typography refers to the art or technique of arranging type for making the written language legible, readable and appealing when displayed. Adding hierarchy in your layout adds structure and flow to your design. You can use typography for wedding invitation or also for website layout. At first glance, it might not be possible to imagine any correlation between typography and mathematics. However, typography is a blend of letter forms and mathematical proportions.

Three factors are crucial to typography; font size, line width and line-height.  All these aspects need to be in proportion to each other.  By achieving proportion in these three elements, the content you want to put forth would be very appealing to your readers on websites, or even blogs. By tweaking the font size and the content width, you can get an understanding of what the font height should be.  A 70-80 CPL-Characters Per Line, is considered comfortable for reading. If the content is too lengthy, the readers would lose out on the natural flow and find it challenging to find the start of the next line.

Golden Ratio can also be of help to have a guide for typography sizes.  If you breakdown a three-line text by importance in three sections named A, B and C you’d be able to understand the golden ratio a whole lot better. Suppose C is the least important piece of information you have, and you use the size 10 px for its content. If you need to figure out what size of the text to use for more critical text B multiply the font size of C by 1.618.

2. Adding to the Image Structure:

Understanding the Golden Ratio in Design- Adding Image Structure

Photographers always have a guiding principle that they use when they click photographs. There are many guiding principles in photography that helps photographers better frame their picture.  One such guideline or rule is known as The Rule of Thirds. The rule of thirds essentially is dividing a composition into 9 equal parts, by dividing the frame with two equidistant vertical and horizontal lines. The points where these lines intersect are known as intersection points. The idea of using the rule of one third is that the subject should be placed on the intersection points in a way that the subject only takes up 1/3rd of the frame. This can also be done in post-editing using grid lines. Another such guideline is the Golden Ratio.

Golden Ratio works best when you are trying to create a perfect sense of harmony in your images. Now unlike the rule of thirds, using golden ratio when clicking could be a little trickier, especially when you’re new to the concept. Hence using the Golden Spiral in post-production is one of the best ways to go around it.  Overlay the spiral on top of your image. This would help you see which elements of the picture sit where and if they’re creating harmony together. It also allows you to identify focal points and where they need to be. It can also be used to understand which elements need to be moved for giving the design more energy.

3. For creating Logo Design:

Design- creating logo designs- logos

Logos are one of the most critical aspects of business identity. It helps new potential customers identify your brand, and old customers to retain your services and products through your logo. A brand logo helps create the first impression of the business’ values and relevance to its audience.  It is the first interaction anyone has with a brand as logos are more visual than texts. This is why it is very important to have a great logo that delivers what the brand stands for at its core in a single glance.

One good practice for creating spectacular logo designs is using the Golden Ratio. Using the Golden Ratio for designing logos help people instantly connect to the brand. An excellent example of this would be how many famous brands like Twitter, Apple, even Pepsi have been using it to design their logo.

You can also make use of the Fibonacci’s Sequence to create logos. Initially, start by creating a circular sequence using the Fibonacci’s Sequence and then rearrange them for forming a grid that would work as the basic framework for your logo design.

4. Golden Ratio and Architecture:

Using Golden Ratio- Architecture

Architecture refers to the art of creating designs for buildings and constructing them as well. Ancient Greek architecture has been using the Golden Ratio to create its beautiful monuments. These monuments always seem to have dimensional relationships between their width and height.  The entire building gives a sense of being in perfect proportion. Famous polymath Leonardo da Vinci himself has used the golden ratio to create some appealing compositions in his times. Even the most famous painting The Last Supper the characters are arranged in the lower two-thirds of the golden ratio. Also, the position of Jesus is perfectly placed by arranging golden rectangles throughout the canvas.

Taj Mahal is known to be one of the Seven Wonders of the World. It also used Golden Ratio for its design. The central building of the Taj Mahal was designed using the Golden Ratio. The rectangles helped create the basic outline for the exteriors of the building, which were all in the Golden Proportion.

Using the golden ratio in architecture helps bring a sense of balance and height to the structure.  Any building that seems well balanced naturally draws attention towards it. One of the most simple manners to reflect balance in a building is by using the Golden rectangle principles.  Another advantage of using the Golden Ratio is it allows you to create various shapes. You don’t need to stick to box-shaped or rectangular structures. The golden ratio uses those shapes as a base to guide your design. Still, you can easily incorporate various other shapes. You need to make a few changes to the golden rectangle to turn the building into any shape you desire.  A few derivatives that architects usually use are the Golden Triangle and a Logarithmic Spiral.

5. Designing and Creating  Layouts:

Designing and Creating Layouts- Desgin- Website Design- Website Layout

Layouts are the system arrangement of various elements on a page that usually refers to a specific placement on text, image and the style. It is essential to understand layouts because a wrongly worked layout would lead to inaccurate delivery of the message you want to convey. A good layout is essential to convey the message effectively. Not only this but a proper layout would help enhance the look of a particular object individually and also as a whole. Hence for successful layouts, the two criteria that need to be kept in mind are individual visual elements and their relationship.

There are many layout options available to designers.  One of them is the “Z” layout which takes inspiration from the letter “Z” itself. It generally shows the path that a reader sees the elements on a page or a design.  Another layout principle is the Golden Ratio. Golden Spiral works best when you have many elements that might differ from each other to be arranged in a single layout. It is seen that people are naturally drawn to the centre of the spiral when witnessing a golden spiral. This gives us the insight to place the most important element in the centre of the spiral

6. The presence of Golden Ratio in Human Face:

Human-Face-Golden Ratio

Front face: It is interesting how prevalent the golden ratio is. For understanding its relevance, it is important to realize that even our faces draw from the concept of the golden ratio. The head makes a golden rectangle, and our eyes become the central point. The nose and the mouth are both situated at the right sections of the distance of the chin and eyes.

Side Face: If you look at a human head from the side, it illustrates the Divine Proportion. The first golden section that is at the front of the head defines the ear opening position. Then successive golden sections define different parts of the face, like the neck, the back of the eye, and front of the eye guiding back to the nose and mouth.

The human face has several instances of the divine proportion.  The centre of the pupil is proportional to the bottom of the teeth and bottom of the chin. The outer and inner edge of the eye is proportionate to the centre of the nose. Our outer edge of lips complements the outer ridges of lips.  The width of the iris is proportional to the width of the iris.

Understanding the Golden Ratio can be very helpful for design practices. It is a mathematical approach to design that stands out from other design practices. It is prevalent in many aspects of life naturally as well. Since it is naturally available in so many instances, we tend to appreciate any design that uses its principles many times without even realizing it.  Just remember the constant ratio 1:1.618 and keep using it in different instances and places.

100 HD Blurred Backgrounds


One of the great things about paid search is the fact that you can track everything. If someone visits your store after seeing your billboard or TV spot, there’s no real way to trace that. 

However, if someone sees your paid search ad and visits your website, you know how they got to your site. You know which ad they saw, what copy they responded to and even what search term triggered your ad.

There’s so much data that it can be hard to figure out what it all means or what to do with it. Impression counts, clickthrough rates, cost-per-click…how do you sort through it all and use your paid search metrics to make intelligent decisions?

I mean, what’s the point of having all of that data if you don’t know what to do with it?

To make matters worse, a lot of this data can be hard to properly interpret, so even experienced online marketers often draw the wrong conclusions from their data or focus on the wrong metrics in their accounts. So, if you’ve ever stared at your paid search account and wondered, “What am I missing?”, this article is for you.

Are you focused on the right paid search metrics?

If you’re like most online marketers, you probably have several campaigns running, at least a dozen ads and over a hundred keywords to keep track of. And that’s if your account is on the small side.

Every one of those campaigns, ads, ad groups and keywords can give you a wealth of information about your audience and how effective your advertising is…but only if you know how to use your data.

These days, paid search is so competitive that it isn’t enough to simply set up Google Analytics and keep an eye on your cost-per-click. You need to know how to interpret every aspect of your paid search data and use it to optimize the performance of your account.

Now, while that might sound like a daunting task, most of the information in your paid search account can be broken down into three manageable pieces: information about your traffic, information about conversions and information about sales.

Let’s take a look at each of these three types of data and how you can use them to interpret what’s happening in your paid search account.

What sort of traffic are you getting?

When it comes to paid search advertising, most marketers tend to focus on traffic-related metrics like impressions, cost-per-click (CPC) or click-through rate (CTR). After all, the main reason why you run paid search campaigns is to drive more traffic to your website.

And, not surprisingly, paid search platforms like Google Ads and Bing Ads are full of traffic-related information: device segmentation data, keyword info, impression share insights, and more. For Google and Bing, this info is incredibly easy to track and supply and it’s what most of their users are interested in.

What you can learn from traffic data

While all of this traffic data is certainly handy, it’s only useful if you know what to do with it. That being said, your traffic data tells you a lot about how well your campaigns are working for your target audience.

If no one is clicking on your ads, there’s a good chance that your ad copy needs some work…or you’re targeting the wrong keywords. If your cost-per-click is too high, you might need to rethink your bidding strategy. If you’re not getting enough impression share on your best campaigns, you probably need to consider shifting your budget around.

For example, say you’re running paid search ads for a local attorney. On average, this client makes $3,200 from a new client and spends about $1,200 taking care of them.

In your most recent review of your campaigns, you review your traffic data and put the following report together:

From the data above, it’s easy to see which campaign is generating the best results. Campaign #3 produces more clicks at a lower cost-per-click than any of your other campaigns. In contrast, while you spent over twice as much on campaign #4, you got one-third of the clicks you got from campaign #3.

Clearly, you either need to shut down campaign #4 and put its budget into a better campaign like #3 or invest some time into figuring out why campaign #4 is performing so poorly.

However, before you make any decisions, we should probably talk about the other two types of data in your account. After all, your attorney friend doesn’t make money from clicks. To make money, she needs leads…and none of this data tells you whether or not all of those clicks are actually turning into leads.

Is your traffic converting?

So, with that in mind, let’s talk about conversion data. Because Google and Bing often can’t tell what a conversion is for your website, it takes some extra work to set up conversion tracking for your site. And, as a result, almost half of paid search advertisers don’t track their campaigns beyond traffic data.

But here’s the thing, without conversion data, you can’t answer the following two critical questions about your paid search campaigns.

1. Is my website (or landing page) a good fit for my traffic?

Paid search marketing is intent-based marketing. When someone searches for something on Google or Bing and clicks on your ad, they’re actively looking for a solution to a problem…a problem they think your business can help them with.

Their click is an act of faith in your business and the page they land on after clicking shows them whether or not their faith was justified. If your landing page or website meets their expectations, a decent percentage of people should convert. If not, they’ll leave.

So, if your conversion rate is high, then your destination page is a good fit for your traffic. However, if your conversion rate is low, it means that something is off. Your landing page or site isn’t working for your traffic, so they’re leaving to find something better.

If you find yourself in the latter situation, you may want to take a hard look at the page you’re sending traffic to. You may need to rethink your page and site experience to bring it into closer alignment with the expectations of your traffic.

2. Is your traffic a good fit for your landing page?

Of course, the opposite might be true, too. If your landing page seems like it should be converting traffic, but it isn’t, your ads may be sending the wrong people to your page.

If people click on your ads because they want a divorce attorney, but you’re a personal injury firm, will they convert? The wrong traffic never converts, regardless of how good your site is.

In this situation, it’s often a good idea to look at the search terms people are using to find your ads and the actual ad copy that you’re using. If it seems like you’re attracting clicks from the wrong people, you may need to rework your advertising strategy to target the right audience.

What you can learn from conversion data

Once you have set up conversion tracking, look beyond traffic data and see how your campaigns did in terms of conversions.

Although it doesn’t have the best conversion rate (CR), campaign #3 gets enough cheap clicks that it still has the best cost-per-lead. And, as before, campaign #4 is still a lost cause. Between a low conversion rate and high cost-per-click, it’s producing leads at almost ten times the cost of a lead from campaign #3.

With an 8 percent conversion rate, it doesn’t seem like either of these campaigns are targeting the wrong traffic, but they could probably both benefit from a little conversion rate optimization on their destination pages.

However, while this data paints a clearer picture, your attorney friend still doesn’t make money off of leads. She needs to close new clients. To get at that information, we need to look at our sales data.

Are you making sales?

As helpful as traffic and conversion data are, they still don’t tell you whether or not your campaigns are making money. And, if your campaigns aren’t making money, why are you running them?

Unfortunately, tracking your paid search campaigns clear through to sales data can be tricky. E-commerce is pretty straightforward, but once you get beyond that, it can be hard to connect your actual sales data to your campaign performance. You often need some sort of CRM like Salesforce and you have to figure out how to connect all of the dots.

But is it worth it? Absolutely. Let’s take a look at what the sales data for our hypothetical law firm’s campaigns shows.

All of sudden, campaign #4 just went from zero to hero. It might not have a great CPC or conversion rate, but its return-on-ad-spend (ROAS) is almost twice the ROAS of any other campaign.

So what does this actually tell us? Well, for one thing, it’s clear that campaign #4 appeals to people who are much more likely to buy than the people in any of the other campaigns. Campaign #3 might drive a lot more traffic, but that traffic is far less likely to sign up for our attorney friend’s services.

Does this mean that campaign #3 is bad? With a ROAS of 92 percent, it’s certainly losing money right now, but it has a lot going for it on the traffic and data front. Before you can pass judgement on it, you’ll need to dive into that data and see if there is any way to turn all of that potential into actual sales.

Maybe you need to change your ad messaging to filter out people who aren’t likely to actually become a client. Maybe you could tweak the landing page to better appeal to potential clients. Maybe your attorney friend just needs some coaching on how to respond to leads from this campaign.

In any case, without this sales data, it would have been easy to assume that campaign #4 was a complete loss and campaign #3 deserved more of your budget – when, in fact, the opposite was actually true. This is why sales data is so important. Traffic and conversion data teach you useful things about your campaigns, but only sales data answers the question, “Are my ads actually making money?”


Your paid search account is full of valuable information, but turning all of that data into actionable information can sometimes seem overwhelming. The trick is making sure that you have access to all of the data that you need to make educated decisions and then knowing what each type of data tells you.

Now that you know how to interpret your data, all you have to do is start digging through your paid search metrics. Opportunities to improve your account should quickly become apparent. Good luck!

This story first appeared on Search Engine Land. For more on search marketing and SEO, click here.


Opinions expressed in this article are those of the guest author and not necessarily Marketing Land. Staff authors are listed here.

About The Author

Jacob is passionate entrepreneur on a mission to grow businesses using PPC & CRO. As the Founder & CEO of Disruptive Advertising, Jacob has developed an award-winning and world-class organization that has now helped over 2,000 businesses grow their online revenue. Connect with him on Twitter.


If there’s one thing I’ve learned over the 15 years working on Google Search, it’s that people’s curiosity is endless. We see billions of searches every day, and 15 percent of those queries are ones we haven’t seen before–so we’ve built ways to return results for queries we can’t anticipate.

When people like you or I come to Search, we aren’t always quite sure about the best way to formulate a query. We might not know the right words to use, or how to spell something, because often times, we come to Search looking to learn–we don’t necessarily have the knowledge to begin with. 

At its core, Search is about understanding language. It’s our job to figure out what you’re searching for and surface helpful information from the web, no matter how you spell or combine the words in your query. While we’ve continued to improve our language understanding capabilities over the years, we sometimes still don’t quite get it right, particularly with complex or conversational queries. In fact, that’s one of the reasons why people often use “keyword-ese,” typing strings of words that they think we’ll understand, but aren’t actually how they’d naturally ask a question. 

With the latest advancements from our research team in the science of language understanding–made possible by machine learning–we’re making a significant improvement to how we understand queries, representing the biggest leap forward in the past five years, and one of the biggest leaps forward in the history of Search. 

Applying BERT models to Search

Last year, we introduced and open-sourced a neural network-based technique for natural language processing (NLP) pre-training called Bidirectional Encoder Representations from Transformers, or as we call it–BERT, for short. This technology enables anyone to train their own state-of-the-art question answering system. 

This breakthrough was the result of Google research on transformers: models that process words in relation to all the other words in a sentence, rather than one-by-one in order. BERT models can therefore consider the full context of a word by looking at the words that come before and after it—particularly useful for understanding the intent behind search queries.

But it’s not just advancements in software that can make this possible: we needed new hardware too. Some of the models we can build with BERT are so complex that they push the limits of what we can do using traditional hardware, so for the first time we’re using the latest Cloud TPUs to serve search results and get you more relevant information quickly. 

Cracking your queries

So that’s a lot of technical details, but what does it all mean for you? Well, by applying BERT models to both ranking and featured snippets in Search, we’re able to do a much better job  helping you find useful information. In fact, when it comes to ranking results, BERT will help Search better understand one in 10 searches in the U.S. in English, and we’ll bring this to more languages and locales over time.

Particularly for longer, more conversational queries, or searches where prepositions like “for” and “to” matter a lot to the meaning, Search will be able to understand the context of the words in your query. You can search in a way that feels natural for you.

To launch these improvements, we did a lot of testing to ensure that the changes actually are more helpful. Here are some of the examples that showed up our evaluation process that demonstrate BERT’s ability to understand the intent behind your search.

Here’s a search for “2019 brazil traveler to usa need a visa.” The word “to” and its relationship to the other words in the query are particularly important to understanding the meaning. It’s about a Brazilian traveling to the U.S., and not the other way around. Previously, our algorithms wouldn’t understand the importance of this connection, and we returned results about U.S. citizens traveling to Brazil. With BERT, Search is able to grasp this nuance and know that the very common word “to” actually matters a lot here, and we can provide a much more relevant result for this query.


A reducer is a function that determines changes to an application’s state. It uses the action it receives to determine this change. We have tools, like Redux, that help manage an application’s state changes in a single store so that they behave consistently.

Why do we mention Redux when talking about reducers? Redux relies heavily on reducer functions that take the previous state and an action in order to execute the next state.

We’re going to focus squarely on reducers is in this post. Our goal is to get comfortable working with the reducer function so that we can see how it is used to update the state of an application — and ultimately understand the role they play in a state manager, like Redux.

What we mean by “state”

State changes are based on a user’s interaction, or even something like a network request. If the application’s state is managed by Redux, the changes happen inside a reducer function — this is the only place where state changes happen. The reducer function makes use of the initial state of the application and something called action, to determine what the new state will look like.

If we were in math class, we could say:

initial state   action = new state

In terms of an actual reducer function, that looks like this:

const contactReducer = (state = initialState, action) => {
  // Do something

Where do we get that initial state and action? Those are things we define.

The state parameter

The state parameter that gets passed to the reducer function has to be the current state of the application. In this case, we’re calling that our initialState because it will be the first (and current) state and nothing will precede it.

contactReducer(initialState, action)

Let’s say the initial state of our app is an empty list of contacts and our action is adding a new contact to the list.

const initialState = {
  contacts: []

That creates our initialState, which is equal to the state parameter we need for the reducer function.

The action parameter

An action is an object that contains two keys and their values. The state update that happens in the reducer is always dependent on the value of action.type. In this scenario, we are demonstrating what happens when the user tries to create a new contact. So, let’s define the action.type as NEW_CONTACT.

const action = {
  type: 'NEW_CONTACT',
  name: 'John Doe',
  location: 'Lagos Nigeria',
  email: '[email protected]'

There is typically a payload value that contains what the user is sending and would be used to update the state of the application. It is important to note that action.type is required, but action.payload is optional. Making use of payload brings a level of structure to how the action object looks like.

Updating state

The state is meant to be immutable, meaning it shouldn’t be changed directly. To create an updated state, we can make use of Object.assign or opt for the spread operator.


const contactReducer = (state, action) => {
  switch (action.type) {
    case 'NEW_CONTACT':
    return Object.assign({}, state, {
      contacts: [
      return state

In the above example, we made use of the Object.assign() to make sure that we do not change the state value directly. Instead, it allows us to return a new object which is filled with the state that is passed to it and the payload sent by the user.

To make use of Object.assign(), it is important that the first argument is an empty object. Passing the state as the first argument will cause it to be mutated, which is what we’re trying to avoid in order to keep things consistent.

The spread operator

The alternative to object.assign() is to make use of the spread operator, like so:

const contactReducer = (state, action) => {
  switch (action.type) {
    case 'NEW_CONTACT':
    return {
        ...state, contacts:
        [...state.contacts, action.payload]
      return state

This ensures that the incoming state stays intact as we append the new item to the bottom.

Working with a switch statement

Earlier, we noted that the update that happens depends on the value of action.type. The switch statement conditionally determines the kind of update we’re dealing with, based on the value of the action.type.

That means that a typical reducer will look like this:

const addContact = (state, action) => {
  switch (action.type) {
    case 'NEW_CONTACT':
    return {
        ...state, contacts:
        [...state.contacts, action.payload]
    case 'UPDATE_CONTACT':
      return {
        // Handle contact update
    case 'DELETE_CONTACT':
      return {
        // Handle contact delete
      return {
        // Handle contact list
      return state

It’s important that we return state our default for when the value of action.type specified in the action object does not match what we have in the reducer — say, if for some unknown reason, the action looks like this:

const action = {
  type: 'UPDATE_USER_AGE',
  payload: {
    age: 19

Since we don’t have this kind of action type, we’ll want to return what we have in the state (the current state of the application) instead. All that means is we’re unsure of what the user is trying to achieve at the moment.

Putting everything together

Here’s a simple example of how I implemented the reducer function in React.

See the Pen

reducer example
by Kingsley Silas Chijioke (@kinsomicrote)

on CodePen.

You can see that I didn’t make use of Redux, but this is very much the same way Redux uses reducers to store and update state changes. The primary state update happens in the reducer function, and the value it returns sets the updated state of the application.

Want to give it a try? You can extend the reducer function to allow the user to update the age of a contact. I’d like to see what you come up with in the comment section!

Understanding the role that reducers play in Redux should give you a better understanding of what happens underneath the hood. If you are interested in reading more about using reducers in Redux, it’s worth checking out the official documentation.