DEV Community

Cover image for CSS Grid Layout Template Areas (Secrets of Painless Layout)
crayoncode
crayoncode

Posted on

CSS Grid Layout Template Areas (Secrets of Painless Layout)

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:

Result

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

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.

<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>
Enter fullscreen mode Exit fullscreen mode

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)
.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);

}
Enter fullscreen mode Exit fullscreen mode

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.

.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;
}
Enter fullscreen mode Exit fullscreen mode

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.

.credit-card {
  ...

  grid-template-areas: "provider . . ."
    "number number number number"
    "good-through-label good-through-value . validity"
    "holder holder holder select";
}
Enter fullscreen mode Exit fullscreen mode

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.

.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;
  }
}
Enter fullscreen mode Exit fullscreen mode

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;

.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);
  }
Enter fullscreen mode Exit fullscreen mode

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

.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);
  }
}
Enter fullscreen mode Exit fullscreen mode

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:

.credit-card {
  ...

  > .select {    
    transition: box-shadow 250ms, transform 250ms;

    &:active {
      box-shadow: 0px 0px 4px 0px rgba(black, 0.2);
      transform: translate(-1px, -1px);
    }
  }
Enter fullscreen mode Exit fullscreen mode

Top comments (0)