Introduction to CSS Grid: What You Should Know

Introduction to CSS Grid: What You Should Know

<strong>Introduction to CSS Grid. CSS Grid is the most powerful layout system available in CSS. It brings a two-dimensional layout tool to the web, with the ability to place items in rows and columns.</strong>

Introduction to CSS Grid. CSS Grid is the most powerful layout system available in CSS. It brings a two-dimensional layout tool to the web, with the ability to place items in rows and columns.

I first heard about CSS Grid towards the end of 2016. I was sitting at one of my first Tech Ladies meetings and an attendee mentioned hearing how amazing it was. Fast forward a year and a half later and I’m finally digging deeper into Grid. As a devoted Flexbox user, I can already tell how this will be a game changer.

The biggest question I had when beginning to learn about CSS Grid was: how is Grid different than Flexbox? And I found out that in general, Grid can do everything that Flexbox can do. Some people are of the mindset that Grid is for multi-dimensional layouts while Flexbox should be used for one-dimensional layouts. But Grid is great at one-dimensional layouts as well — especially if you come back later and decide that you want to make that layout multi-dimensional.

Setting Up CSS Grid

Grid is extremely easy to setup — all it takes is two lines of CSS.


<div class=”wrapper”>
  <div class=”item”>1</div>
  <div class=”item”>2</div>
  <div class=”item”>3</div>
  <div class=”item”>4</div>
  <div class=”item”>5</div>
  <div class=”item”>6</div>


