Grey and black metal grid abstract artwork

Today, I Learned CSS Grid in Under Fifteen Minutes (and You can Too): The Basics

Yes, that's right. It took me less than fifteen minutes to learn CSS grid. You can do likewise, without having to sit through a video that's over an hour long (assuming you already know some CSS). It's not some complicated addition to the language, but really quite elegant and simple.

Introducing CSS Grids

If you've ever used a spreadsheet application (such as Excel), mput something in an HTML <table> or used Bootstrap/Foundation, you've used a grid. It's a two-dimensional layout/placement system that uses columns and rows instead of X and Y coordinates. Each specification of column and row specifies the location of a cell that contains content.

A typical grid consists of up to six columns with up to six rows (although you can define more; typically twelve if you use Bootstrap), to give thirty-six cells for content. It's also possible to nest grids within the cells of an outer grid, but that's not necessary when there are various means of fine-grained control for specifying the size(s) of cells. A little planning beforehand can make that fairly easy. Grids must be placed in a container element which displays as a block by default (display: block;). Typically, this is an <aside>, <div> or <section> element with a class attribute of "container" (and an identifier if there is more than one grid on the page in question). Ideally, this element spans the entire width of the viewport or parent element (or close to it) in order to make maximum use of available screen real estate. (The fact that Pub0x doesn't do this and leaves large areas of whitespace on the sides of both the editor and published content is somewhat irksome to me.)

Items within a grid may span multiple columns or rows (or both; both could be good), similar to using the colspan and/or rowspan attributes on <th> and/or <td> elements in an HTML <table> (like developers used to do before CSS existed and gave us options for the layout of non-tabular/textual items). However, CSS grids also allow for items to stack/overlap (in a much easier and more reliable way than using absolute positioning).

To place an item in a grid, use a block-level element (such as a <div>) with the class attribute of "item item-x", where "x" is a number starting with 1, up to 36 for a 6x6 grid or 144 for a 12x12 grid. (For some strange reason, CSS grids are one-based, instead of zero-based. Expect off-by-one errors in your CSS.) Here's an example:

    <section id="main">
      <h1>CSS Grid Example</h1>
      <div class="container" id="main-grid">
      <!-- Unlike in Bootstrap, you don't need to place items
         within divs with "row" classes; the CSS handles that
         for you. -->

        <div id="item1" class="item item-1 first">#1</div>
        <div id="item2" class="item item-2">#2</div>
        <!-- ... more items here ... -->
        <div id="item36" class="item item-36 last">#36</div>
      </div> <!-- /#main-grid.container -->
    </section> <!-- /#main -->

That's only half the grid done, though. (At this point, what you'll see is a number of rows/lines of text corresponding to the number of cells, which is neither desired nor interesting.) To make the div with the class of "container" behave as a grid, you have to write some CSS, particularly .container { display: grid; } (along with a few other properties I'll cover shortly, mainly the number of columns and rows in the grid, as well as the default height and width of a cell). Otherwise, the default is one column per row (as mentioned at the start of this paragraph). For example:

#main-grid {
  display: grid; grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
  /* 'fr' is short for 'fractional'. Here, we have five columns
    of equal width (20% each) and three rows of 1em each.
  grid-template-rows: 1em 1em 1em; width: 99.8 vw;
  /* Container takes up 99.8% of the viewport. */
  min-width: 600px; margin: 1em auto;
  /* I could also specify `repeat(5, 1fr)`, since the `repeat`
   function takes a count as its first argument and a value
   to repeat as the second argument. Any unit of length (fixed
   or relative) can be specified for a column/row size.


Note: It is advisable to use relative sizing units (em, rem, fr or %), instead of fixed ones (px), for the size of cells. Doing this this helps to make the grid(s) responsive and use the maximum available space. Later on, I'll show you a trick you can use to ensure this is the case, without the need for media queries or hiding overflowing cells. However, it is perfectly acceptable to use fixed units for specifying the minimum width and height. As shown above, fr (fractional) can be used as a shorthand for "equal percentage of available space". For example: Three columns of 1fr get 33.3% each. If one of those three columns is of width 2fr, it gets 50% of the space while the other two get 25%, etc.

To position a particular item within a grid, use the grid-column-* and grid-row-* or grid-area properties for it:

#item1 { /* First item in grid;
  use .item-1 or .item.first to apply properties to all
  first items in all grids */

  grid-column-start: 1; /* start in first column */
  grid-column-end: 3; /* span two columns */

  grid-row-start: 1; /* start in first line/row */
  grid-row-end: 2; /* no row spanning */


Note: As previously mentioned, the numbers are 1-based. The start value is inclusive, while the end value is exclusive. An item with a starting row of 1 and ending row of 3 spans two rows, not three. Likewise, an item with a column start of 1 and end of 5 spans four columns, not five. (Do you see what I mean about expecting to put off-by-one errors in your code?)

If you do not specifically declare the sizes of items, they will default to 1x1 cells (using whatever is specified for the size of a cell in the grid) to fill the available space. If you do not specifically declare the positions of items (starting columns and rows) of items, the grid will populate from left to right and top to bottom.

Really, that is the bare minimum that you need to know in order to use CSS grids. Of course, as with other things in CSS, there are easier, more efficient and less cumbersome/verbose ways to specify the attributes/properties of grids and the items therein. It also gets somewhat fancy. However, since it's late at night and I need to get to bed (at time of writing), I'm leaving those parts of the tutorial for at least one additional post on the topic.

Once again, my apologies for the ugly blocks of red monospaced text; the code editor is still not working for me. Support for Codepen/Snippets (or whatever Stack Overflow uses) would be welcome. #ItWorksOnMyMachine, right?

Thumbnail image: Photo by Pixabay on Pexels

How do you rate this article?


Great White Snark
Great White Snark

I'm currently seeking fixed employment as a S/W & Web developer (C# & ASP .NET MVC, PHP 8+, Python 3), hoping to stash the farmed fiat and go full Crypto, quit the 07:30-18:00 grind. Unsigned music producer; snarky; white; balding; smashes Patriarchy.

Return to the Source
Return to the Source

Use the Force; read the source! This blog is mostly a collection of study notes on ASM, ASP .NET, Blender, BASIC, C/C++, C#, ChucK, Computer Architecture, Computer Literacy, CSS, Digital Logic, Electronics, F#, GIMP, GTK+, Haskel, Java, Julia, JavaScript (ES6+) & JSON, LISP, Nim, OOP, Photoshop, PLAD, Python, Qt, Ruby, Scheme, SQL (MySQL & SQLite), Super Collider, UML, Verilog, VHDL, WASM, XML. If I can learn it and make notes on it, I'll write about it. || Blog images copyright Markus Spiske and Pixabay

Send a $0.01 microtip in crypto to the author, and earn yourself as you read!

20% to author / 80% to me.
We pay the tips from our rewards pool.