Grow your CSS skills. Land your dream job.

grid

Last updated on:

The grid property in CSS is the foundation of Grid Layout. It aims at fixing issues with older layout techniques like float (clearing was weird) and inline-block (spacing issues) by providing a new way of building web pages with CSS.

The idea is to define an element as a grid. Think columns and rows like a spreadsheet. Then, you can define for each child a column and a row (resulting in a cell). No markup changing is involved; everything is done through CSS.

Along with the fact this method fixes the issues we encounter with older layout techniques, its main benefit is you can display a page in a way which can differ from the flow order.

Reminder: please note the CSS Grid Layout is currently a working draft, meaning things may change and currently supporting browsers support may revise their implementation.

Properties

Since CSS Grid Layout is a whole module and not a single property, it gathers a bunch of properties (15 to be exact) meant to be used together. Some are meant to be set on the parent (grid) element, others on the children.

Currently Supported

The following are the grid-element properties (that go on the parent element).

display: grid | inline-grid

display: other values | grid | inline-grid

This defines a grid context on an element.

grid-rows | grid-columns

grid-rows | grid-columns:  
<track-list>    => [ [ <string> ]* <track-group> [ <string> ]* ]+ | none
<track-group>   => <track-minmax> | [ repeat( <positive-integer> , [ [ <string> ]* <track-minmax> [ <string> ]* ]+ ) ]
<track-minmax>  => minmax( <track-breadth> , <track-breadth> ) | auto | <track-breadth>
<track-breadth> => <length> | <percentage> | <fraction> | min-content | max-content

This defines the number of rows/columns in the grid as well as their dimension.

Any of those properties support a list of values separated by spaces. Each value will define a new column/row by setting its dimension. A list of 4 values will result in 4 columns/rows. A single value will produce a single column/row.

Accepted values include length (like px or em), percentages, fractions (fr; see below), auto (or fit-content), mincontent, maxcontent, and minmax(), or the repeat() function.

The repeat() function has been specifically designed for this module. It allows you to define a pattern repeated X times. Let's say you want to do 12 equal-width columns spaced from each other by a 1% margin; you could define 1fr repeat(11, 1% 1fr). It is the same as 1fr 1% 1fr 1% 1fr 1% 1fr 1% 1fr 1% 1fr 1% 1fr 1% 1fr 1% 1fr 1% 1fr 1% 1fr 1% 1fr.

As of writing, repeat() isn't supported yet. However you may find a similar syntax looking like this: (pattern)[x]. So 1fr (1% 1fr)[11].

Important! grid-rows and grid-columns are deprecated but currently supported by Internet Explorer 10. The new and official syntax is grid-definition-rows and grid-definition-columns.

This next set of properties are for the grid-item elements (children of the grid-element).>

grid-row | grid-column

grid-row | grid-column: <integer> [DEFAULT: auto]

This defines on which row and which column will be displayed the item.

