How to create an adaptive layout with CSS Grid

It goes without saying that web developers have a lot of choices when it comes to laying out their webpages. Ensuring your layout can adapt to different devices, orientations, and screen sizes an important consideration as you decide which methods to use. Grid layout is a new layout method that enables you to divide space for major regions of a webpage based on either a fixed amount, the available space within the browser window, or a combination of both.

Because Grid layout enables you to align elements into columns and rows but has no content structure, it also enables scenarios—like the one described in this article—that are either not possible or are very difficult to achieve with HTML or Cascading Style Sheets (CSS) tables. Plus, by using Grid layout in conjunction with media queries, you can enable your layout to seamlessly adapt to changes in device form factor, orientation, available space, and more.

The CSS Grid Layout specification is currently a World Wide Web Consortium (W3C) Working Draft and is partially supported in Internet Explorer 10 in the vendor-prefixed form. For a full list of supported properties, see Grid Layout on MSDN. Because the Grid Layout specification is still in development, support in Internet Explorer 10 might not correspond exactly to that laid out in the specification.

Here we guide you through the creation of a simple light box page for viewing photos in a photo gallery. We use Grid layout to organize the page's content, and media queries to optimize the layout for viewing in either a portrait or landscape orientation. In a portrait layout, the height of the browser window is greater than its width; in a landscape orientation, the width of the browser window is greater than its height.

This topic has the following sections:

  • Designing the page
  • Constructing the Grid
  • Structuring the page
  • Creating the Grid element and specifying rows and columns
  • About fractional units
  • Assigning page elements to columns and rows
  • Aligning Grid items
  • Using Grid with media queries
  • Creating element overlap with Grid
  • Conclusion
  • Related topics

Designing the page

We want this light box page to take up the entire screen in Internet Explorer in the new Windows UI environment, with no scrolling. Of course, this page should also be equally useable in Internet Explorer for the desktop, and should fit nicely into that browser's chrome as well.

The following sketch approximates how we want our light box page to look when in a landscape orientation. We've chosen to sketch this assuming the browser takes up a full widescreen display with a 16:9 aspect ratio.

In this sketch, A is a small area intended for a logo, B is intended for a photo caption or description, C is the main photo viewing area, and D is for thumbnails of the other photos in the collection.

Because the light box page is intended to be viewed full screen, we'll have to account for different screen sizes. The focus of the page is the large photograph. Therefore, when the screen size increases, let's make the photograph panel (C) expand. But we should also prevent panel A from expanding at all, prevent panel B from expanding horizontally, and prevent panel D from expanding vertically.

Constructing the Grid

This scenario is an ideal use for Grid layout. To help construct the Grid, we'll add dotted lines to complete the Grid lines that aren't already visible. To achieve the margins between page elements and prevent the design from looking too crowded, we'll add some gutters. Gutters can simply be extra columns and rows of a fixed width or height.

In this image, the purple dotted line represents the Grid element, or Grid layout container. The red dotted lines represent the Grid lines.

This Grid has a total of five rows and three columns:

  • The gutters are the second and fourth rows and the second column
  • The first and last rows have fixed heights to account for the fixed height of panels A and D
  • The third row's height is variable, so that the layout will scale to any screen
  • The first column has a fixed width, to account for the fixed width of panels A and B
  • The last column's width is variable, so that the layout will scale to any screen

Structuring the page

Let's start marking up the Grid. To begin, we write a simple bit of HTML to get a basic page structure. Notice that the order of the sections is not necessarily what you would expect them to be given our sketch, but that's one of the benefits of Grid: you can reorder elements from Document Object Model (DOM) order however you want.

<!DOCTYPE html>
<html>

<head>
<meta content="IE=10" http-equiv="X-UA-Compatible" />
<link href="photogallerystyles.css" media="screen" rel="stylesheet" type="text/css">
<style>
</style>
</head>

<body>

<div id="body">
  <div id="grid">
    <div id="text_box" class="orange">
      Text box</div>
    <div id="big_pic" class="red">
      <img id="mainphoto" alt="mainphoto" src="images/img1.jpg"></div>
    <div id="photos" class="blue">
      Photos</div>
    <div id="logo" class="green">
      <div id="logotype">
        CONTOSO<br>IMAGES</div>
      <div id="pagedesc">
        Lightbox</div>
    </div>
  </div>
</div>

</body>

</html>

Creating the Grid element and specifying rows and columns

Now, create the Grid element and specify the rows and columns.

The first thing to do is to add the display element and set it to -ms-grid. This creates the Grid element.

In the Grid element, we use the -ms-grid-columns property to specify the width of each column in a space-delimited list. Likewise, we use the -ms-grid-rows property to specify the height of each column in a space-delimited list.

For the element with ID "grid", then, our CSS looks like this:

#grid {
  height: calc(100vh - 65px);  /* 65px to account for scrollbar */;  
  display: -ms-grid;
  -ms-grid-columns: 200px 25px 1fr;
  -ms-grid-rows: 160px 25px 1fr 25px 200px; 
  border: 1px solid red;          /* for a visual guide */
}

About fractional units

