11

Is it possible to limit the width of a CSS grid column?

body {
  margin: 0;
  padding: 0;
}
.container {
    display: grid;
    grid-template-columns: minmax(17.5%, 250px) minmax(31.25%, 480px) auto;
    grid-template-rows: 100vh;
    grid-gap: 0;
}
.menu {
    padding-top: 32px;
    background: linear-gradient(135deg, #837DB5 0%, #364176 100%);
}
.list-view {
    background-color: #F5F5FC;
}
<div class="container">
  <div class="menu"></div>
  <div class="list-view"></div>
  <div class="details"></div>
</div>

In the example above it always uses 17.5% width for the menu because:

"If max is smaller than min, then max is ignored and the function is treated as min."

source: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns

What I want is a menu that is 17.5% width with a max of 250px. Is that possible?

TylerH
  • 20,799
  • 66
  • 75
  • 101
klaasjansen
  • 537
  • 1
  • 6
  • 20
  • If i understood correctly you want the width to grow with screen hence the percentage value, but be fixed at 250px when the screen is smaller ? – Rainbow May 14 '18 at 12:38
  • No I guess the other way around. I want it to be 17,5%, but be fixed at 250px when the screen is bigger. – klaasjansen May 14 '18 at 12:39

3 Answers3

8

One way to do this might be declare:

.container {grid-template-columns: 250px 480px auto;}

as your standard rule.

Then, after considering the narrowest width you would like to apply to your third column, you can apply a @media query.

Let's say you want to ensure your third column is no narrower than 100px.

250px + 480px + 100px = 830px

So you need to write a @media query for 830px:

@media only screen and (max-width: 830px) {

    .container {grid-template-columns: 17.5% 31.25% auto;}
}

Working Example:

body {
  margin: 0;
  padding: 0;
}

.container {
    display: grid;
    grid-template-columns: 250px 480px auto;
    grid-template-rows: 100vh;
    grid-gap: 0;
}

.menu {
    padding-top: 32px;
    background: linear-gradient(135deg, #837DB5 0%, #364176 100%);
}

.list-view {
    background-color: #F5F5FC;
}

@media only screen and (max-width: 830px) {
    
    .container {grid-template-columns: 17.5% 31.25% auto;}
}
<div class="container">
  <div class="menu"></div>
  <div class="list-view"></div>
  <div class="details"></div>
</div>
Rounin
  • 27,134
  • 9
  • 83
  • 108
  • 1
    Yeah I guess that's also possible. Was hoping to find a css-grid only solution. – klaasjansen May 14 '18 at 13:00
  • 1
    If you want the first column width to be `17.5%` of the `` width up until a certain `` width and then always `250px` after that, then a `@media` query is absolutely the way to go. – Rounin May 14 '18 at 13:10
4

You want your column to have a standard width of 17.5%, and a maximum width of 250px.

You can't use grid-template-columns because the minmax() function computes to min anytime max is less than min. This means that 17.5% will override 250px on wider screens.

A clean workaround would be to set grid-template-columns to min-content, which shrink-wraps the column to the length of the content. Then set the width parameters on the grid item.

.container {
  display: grid;
  grid-template-columns: min-content minmax(31.25%, 480px) auto;
}

.menu {
  width: 17.5%;
  max-width: 250px;
}

However, the percentage length on the grid item doesn't work in this scenario because the parent reference (the column) is essentially set to a zero width (min-content). (fiddle demo).

Fortunately, in this case, because your container is set to the width of the viewport, you can easily overcome this problem with vw units instead.

.menu {
  width: 17.5vw;
  max-width: 250px;
}

.container {
  display: grid;
  grid-template-columns: min-content minmax(31.25%, 480px) auto;
  grid-template-rows: 100vh;
  grid-gap: 0;
}

.menu {
  width: 17.5vw;
  max-width: 250px;
  padding-top: 32px;
  background: linear-gradient(135deg, #837DB5 0%, #364176 100%);
}

.list-view {
  background-color: #F5F5FC;
}

body {
  margin: 0;
  padding: 0;
}
<div class="container">
  <div class="menu"></div>
  <div class="list-view"></div>
  <div class="details"></div>
</div>

jsFiddle demo

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

Am not sure if its feasible in this way, but an alternative is to use flexbox instead of CSS grid and you can easily achieve this:

body {
  margin: 0;
  padding: 0;
}

.container {
  display: flex;
  height: 100vh;
}

.menu {
  width: 17.5%;
  max-width: 250px;
  padding-top: 32px;
  background: linear-gradient(135deg, #837DB5 0%, #364176 100%);
}

.list-view {
  width: 32.25%;
  max-width: 480px;
  background-color: #F5F5FC;
}

.details {
  flex: 1;
}
<div class="container">
  <div class="menu"></div>
  <div class="list-view"></div>
  <div class="details"></div>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415