Important! grid-row is supposed to be a shorthand for grid-row-position and grid-row-span. The current implementation in Internet Explorer 10 for grid-row should be the one for grid-row-position (which isn't supported). Same goes for grid-column.

grid-row-span | grid-column-span

grid-row-span | grid-column-span: &lt;integer> [DEFAULT: 1]

This defines the number of rows or cells the item will occupy. If not specified, the item will only occupy its own cell. A positive value will expand the item to next rows/cells.

grid-row-align | grid-column-align

grid-row-align | grid-column-align: start | end | center | stretch [DEFAULT: stretch]

grid-row-align defines the vertical alignment within the row while grid-column-align defines the horizontal alignment within the column.

If not specified, the item will occupy the whole cell. If any of the other 3 allowed value is specified, the item will be sized according to its content and aligned as desired (start, end or center).

Note that start doesn't necessarily mean "left" when dealing with grid-column-align since it depends on the document direction. It means "left" when document is ltr, "right otherwise". Same goes for end.

New unit: fr

It also involves a new unit that can be used for grid-rows and grid-columns: fr. It stands for "fraction of available space". Think of it as percentages for available space when you've taken off fixed-sized and content-based columns/rows. As the spec says:

The distribution of fractional space occurs after all ‘length’ or content-based row and column sizes have reached their maximum.

Coming Soon

The properties covered so far are the very basics to use the grid layout; they are also the first (and currently only) properties to be supported in this module.

According to the official specifications, there are a lot more involved than just these, including:

  • grid-template: allows grid definition through a template of identifiers
  • grid-column-position: current grid-column since grid-column is supposed to be a shorthand for grid-column-position and grid-column-span
  • grid-row-position: same as above
  • grid-position: shorthand for grid-column-position and grid-row-position
  • grid-span: shorthand for grid-column-span and grid-row-span
  • grid-area: shorthand for grid-column-position, grid-row-position, grid-column-span and grid-row-span
  • grid-auto-columns: change default size for columns
  • grid-auto-rows: change default size for rows
  • grid-auto-flow: allows grid-items to automatically flow in available cells

Unfortunately, these properties are currently unsupported.

Example

Let's make a little example. Please consider a structure like this one:

<div class="main">
  My awesome content here
</div>
  
<footer class="footer">
   Some informations here
</footer>
  
<header class="header">
  My site title goes here
</header>
  
<aside class="sidebar">
    Here is my side content
</aside>

Please note how the markup order has absolutely no impact on the final rendering.

body {
 /* First, we define body as a grid element */
 display: grid;
   
 /* Then, we define the number of columns we want by setting their dimensions */
 /* Beware, gaps between columns will be actual columns too */
 /* 1. This means there are 3 columns: 
  * the first one is 200px wide
  * the second one will be a margin (1%) 
  * the third one will occupy the remaining space 
  */
 grid-columns: 200px 1% 1fr; /* 1 */
   
 /* Now we define the number of rows and their dimensions */
 /* 2. this means there are 5 rows: 
  * the first one will be sized according to its content
  * the second one will be a margin
  * the third one will be sized according to its content
  * the fourth one will be a margin as well
  * the last one will be sized according to its content 
  */
 grid-rows: auto 15px auto 15px auto; /* 2 */
   
 /* The body element is now a 3*5 grid. */
}
 
/* Both the header and the footer will be full width, so we have to make them occupy the 3 columns */
.header, 
.footer {
  grid-column-span: 3;
}

/* Let's define in which row the header will be: the first one */
.header {
  grid-row: 1;
}
 
/* Same for the footer: the last one so the fifth (remember margins count as cols/rows */
.footer {
  grid-row: 5;
}
 
.sidebar {
  /* The sidebar will occupy the first column which is 200px wide */
  grid-column: 1;
  /* And the 3rd row (there are the header and a margin before) */
  grid-row: 3;
}
 
.main {
  /* The main content will be on the 3rd column and the 3rd row */
 grid-column: 3;
 grid-row: 3;
}

With a few other lines of CSS to handle styling issues, we have a decent layout with absolutely no floats, no inline-blocks, no defined widths, no defined heights and no margins and completely independant of the flow order. Pretty neat, right?

Check out this Pen!

If you see the 4 parts one under the other, your browser doesn't support CSS Grids. Please switch to a supported browser to enjoy the demo.

Now let's add a 2nd sidebar to, for instance, display ads. It will be on the right side of the main content. There are a few tweaks to do in order to make everything works.

/* We first change the grid-columns definition on the grid element to add 2 new columns: one margin and one sidebar */
body {
  display: grid;
  grid-columns: 200px 1% 1fr 1% 100px;
  grid-rows: auto 15px auto 15px auto;
  /* We could have writen grid-rows: auto (15px auto)[2] */
}

/* Both the header and the footer will expand to 5 columns instead of 3 */
.header, .footer {
  grid-column-span: 5;
}

.ads {
  grid-column: 5;
  grid-row: 3;
}

Done! We now have a layout with full-width header and footer, 3-columns on the main part including 2 fixed-width columns with about 13 lines of CSS.

Check out this Pen!

If you see the 5 parts one under the other, your browser doesn't support CSS Grids. Please switch to a supported browser to enjoy the demo.

What about responsive design? Easy as a pie. Let's slightly tweak our design when under 600px device width.

@media all and (max-width: 600px) {
  body {
    /* First, we make the body 1-column and 5 rows spaced by 4 margin rows */
    grid-columns: 1fr;
    grid-rows: auto (1% auto)[4];
    /* This is the same as:
     * grid-rows: auto 1% auto 1% auto 1% auto 1% auto;
     */
  }
  
  /* Then we say to all elements they belong in the only existing column */
  .header, .ads, .sidebar, .main, .footer {
    grid-column: 1;
  }
  
  /* Now we define their row; don't forget spacing rows! */
  .header  { grid-row: 1; }
  .ads     { grid-row: 3; }
  .main    { grid-row: 5; }
  .sidebar { grid-row: 7; }
  .footer  { grid-row: 9; }
  
  /* We even can create grids inside grids */
  .ads {
    display: grid;
    grid-columns: 1% (32% 1%)[3]; /* 1% 32% 1% 32% 1% 32% 1% */
    grid-rows: 2; /* One for the title, one for the images */
  }
  
  .ads h2  { grid-row: 1; grid-column-span: 3; }
  .ads img { grid-row: 2; }
  .ads img:nth-of-type(1) { grid-column: 2; }
  .ads img:nth-of-type(2) { grid-column: 4; }
  .ads img:nth-of-type(3) { grid-column: 6; }
}

Have a look at this Pen and resize your browser to see the magic!

Here is a grid system made with CSS Grid Layout and Sass:

Check out this Pen!

If you see all items one under the other, your browser doesn't support CSS Grids. Please switch to a supported browser to enjoy the demo.

If you feel uncomfortable with the idea of having columns and rows as margins, I guess you can still use actual margins on element but that defeats the purpose a bit. Or you could use a CSS preprocessor to ease you the calculations; here is a demo.

Related

Other Resources

Browser Support

Chrome Safari Firefox Opera IE Android iOS
none none none none 10+ none none

Support coming in WebKit and Gecko (currently in some nightly builds).

Comments

  1. Nkosi
    Permalink to comment#

    Great article, much appreciated.

  2. Ian
    Permalink to comment#

    Great article cheers. Didn’t think I’d see the day again IE was more “edge” than FF and chrome

    • Cezar
      Permalink to comment#

      Exact my thought!

    • Permalink to comment#

      this makes me wonder if someone who works on IE made this feature… anyway, cheers for when other bowers can use it too! until then, keep rocking the old school methods. :(

  3. Michael
    Permalink to comment#

    Looks promising! Can’t believe I had to load up VMware to open IE 10 to actually see it in action, but well worth it.

    Thanks for sharing!

  4. Jack
    Permalink to comment#

    亮瞎我了!竟然有IE支持的别的内核不支持的一刚!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!我吐了一屏幕的水!!!!!!!!这TM是本世纪的奇迹啊!!!!!
    This is the miracle of the century that only IE Support!

  5. It’s already available in HTML5 and CSS3 for develop in windows 8……….. *only for windows 8 APP

  6. Great stuff, can’t wait to use it ^^

    I do have a question since I can’t setup IE10 at the moment :P

    What happens if you set an element outside the grid (e.g. cell 11×11 in a 10×10 grid), or set it to expand beyond the grid (e.g. spans 5 columns in a 4 column grid)?

    Thanks :)

  7. John
    Permalink to comment#

    This is a great stuff.. hope google and ff and other support this grid system.. can’t wait to test it…

  8. nick

    cant wait! i just installed the grid

  9. I want it on all browsers!

  10. asdasdasdasdasdasd
    Permalink to comment#

    kjhklasjkdasjkldjasdkljasd
    askdaklsdlkasdas
    dasdjkashdklashdas
    asdjklashdklahsdas
    dasdjklashdkuashdas
    dasdasjkdajklshdasda
    sdasd

    djasd

    asd´ka asidjad

    <

    p style=”position:fixed; width:100%; height:50%; top:0; left:0; background:rgba(0,0,0,0.5)”><

  11. Martin Svetoslavov
    Permalink to comment#

    Now also supported by the latest version or two of Crome.

  12. Ian
    Permalink to comment#

    Hi,

    tl;dr – no new browser support and now apparently in the near future

    I am running both released chrome (30) and canary(32) . Currently neither of these are rendering the codepens as intended. So at least upto chrome 32 won’t support this.

    As for Firefox:
    Firefox 27nightly – no joy
    I expect this mean all versions before equally not support so for at least (I guess) the next 3 versions of FF won’t support this.

    Opera given the lack of mobile support see below I doubt it

    Mobile all Android 4.3
    Chrome 30 – no joy
    Firefox 24 – no joy
    Opera Mobile 16 – Nope

    Ian

    • Ian
      Permalink to comment#

      The tl;dr should have read

      no new browser support and none apparently in the near future

  13. Permalink to comment#

    No sense if just IE +10 supports it!

  14. Tremendus Apps
    Permalink to comment#

    This is exactly what this industry needs to streamline layout development. It can take literally a day to put LESS/CSS together to get complex responsive design … even when using UI kits like Bootstrap when you need fixed width/height or absolute/fixed position elements. This would simply things enormously.

  15. Eli
    Permalink to comment#

    Mr. #BADA55 Internet Explorer.
    But I still couldn’t use grid areas.

  16. Osama Bin Login
    Permalink to comment#

    Well the last several specs said this:

    Editors:
    Tab Atkins Jr. (Google)
    fantasai (Mozilla)
    Rossen Atanassov (Microsoft)

    Former Editors:
    Alex Mogilevsky (Microsoft Corporation)
    Phil Cupp (Microsoft Corporation)

    so that explains why it works on IE before it works on the other browsers. Silverlight also works on IE and no other browsers. As with some other parts of CSS3/HTML5, can’t use it till it works “everywhere”.

  17. y0ssar1an
    Permalink to comment#

    Update: These properties were dropped from the CSS spec. Do not use them, even in prefixed form.

    grid-row-align
    grid-row-span
    grid-column-align
    grid-column-span

Leave a Comment

Current day month ye@r *

*May or may not contain any actual "CSS" or "Tricks".