To enable the Grid to size itself according to the space available to it, we use fractional units (fr). The size of a fractional unit depends on both the total available space and the total number of fractional units specified. In our light box example page, we use just one fractional unit, but more complex layouts are also possible. For instance, consider a case where four columns are specified with lengths of auto, 100 pixels, 1 fractional unit, and 2 fractional units. The columns will appear as follows:

  • Column 1 (auto keyword): Column is fitted to the content in the column.
  • Column 2 ("100px"): Column is 100 pixels wide.
  • Column 3 ("1fr"): Column takes up one fraction unit of the remaining space.
  • Column 4 ("2fr"): Column takes up two fraction units of the remaining space.

Because there are three total fraction units in this grid, Column 3 is allotted 1 fraction unit divided by 3 fraction units—or 1/3—of the remaining space. Column 4 is allotted 2/3 of the remaining space.

Assigning page elements to columns and rows

If you look at the page now, it's definitely not yet ready. All the different page elements overlap each other because we haven't yet defined in which column(s) each element should go. We do this by using a combination of the -ms-grid-row, -ms-grid-column, -ms-grid-row-span, and -ms-grid-column-span properties.

The -ms-grid-row and -ms-grid-column properties, when applied to a page element, specify the Grid cell where the page element begins. In left-to-right, top-to-bottom languages, the -ms-grid-row property specifies the uppermost row that the element is to occupy. Similarly, you specify the leftmost column that the element is to occupy with the -ms-grid-column property.

The -ms-grid-row-span and -ms-grid-column-span properties, when applied to a page element, specify how many rows and columns the page element is to span.

Be aware that if you attempt to span past the number of defined columns or rows in the Grid, another column or row is implicitly created and its width or height is set to auto (fit to content) for every column or row beyond the defined number.

#text_box {
  -ms-grid-row: 3;
  -ms-grid-column: 1; 
  -ms-grid-row-span: 3;
  padding: 15px;
}
#big_pic {
  -ms-grid-row: 1;
  -ms-grid-column: 3;
  -ms-grid-row-span: 3;
  padding: 15px;
}
#photos {
  -ms-grid-row: 5; 
  -ms-grid-column: 3;
  padding: 15px;
}
#logo {
  -ms-grid-row: 1; 
  -ms-grid-column: 1;
  text-align: center;
  padding: 20px;
}

View the page with these selectors added as well as some styling of other page elements.

Aligning Grid items

The page looks good, but ideally the photo would be centered in its panel. To accomplish this, we'll use the -ms-grid-row-align and -ms-grid-column-align properties. These properties define how to align an item within a row or column, respectively. In our case, we'll set both of these properties to center on the ID selector for "big_pic":

#big_pic { 
  -ms-grid-row: 1;
  -ms-grid-column: 3;
  -ms-grid-row-span: 3;
  padding: 15px;
  -ms-grid-row-align: center;
  -ms-grid-column-align: center;
}

You can view this version of the page.

Using Grid with media queries

Our layout looks good in a landscape orientation. What about when the viewing device is in a portrait orientation? In this case, we can use media queries.

Using media queries, we'll redefine aspects of the layout so that they're tailored to a portrait layout. To add portrait layout-specific styles to the style sheet, first add the media query syntax:

@media all and (orientation: portrait) {

}

In media query parlance, portrait orientation defines a page whose width is larger than its height. Conversely, a page is in landscape orientation when its height is larger than its width.

Now we'll add a new Grid layout and some new styling for other page elements. We're adding these styles between the media query's curly brackets:

#grid {
    -ms-grid-columns: 150px 25px 1fr;
    -ms-grid-rows: 100px 25px 1fr 25px 100px;
}
#text_box {
  -ms-grid-row: 1; 
  -ms-grid-column: 3;
  -ms-grid-row-span: 1;
}
#big_pic {
  -ms-grid-row: 3;
  -ms-grid-column: 1;
  -ms-grid-column-span: 3;
  -ms-grid-row-span: 1;
}
#photos {
  -ms-grid-row: 5;
  -ms-grid-column: 1;
  -ms-grid-column-span: 3;
  -ms-grid-row-span: 1;
}
#logo {
  -ms-grid-row: 1;
  -ms-grid-column: 1;
  text-align: center;
  padding: 20px;
}
#logotype {
  font-size: 15px;
}
#pagedesc {
  font-size: 12px;
}
#mainphoto {
  width: 100%; 
  border-width: 10px;
  border-color: white;
}

Now, you can view the finished page. If you don't have a device you can turn to view the page in a portrait orientation, open the page in Internet Explorer for the desktop and resize it so that its width is less than its height.

Creating element overlap with Grid

CSS Grid opens up many more possibilities for page layout. For instance, Grid enables you to easily create content overlays, which, when combined with the opacity property, can create, for instance, translucent bands of text over an image. For more information and to see Grid overlays in action, see CSS Grid overlay sample in the Internet Explorer Samples Gallery.

Conclusion

You should now have an idea of the possibilities of Grid layout, and how to use the Grid properties with media queries. To learn more, see the links in the following section.

Contoso Images photo gallery

Grid Layout

Internet Explorer 10 Guide for Developers: Grid layout

IE Blog: IE10 Platform Preview and CSS Features for Adaptive Layouts