Search code examples
htmlcssgrid-layoutcss-grid

How to use grid-row-align and grid-column-align?


I am experimenting with display: grid; and do not understand how grid-row-align and grid-column-align work. Some documentation states that (EDIT: this link is now gone, probably after I posted a comment pointing to Michael_B's answer below)

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

My understanding is that this is a property which must be set in the container of the impacted element (but I also tried to put it in the rules for the element itself). Specifically I expected that in the following code, the word hello would be centered both horizontally and vertically in his box.

What is the correct usage of these properties?

Note: I am using Chrome 58, which according to the compatibility matrix is OK.

#container {
  display: grid;
  grid-template-columns: auto;
  grid-template-rows: auto auto;
  height: 300px;
  width: 300px;
  border-style: solid;
  border-width: 1px;
  grid-row-align: center;
  grid-column-align: center;
}
#box-1 {
  grid-column: 1;
  grid-row: 1;
  border-style: solid;
  border-width: 1px;
  /* I also tried to put them here
  grid-row-align: center;
  grid-column-align: center;
  */
}
#box-2 {
  grid-column: 1;
  grid-row: 2;
  border-style: solid;
  border-width: 1px;
}
<div id="container">
  <div id="box-1">
    hello
  </div>
  <div id="box-2">
    world
  </div>
</div>


Solution

  • In the current CSS Grid Layout specification, there are no such properties as grid-row-align and grid-column-align. They simply don't exist (see Property Index).

    These properties were part of a now obsolete Grid spec, which is no longer being implemented in browsers. IE10/11 and Edge may still support grid-row-align / grid-column-align, but Edge is currently in the process of upgrading to the current spec.

    To center text inside a grid item, simply use flexbox:

    #container {
      display: grid;
      grid-template-columns: auto;
      grid-template-rows: auto auto;
      height: 300px;
      width: 300px;
      border-style: solid;
      border-width: 1px;
    }
    
    #box-1 {
      grid-column: 1;
      grid-row: 1;
      border-style: solid;
      border-width: 1px;
    
      /* NEW */
      display: flex;
      justify-content: center;
      align-items: center;
    }
    
    #box-2 {
      grid-column: 1;
      grid-row: 2;
      border-style: solid;
      border-width: 1px;
    
      /* NEW */
      display: flex;
      justify-content: center;
      align-items: center;
    }
    <div id="container">
      <div id="box-1">hello</div>
      <div id="box-2">world</div>
    </div>

    Keep in mind that alignment properties on the container will apply to the grid item, but not the content of the grid item, which is another level down.

    So if you give the container justify-items: center and align-items: center, the entire item gets centered in the container, which is not what you want.

    #container {
      display: grid;
      grid-template-columns: auto;
      grid-template-rows: auto auto;
      height: 300px;
      width: 300px;
      border-style: solid;
      border-width: 1px;
      justify-items: center; /* new */
      align-items: center;   /* new */
    }
    
    #box-1 {
      grid-column: 1;
      grid-row: 1;
      border-style: solid;
      border-width: 1px;
    }
    
    #box-2 {
      grid-column: 1;
      grid-row: 2;
      border-style: solid;
      border-width: 1px;
    }
    <div id="container">
      <div id="box-1">hello</div>
      <div id="box-2">world</div>
    </div>

    So you need to make the grid item a nested container in order to apply alignment properties to the content. You can give the item display: grid and use justify-items and align-items like in the example above. But if you don't need a new grid inside the grid item, flex may be a simpler (and lighter?) solution.