.wrapper {
    display: grid;
    grid-template-columns: 10rem 10rem 10rem;

And voila! You have a grid. Seriously, that’s all you need. It’s pretty great.

You’ll notice that, unlike when setting Flexbox to display: flex, adding display: grid to your wrapper doesn’t immediately make a difference. This is because you aren’t explicitly defining how many columns you want your grid to have. You’ll do this with grid-template-columns like I did above. So in this example, I’m setting three columns to have a width of 10rem each.

You can use any value you want when setting grid-template-columns, but I suggest staying away from percentages unless you’re trying to add up to 100%. This is because you will have to take your amount of grid-gap (which we’ll dive into in a little bit) into account, and that can get a little tricky.

Explicit vs Implicit Tracks

Before I talk about explicit and implicit tracks, let’s first talk about what tracks are. Tracks are the space between two grid lines, either horizontal or vertical. Instead of counting the individual columns and rows by themselves, in CSS Grid you count them by the track lines. Here’s the grid we started with — I’ve numbered all of the track rows and columns to make it a little easier for you to see.

You can see that we actually have four column lines and three row lines. This will help when placing your items on the grid.

A quick side note: if you’re using Firefox it actually has some great dev tools for seeing the column and row track numbers. If you inspect your wrapper element and then go to the layout tab, check the box for your wrapper and now your grid will look like below! I really hope Chrome adds an inspect feature like this in the future. It’s extremely helpful.

Let’s go back to the difference between explicit and implicit tracks. If we take our code from above, you’ll notice that we’ve only set our columns. In this case, we’ve explicitly set our columns to have three, but we’ve implicitly set our rows. We have six items, but obviously, all of these items cannot fit in three columns so a second row gets implicitly set.

This is a little confusing, so I definitely recommend messing around with CSS Grid on your own to see the difference between explicit and implicit tracks.

Adding Grid-Gap

Think of grid gap like margin except it’ll only be added between items and not to the outside of the grid. I’ve run into so many cases when I add margin on items in a Flexbox grid only to have to go to the grid’s wrapper and set the same amount of margin, but negative, to offset the margin that gets set outside of the grid. Thankfully with CSS Grid, you don’t have to deal with that.

Let’s take our example CSS above and add some grid-gap.

.wrapper {
  display: grid;
  grid-template-columns: 10rem 10rem 10rem;
  grid-gap: 1rem;

I used the shorthand property grid-gap, but you can define an explicit value for the columns and rows by using grid-column-gap and grid-row-gap.

Note: Chrome 66 will be changing *grid-gap* to *gap* and *grid-column-gap*/*grid-row-gap* to *column-gap*/*row-gap*.

The Repeat() Function

Defining how wide you want each of your columns to be when using grid-template-columns with three columns that are all the same width is pretty simple. But that’s a lot of typing if you want any more columns than that. This is where the repeat() function comes in.

Here’s our example we’ve been using with the repeat() function added in.

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 10rem);
  grid-gap: 1rem;

As you can see in my CSS, I’m setting three columns each to be 10rems wide. This grid will look exactly like the grid pictured in our grid-gap example. By using the repeat() function we’re just making writing things a little simpler and easier to read for when you’re wanting to set a lot of columns.

Fractional Units

Fractional units, or fr, are a new CSS length unit introduced with CSS Grid and one that I can see myself using all the time. Say we want three columns all of equal width. Instead of setting width: calc(100% / 3) on the items, we can use fractional units. Think of fractional units as “free space.”

Let’s continue on with our example that we’ve been using.

.wrapper {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-gap: 1rem;

You’ll notice that the only thing I changed was grid-template-columns. I’m now telling the browser that I want three columns, and that I want each of those columns to take up one fractional unit or one “free space.” This works very similarly to Flexbox’s flex-grow property.

The reason each item is a little wider than in our previous example is that they are now taking up as much space as they can while still fitting in three columns. In this case, I didn’t set a hard width so they are taking up the full-width of my viewport. I know this is a little hard to see without having it on your own screen, so I definitely recommend messing with this on your own.

You don’t have to set all of your columns to be 1fr, either. Below is an example where I’ve set my first and third column to 10rems while my middle column is 1fr. You can also set your columns to 2fr, 3fr, and so on, and that column’s items will take up 2x, 3x (and so on) the amount of space.

Sizing Individual Grid Items

Let’s talk about sizing our individual grid items. You cannot place a hard width on individual items, because we explicitly set the width with grid-template-columns. But what if you want item five in our example to be the width of multiple columns? We can do this using grid-column and span.

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 10rem);
  grid-gap: 1rem;

.item5 {
  grid-column: span 2;

You’ll see above that we’re setting grid-column of item five to be a span of two which will allow item five to span a width of two columns.

But what if you wanted item five to span three columns? This is what will happen.

Because item five naturally starts at the second column, we don’t have enough space for it to span the total width we’ve set. So it will move down to the next row. You can apply the same concept from grid-column to grid-row if you’re wanting an item to span multiple rows.

There’s a pretty simple solution for fixing the blank space that’s leftover from item five moving down a row. It can be used whether you’re setting an item to span a row or a column — grid-auto-flow: dense.

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 10rem);
  grid-gap: 1rem;
  grid-auto-flow: dense;

.item5 {
  grid-column: span 3;

In CSS Grid, the grid will automatically check to see if items fit. Like I said above if an item doesn’t fit it will break to the next line. Grid-auto-flow: dense tells the grid to fill in those empty spaces with any item that will fit. In this case, I’ve added a seventh grid item so the grid automatically moves that and the sixth item to the empty spots.

CSS Grid will always layout items that need to go in a specific spot first — in this case, item five, since it is spanning three columns. Then, if you have grid-auto-flow: dense set, it will look for other items to fit into the blank spots on the grid.

The grid-auto-flow property by itself determines in which direction you need to add another row or column after you’ve already defined your items. Row is the default. I haven’t see a big use case for this besides using grid-auto-flow: dense.

Placing Grid Items

In our example with sizing individual grid items, we were originally setting item five to grid-column: span 2, which allowed item five to span across two columns. Actually, grid-column is shorthand for grid-column-start and grid-column-end. The same goes for grid-row as well.

So, technically, we were setting item five to be grid-column-start: span 2 and grid-column-end: auto. Essentially, we were telling the grid to start item five where it naturally would, but go twice the size.

Let’s work with item five again, and I’m going to show you this using Firefox’s inspector tools so it’s easier for you to see what track line item five is at. I’ve also added a couple more grid items.

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 10rem);
  grid-gap: 1rem;

.item5 {
  grid-column-start: 1;
  grid-column-end: 3;

CSS Grid will layout all of the items before our fifth one, stop and then look at where we started and ended item five, and place it where we told it to. The shorthand of this would be grid-column: 1 / 3 where 1 is our start value and 3 is our ending value.

You can also tell an individual grid item how wide you want it to span and where you want it to end. I’m using the shorthand grid-column property in this example, so I’m telling item five to span two columns ending at track line four.

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 10rem);
  grid-gap: 1rem;

.item5 {
  grid-column: span 2 / 4;

If you want your item to span the entire width of the grid, but don’t know how wide your grid is, you can set grid-column: 1 / -1. Basically that -1 value is telling your item to go all the way across to the last track. If you do this with rows you’ll notice that your item may not go all the way to the bottom of your grid. It will only go to the bottom of your explicit rows, not your implicit rows.


Here are some resources I highly recommend for a deeper dive into CSS Grid!

  • Wes Bos’ CSS Grid Tutorial — it’s totally free and is where I learned about grid. I love his style of teaching!
  • CSS Tricks’ Complete Guide to CSS Grid — this has some great cheat sheets for when you’re stuck on a certain aspect of Grid.
  • CSS Grid Garden — a fun way to practice what you’ve learned about CSS Grid. I recommend doing a tutorial before attempting this as it gets a little confusing at times.

Thanks for reading my tutorial on CSS Grid! Be sure to follow me on Twitter for lots of tweets about tech and, if I’m being honest, lots of tweets about dogs too.

By : Kara Luton

Learn More

☞ The Web Developer Bootcamp

☞ Build Responsive Real World Websites with HTML5 and CSS3

☞ Web Design for Beginners: Real World Coding in HTML & CSS

☞ Beginner Full Stack Web Development: HTML, CSS, React & Node

☞ The Complete HTML & CSS Course - From Novice To Professional

☞ The Ultimate HTML Developer

☞ CSS - The Complete Guide (incl. Flexbox, Grid & Sass)

☞ The Complete Sass & SCSS Course: From Beginner to Advanced

7 Best Vue CSS Component for Your App

7 Best Vue CSS Component for Your App

Vue CSS frameworks are great for many reasons; code is more universally understood, web applications are easier to maintain, and prototyping becomes less of an extra step.

Vue CSS frameworks are great for many reasons; code is more universally understood, web applications are easier to maintain, and prototyping becomes less of an extra step and more part of the development process.

1. Tailwindcss-Vue

Tailwindcss-Vue is a library of UI components for Vue.js built using the Tailwind CSS utility-first CSS framework.


2. @zeit-ui/vue

Vue implementation for Zeit Style, originating from Zeit Design.

@zeit-ui/vue is a Vue implementation for zeit style, originating from Zeit Design. Lean more at GITHUB.

The design of the Zeit is concise and aesthetic feeling, this is an important reason for popular of Zeit. Now you can use them through the @zeit-ui/vue.


3. CSSeffectsSnippets

Click on the animation to copy it to your clipboard



4. Vue Cirrus

A fully responsive and comprehensive CSS framework with beautiful controls and simplistic structure. Cirrus is designed to be adaptable to existing themes or when starting fresh. These are the Vue Components for this CSS framework.



5. Vue CSS Modules

Seamless mapping of class names to CSS modules inside of Vue components.


6. BG MixMaster 90 — CSS Background Grid /Pattern Generator

make a background grid (like graph paper) using only one background gradient property and ended up with this killer mix tape for making all kinds of background grids and patterns.



CSS Rules from JS, change rules dynamically, CSSOM, css modules, auto vendor prefixer, media query for old browsers.

CSS in JS solution, create CSSOM and CSS rules from js, features:

  • CSS Rules create and diff
  • CSS modules with local class
  • Auto vendor prefixer
  • Media query for old browsers
  • Dynamically change CSS



Using CSS Quickies - CSS variables

Using CSS Quickies - CSS variables

Quickies CSS Tutorial: CSS Variables - How to create white - dark themes easily

What is CSS Quickes?

I started to ask my beloved community on Instagram: "what CSS properties are confusing for you?"

In "CSS Quickies" I will explain one CSS property in deep. These are community requested properties.

I'm also live streaming while coding on if you want to spend some fun time or you can ask me any question!

Let's talk about Custom properties aka CSS Variables.

Finally! If you ever have worked with CSS and wanted to keep your design consistent? Or was it more like at some pages, your website had different padding, margin or colors?

Maybe you wanted to implement a dark theme? It was possible, but now it has become easier!

Of course, if you have used LESS or SASS, then you know variables, and now they are finally supported natively. 😁

Let's have a look at it!

Defining a CSS variable

You define a CSS variable with prefixing a CSS property with --. Let's look at some examples.

  --example-color: #ccc;
  --example-align: left;
  --example-shadow: 10px 10px 5px 0px rgba(0,0,0,0.75);

Your first question is: "What is that ':root' pseudo-class?".

Good question! The :root pseudo-class is as you would use the html selector except that the specificity is higher of the ':root' pseudo-class. This means that if you set properties in the :root pseudo-class it will win over the html selector.

Okay, the rest is pretty simple. The custom property --example-color has the value of #ccc. When we use the custom property, for example, on the background-color property, the background of that element will be a light gray. Cool right?

You can give the custom property, aka CSS variable every value you could give any other property in CSS. It is okay to use left for example or 10px and so on.

Using CSS variables

Now that we know how to set CSS variables, we need to learn how to use them!

For this, we need to learn the var() function.

The var() can have two arguments. The first argument needs to be a custom property. If the custom property is not valid, you want to have a fallback value. To achieve this, you simply need to set the second argument of the var() function. Let's look at an example.

  --example-color: #ccc;

.someElement {
background-color: var(--example-color, #d1d1d1);

This should be now pretty straightforward for you to understand. We are setting the --example-color to #ccc and then we are using it in .someElement to set the background color. If something goes wrong and our --example-color is not valid, we have a fallback value of #d1d1d1.

What happens if you don't set a fallback value and your custom variable is invalid? The browser then will act as if this property was not specified and do its regular job.

Tips and tricks
Multiple fallback values

What if you want to have multiple fallback values? So you would think you could do the following:

.someElement {
background-color: var(--first-color, --second-color, white);

This will not work. After the first comma var() treats everything even the commas as a value. The browser would change this into background-color: --second-color, white;. This is not what we want.

To have multiple values, we can simply call var() inside a var(). Here comes an example:

.someElement {
background-color: var(--first-color, var(--second-color, white));

Now this would produce our desired outcom. When both --first-color and --second-color are invalid then the browser will set the background to white.

What if my fallback value needs a comma?

What to do if for example, you want to set a font-family in in the fallback value and you need to specify more then one font? Looking back at the tip before this should be now straight forward. We simply write it with the commas. Example time:

.someElement {
font-family: var(--main-font, "lucida grande" , tahoma, Arial);

Here we can see the after the first comma the var() function treats everything like one value.

Setting and getting custom properties in Javascript

In more complex apps and websites, you will javascript for state management and rendering. You also can get and set custom properties with javascript. Here is how you can do it:

    const element = document.querySelector('.someElement');
// Get the custom propety"--first-color");
// Set a custom propety"--my-color", "#ccc");

We can get and set the custom properties like any other property. Isn't that cool?

Making a theme switcher with custom variables

Let's first have a look at what we will do here:

The HTML markup
<div class="grid theme-container">
<div class="content">
<div class="demo">
<label class="switch">
<input type="checkbox" class="theme-switcher">
<span class="slider round"></span>

Really nothing special here.

We will use CSS grid to center the content that's why we have a .grid class on our first element the .content and .demo Classes are just for styling. The two crucial classes here are .theme-container and .theme.switcher.

The Javascript code
const checkbox = document.querySelector(".theme-switcher");

checkbox.addEventListener("change", function() {
const themeContainer = document.querySelector(".theme-container");
if (themeContainer && this.checked) {
} else {

First we are selecting our .theme-switcher input and the .theme-container element.

Then we are adding an event listener that listens if a change happens. This means that every time you click on the input, the callback for that event listener will run.

In the if clause we are checking if there is a .themeContainer and if the checkbox input is checked.

When this check is true, we are adding the .light class to the .themeContainer and if it is false, we are removing it.

Why are we removing and adding the .light Class? We will answer this now.

The CSS code

Since this code is lengthy, I will show it to you step by step!

.grid {
display: grid;
justify-items: center;
align-content: center;
height: 100vh;
width: 100vw;

Lets first center our content. We are doing this with css grid. We will cover the grid feature in another CSS quickies!

:root {
/* light /
--c-light-background: linear-gradient(-225deg, #E3FDF5 0%, #FFE6FA 100%);
--c-light-checkbox: #fce100;
dark */
--c-dark-background:linear-gradient(to bottom, rgba(255,255,255,0.15) 0%, rgba(0,0,0,0.15) 100%), radial-gradient(at top center, rgba(255,255,255,0.40) 0%, rgba(0,0,0,0.40) 120%) #989898;
--c-dark-checkbox: #757575;

Puh this is a lot of code and numbers but actually we are not doing much here. We are preparing our custom properties to be used for our theme. --c-dark- and --c-light- is what I have chosen to prefix my custom properties. We have defined a light and a dark theme here. For our example we just need the checkbox color and the background property which is a gradient in our demo.

.theme-container {
--c-background: var(--c-dark-background);
--c-checkbox: var(--c-dark-checkbox);
background: var(--c-background);
background-blend-mode: multiply,multiply;
transition: 0.4s;
.theme-container.light {
--c-background: var(--c-light-background);
--c-checkbox: var(--c-light-checkbox);
background: var(--c-background);

Here comes an integral part of the code. We now see why we named the .theme-container How we did. It is our entrance to have now global custom variables. We don't want to use the specific custom variables. What we want is to use global custom variables. This is why we are setting --c-background. From now on, we will only use our global custom variables. Then we are setting the background.

.demo {
font-size: 32px;

/* The switch - the box around the slider */
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;

/* Hide default HTML checkbox /
.switch .theme-switcher {
opacity: 0;
width: 0;
height: 0;

This is just some boilerplate code to set our style. In the .demo selector, we are setting the font-size. This is the size of our symbols for the toggle. In the .switch selector the height and width is how long and wide the element behind our toggle symbol is.

/ The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: var(--c-checkbox);
transition: 0.4s;

.slider:before {
position: absolute;
content: "🌑";
height: 0px;
width: 0px;
left: -10px;
top: 16px;
line-height: 0px;
transition: 0.4s;

.theme-switcher:checked + .slider:before {
left: 4px;
content: "🌞";
transform: translateX(26px);

Here we can finally see our custom properties in action besides using them directly in the .theme.container and again a lot of boilerplate code. As you can see, the toggle symbols are simple Unicode symbols. This is why the toggle will look different on every OS and mobile phone vendor. You have to keep this in mind. Important to know here is that in the .slider:before Selector, we are moving our symbol around with the left and top properties. We are doing that also in the .theme-switcher:checked + .slider:before but only with the left property.

/* Rounded sliders */
.slider.round {
border-radius: 34px;

This again is just for styling. To make our switch rounded on the corners.

That is it! We now have a theme switcher which is extendable. ✌😀

Originally published by lampewebdev at


Thanks for reading :heart: If you liked this post, share it with all of your programming buddies! Follow me on Facebook | Twitter

The ultimate CSS battle: Grid - Flexbox

Build a Custom Full Page Slider with CSS and JavaScript

The main differences between Flexbox and CSS Grid