4

I'm about to take my first baby steps with CSS Grid, having used Bootstrap plus Javascript for grids until now. What I want to start with is something which I know to be very simple, if I but knew how.

Let's say I have a bit of HTML like this:

<div class="container">
 <div id="a">Blah</div>
 <div id="b">Blurgh</div>
</div>
  1. On desktop, I want a 2 column layout with block a on the left, block b on the right.
  2. On mobile (using media query), I want a single column, with block b above block a (so, out of the normal order).

So what do I need to do?

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
John Moore
  • 6,739
  • 14
  • 51
  • 67

2 Answers2

11

CSS Grid provides multiple methods for achieving your layout, including line-based placement, grid areas and the order property. I'll post examples of the first two below.

Line-based placement

.container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 50px;
  grid-gap: .5em;
  padding: .5em;
  border: 1px solid black;
}

@media ( max-width: 600px) {
  .container {
    grid-template-columns: 1fr;
    grid-template-rows: 50px 50px;
  }
  #b {
    grid-row: 1;
  }
}

/* non-essential decorative styles */
#a     { background-color: lightgreen; }
#b     { background-color: orange; }
#a, #b { display: flex; align-items: center; justify-content: center; font-size: 1.5em; }
<div class="container">
  <div id="a">A</div>
  <div id="b">B</div>
</div>

jsFiddle demo


grid-template-areas

.container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 50px;
  grid-gap: .5em;
  padding: .5em;
  border: 1px solid black;
  grid-template-areas: " a b ";
}

#a { grid-area: a; }
#b { grid-area: b; }

@media ( max-width: 600px) {
  .container {
    grid-template-areas: " b " " a ";
    grid-template-columns: 1fr;
    grid-template-rows: 50px 50px;
  }
}

/* non-essential decorative styles */
#a     { background-color: lightgreen; }
#b     { background-color: orange; }
#a, #b { display: flex; align-items: center; justify-content: center; font-size: 1.5em; }
<div class="container">
  <div id="a">A</div>
  <div id="b">B</div>
</div>

jsFiddle demo

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • 1
    I used the 'grid-template-areas' solution, and it works fine. I assume I can just extend it if I have other placement requirements further down the line. Is there a way to effectively switch back to default ordering after this out-of-order placement, so that subsequent blocks are placed left-right in the two columns for desktop, and in a single column for mobile. Or do I have to specify everything with grid-template-area? – John Moore Jan 20 '19 at 14:35
  • Excellent answer, it helped me too. – Signcodeindie May 22 '19 at 14:40
8

The simplest way I believe is to use the CSS grid order property. You can simply define which order the elements appear in by stating the order with number values.

Define the container element to be displayed grid, and then depending on screen size set grid template columns and set order of each item.

Alter screen size to see the result on mobile / desktop:

.container {
  display: grid;
  grid-template-columns: auto auto; /* make each item sit side by side */
}

#a {
  background-color:green;
}

#b {
  background-color: orange;
}
  
@media only screen and (max-width: 600px) {
  .container {
    display: grid;
    grid-template-columns: 100%; /* make each item span full width */
  }

  #a {
    order: 2; /* set this to appear second */
  }

  #b {
    order: 1; /* set this to appear first */
  }
}
<div class="container">
 <div id="a">Blah</div>
 <div id="b">Blurgh</div>
</div>
Jonny
  • 1,053
  • 1
  • 13
  • 26