CSS Grid Layout Template Areas (Secrets of Painless Layout)
Tags: tutorial, css, webdev, ui
Published: 2021-01-10 10:01:36

Today let's start getting to know CSS grid layout and bring some ease to handling grid positions through named areas, so let's build a nice little credit card layout. 

Read the full article or watch me code this on Youtube:

{% youtube MZbX914puc4 %}

## Result

{% codepen https://codepen.io/crayon-code/pen/qBayQLx %} 

## Getting started with CSS grid layout

If you take a look at your credit card or search for images of it, you'll notice that there is certain information being placed in specific spots. So the layout does not follow a specific flow of text, but is rather explicitly / absolutely positioned. Finally, with CSS Grid Layout we have something at hand which makes tasks like this so much easier.

Remember those times where tables were used to setup the layout of a web page? If you're lucky you don't as it was anything else but fun. CSS Grid Layout is here to make up for it. It works kind of similar, as it divides a container into a grid of rows and columns. The child elements of the container then can be assigned to specific cells of that grid and can also span multiple adjacent cells. 
 
![grid-layout](https://dev-to-uploads.s3.amazonaws.com/i/5k69tplo5rvu1e9vqvin.png) 

## Markup

So for the basic markup, there's a wrapping `div.credit-card` which is going to be the grid layout container. The nested children contain the information like credit card number, card holder, date of validity, etc.

```html
<div class="credit-card">
  <div class="provider"><i class="fab fa-cc-visa"></i></div>
  <div class="number">xxxx xxxx xxxx xx80</div>
  <div class="good-through-label">good<br/>through</div>
  <div class="good-through-value">09/24</div>
  <div class="holder">Jane Doe</div>
  <a class="select" href="#">Select</a>
  <div class="validity">valid</div>
</div>
```

## Basic Styling

Let's first apply some styling to the container by e.g.

- Putting a font that looks similar to the embossed letters on a credit card
- Rounding the corners
- Adding glassmorphism via the `backdrop-filter` property (Webkit-based browsers only at the moment)

```css
.credit-card {
  font-family: 'Share Tech Mono', monospace;
  color: white;
  border: 1px solid rgba(white, 0.2);
  border-radius: 0.5rem;

  box-shadow: 0px 0px 8px 2px rgba(black, 0.2);
  padding: 1rem;
  
  // glassmorphism FTW
  backdrop-filter: blur(4px);
  background: rgba(white, 0.2);
  
}
```

## Grid Layout Setup

So let's get into the basic setup of the grid layout. Most importantly `display: grid;` enables the grid layout itself. 

Via `grid-template-rows|columns` the number and proportions of the rows and columns can be defined. In our case we want 4 equally sized columns that add up to the entire vertical/horizontal space available. And instead of writing `1fr 1fr 1fr 1fr` we simply use the `repeat(count, dimension)` function.

Through `grid-column|row-gap` we can define the spacing between all rows and columns. And this is also where the `fr` unit comes into play. We could have also used `25%` when sizing the rows and columns. But as soon as you do so, the gaps make the entire container grow as it is put _on top_ of the 25%. `fr` is a so called _fraction_ of the available space and takes the gaps correctly into account. So each row / column takes an equal fraction of the available space _after_ the gaps have been deducted from it.

```css
.credit-card {
  ...
  
  display: grid;
  grid-template-rows: repeat(4, 1fr);
  grid-row-gap: 0.5rem;
  grid-template-columns: repeat(4, 1fr);
  grid-column-gap: 0.35rem;
}
```

## Defining named areas

In order to position items in the grid, it is necessary to assign them to cells. Each cell has a row and a column number identifying its position in the grid. However, this can become quite tedious and not very robust towards changes in the layout. This is where `grid-template-areas` help a great deal. `grid-template-areas` allows us to assign cells an area name. It is also possible to assign multiple adjacents cells the same area name.

So in the first line of the grid only the `provider` is given, the rest of the cells do not belong any named area which is indicated by the dots.

In the second line the `number` takes all four cells, which is why that identifier is repeated multiple times each separated by a space.

```css
.credit-card {
  ...
  
  grid-template-areas: "provider . . ."
    "number number number number"
    "good-through-label good-through-value . validity"
    "holder holder holder select";
}
```

## Using the named areas

Now each child simply gets its area name assigned and is automatically spanned across the cells that belong to that area. As simple as that.

> __Heads up:__ There are no quotes around the grid area names.

```css
.credit-card {
  ...

  > .provider {
    grid-area: provider;
  }
  
  > .number {
    grid-area: number;
  }
  
  > .good-through-label {
    grid-area: good-through-label;
    
    font-family: 'Lato', sans-serif;
    text-transform: uppercase;
    font-size: 0.65rem;
  }
  
  > .good-through-value {
    grid-area: good-through-value;
  }
  
  > .holder {
    grid-area: holder;
  }
  
  > .select {
    grid-area: select;
  }

  > .validity {
    grid-area: validity;
  }
}
```

## Making it pretty

Now let's also make it pretty by giving the validity indicator a happy green color and a slight shine with a gradient running from transparent black to a 20% white. An additional box-shadow makes it also stand out a little more. The text is centered both horiztonally and vertically using flexbox in conjunction with `justify-content: center;` and `align-items: center;`

```css
.credit-card {
  ...

  > .validity {
    color: white;
    border: 1px solid #44a333;
    font-size: 1rem;
    font-weight: 400;
    background: #57c443 linear-gradient(45deg, rgba(black, 0) 0%, rgba(white, 0.25) 100%);
    
    display: flex;
    justify-content: center;
    align-items: center;
    
    box-shadow: 2px 3px 6px 0px rgba(black, 0.5);
  }
```

Almost the same goes for the select button, except for the color (it's going to be blue) and the font (no serifs):

```css
.credit-card {
  ...

  > .select {
    background: #2ca7d8 linear-gradient(45deg, rgba(black, 0) 0%, rgba(white, 0.25) 100%);
    border: 1px solid #1482ce;
    color: white;
    font-family: 'Lato';
    font-size: 1rem;
    text-decoration: none;
    
    display: flex;
    justify-content: center;
    align-items: center;
    
    box-shadow: 2px 3px 6px 0px rgba(black, 0.5);
  }
}
```

## Making it playful

And finally let's add a playful vibe to the select button, by making the `box-shadow` and `transform` properties transitionable. So each time the user clicks the button, the box shadow is lowered and the button shifted 1px each left and upwards in order to provide a _push_ effect:

```css
.credit-card {
  ...

  > .select {    
    transition: box-shadow 250ms, transform 250ms;
    
    &:active {
      box-shadow: 0px 0px 4px 0px rgba(black, 0.2);
      transform: translate(-1px, -1px);
    }
  }
```