3

When defining grid-template-columns in the corresponding parent div this is fine.

wrapper {
   display:grid;
   grid-template-columns: 1fr 1fr 700px;
}

But what if I only want two columns?

If I delete one of the fr columns, it gets whacked.

So does a grid have a min of fr units if I am to use this? Go ahead and you will see the 2nd column is no longer 700px.

wrapper {
   display:grid;
   grid-template-columns: 1fr 700px; /* removing the 1fr defining only 2 columns,
                                        destroys the layout */
}

A simple example of this here: https://codepen.io/theboman/pen/PLRZjB

body {
  padding: 0px;
  margin: 0px;
}

wrapper {
  display: grid;
  grid-template-columns: 1fr 1fr 700px;  /* remove 1fr above and you will see */
}

header {
  grid-column-start: 1;
  grid-column-end: 4;
  height: 40px;
  background-color: grey;
}

nav li {
  display: inline-block;
  padding: 0px 10px
}

aside {
  grid-column-start: 1;
  grid-column-end: 3;
  background-color: #7fa7e8;
  height: 50vh;
}

article {
  grid-column-start: 3;
  grid-column-end: 4;
  background-color: #7ee8cc;
  height: 50vh;
}
<wrapper>
  <header>
    <nav>
      <ul>
        <li>click here</li>
        <li>2nd click here</li>
      </ul>
    </nav>
  </header>
  <aside>
    Aside - content here
  </aside>
  <article>
    some content goes here
  </article>

</wrapper>
kukkuz
  • 41,512
  • 6
  • 59
  • 95
Bo Opfer
  • 121
  • 1
  • 5

3 Answers3

1

That is because the code has grid-column-start and grid-column-end set for the header, aside and article - see demo below where it works for grid-template-columns: 1fr 700px with some changes in the grid-column values:

body {
  padding: 0px;
  margin: 0px;
}

wrapper {
  display: grid;
  grid-template-columns: 1fr 700px;
}

header {
  grid-column-start: 1;
  grid-column-end: 3; /* CHANGED */
  height: 40px;
  background-color: grey;
}

nav li {
  display: inline-block;
  padding: 0px 10px;
}

aside {
  grid-column-start: 1;
  grid-column-end: 2; /* CHANGED */
  background-color: #7fa7e8;
  height: 50vh;
}

article {
  grid-column-start: 2; /* CHANGED */
  grid-column-end: 3; /* CHANGED */
  background-color: #7ee8cc;
  height: 50vh;
}
<wrapper>
  <header>
    <nav>
      <ul>
        <li>click here</li>
        <li>2nd click here</li>
      </ul>
    </nav>
  </header>
  <aside>
    Aside - Map content here
  </aside>
  <article>
    some content goes here
  </article>
</wrapper>
kukkuz
  • 41,512
  • 6
  • 59
  • 95
1

Short Answer

When you say:

wrapper {
   display:grid;
   grid-template-columns: 1fr 1fr 700px;
}

... you are defining a grid with three explicit columns.

When you switch to:

grid-template-columns: 1fr 700px

... you are defining a grid with two explicit columns.

This method represents only one way of creating columns in a grid.

Another way is through implicit columns, which you happen to be doing with the grid-column-start and grid-column-end properties.

header {
  grid-column-start: 1; 
  grid-column-end: 4;
}

aside {
  grid-column-start: 1; 
  grid-column-end: 3;
}

article {
  grid-column-start: 3; 
  grid-column-end: 4;
}

It doesn't matter how many columns you define at the container level in terms of the implicit grid. You can define none if you want. Columns can also be created at the grid area level.


More about explicit and implicit grids

An explicit grid is the grid that you explicitly define. You create an explicit grid when you use the following properties:

  • grid-template-rows
  • grid-template-columns
  • grid-template-areas
  • grid (which is the shorthand for the three properties above, among others)

However, you are not required to keep grid items in the explicit grid. You can essentially place items and create grid areas anywhere you want, even outside the explicit grid. That's where the implicit grid comes in.

The implicit grid is created by rows and columns that are automatically generated to accommodate grid items that are positioned outside of the explicit grid. This can happen with line-based placement, using properties such as grid-column-start, grid-row-end and shorthands like grid-column and grid-row.

While grid-template-columns and grid-template-rows size explicit tracks, grid-auto-columns and grid-auto-rows size implicit tracks.


Reference

Here's how the spec defines these grid types:

7.1. The Explicit Grid

The three properties grid-template-rows, grid-template-columns, and grid-template-areas together define the explicit grid of a grid container.

The grid property is a shorthand that can be used to set all three at the same time.

The final grid may end up larger due to grid items placed outside the explicit grid; in this case implicit tracks will be created, these implicit tracks will be sized by the grid-auto-rows and grid-auto-columns properties.


7.5. The Implicit Grid

The grid-template-rows, grid-template-columns, and grid-template-areas properties define a fixed number of tracks that form the explicit grid.

When grid items are positioned outside of these bounds, the grid container generates implicit grid tracks by adding implicit grid lines to the grid.

These lines together with the explicit grid form the implicit grid.

The grid-auto-rows and grid-auto-columns properties size these implicit grid tracks.

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
0

The issue is that you are defining grid-column-* which will break if you change the number or the structure of your columns. To avoid this simply remove them and the browser will automatically place your elements.

You only need to specify that the first one need to span all the first row:

body{
  padding:0px;
  margin:0px;
}

wrapper {
  display:grid;
  grid-template-columns: 1fr 700px;
}

header {
    grid-column: 1/-1; /*will take all the row*/
    height: 40px;
    background-color: grey;
}

nav li {
  display: inline-block;
  padding: 0px 10px
}

aside {
  background-color: #7fa7e8;
  height: 50vh;
}

article {
  background-color: #7ee8cc;
  height: 50vh;
}
<wrapper>
<header>
  <nav>
    <ul>
      <li>click here</li>
      <li>2nd click here</li>
    </ul>
  </nav>
</header>
<aside>
  Aside - content here
</aside>
<article>
  some content goes here
</article>

</wrapper>

To make it working for both cases, you need to specify that the article element should be placed at the last column and that the aside element should start from the first one until before the last:

body{
  padding:0px;
  margin:0px;
}

wrapper {
  display:grid;
  grid-template-columns: 1fr 300px;
}

header {
    grid-column: 1/-1; /*will take all the row*/
    height: 40px;
    background-color: grey;
}

nav li {
  display: inline-block;
  padding: 0px 10px
}

aside {
  grid-column: 1/-2;
  background-color: #7fa7e8;
}

article {
  grid-column-end: -1;
  background-color: #7ee8cc;
}
<wrapper>
<header>
  <nav>
    <ul>
      <li>click here</li>
      <li>2nd click here</li>
    </ul>
  </nav>
</header>
<aside>
  Aside - content here
</aside>
<article>
  some content goes here
</article>

</wrapper>

<wrapper style="grid-template-columns: 1fr 1fr 300px;">
<header>
  <nav>
    <ul>
      <li>click here</li>
      <li>2nd click here</li>
    </ul>
  </nav>
</header>
<aside>
  Aside - content here
</aside>
<article>
  some content goes here
</article>

</wrapper>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415