Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to calc() the number of rows in a grid template?

I'd like to calculate the number of rows in a grid template using calc(), but trying to get the repeat count with division isn't working:

.grid {
  display: grid;
  grid-gap: 10px;
  grid-template-columns: 1fr;
  margin-bottom: 10px;
  background: rgba(0, 0, 0, 0.2);
}

.grid>div {
  background: tomato;
  width: 20px;
  text-align: center;
  margin: auto;
}

.grid.no-calc {
  grid-template-rows: repeat(3, 30px);
}

.grid.addition {
  grid-template-rows: repeat(calc(1 + 2), 30px);
}

.grid.subtraction {
  grid-template-rows: repeat(calc(4 - 1), 30px);
}

.grid.multiplication {
  grid-template-rows: repeat(calc(3 * 1), 30px);
}

.grid.division {
  grid-template-rows: repeat(calc(6 / 2), 30px);
}
<p>Top 4 have their row heights set correctly</p>

<div class="grid no-calc">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>

<div class="grid addition">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>

<div class="grid subtraction">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>

<div class="grid multiplication">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>

<p>Division doesn't work in setting row height</p>

<div class="grid division">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>

Is there something I'm missing about the way repeat, calc, and division work together? This is in Chrome 71.0.3578.98.

like image 928
Sander Moolin Avatar asked Jan 30 '19 19:01

Sander Moolin


1 Answers

When using division with calc the result will be a number and not an integer thus it won't work because the repeat() expect an interger

The generic form of the repeat() syntax is, approximately,

repeat( [ <positive-integer> | auto-fill | auto-fit ] , <track-list> )ref

And

At /, check that the right side is <number>. If the left side is <integer>, resolve to <number>. Otherwise, resolve to the type of the left side.ref

And

Number values are denoted by <number>, and represent real numbers, possibly with a fractional component.ref

Even if we both know that the result will be an integer the browser will still consider it as a number.

You can have the same issue with multiplication in case you have a number in one of the sides

.grid {
  display: grid;
  grid-gap: 10px;
  grid-template-columns: 1fr;
  margin-bottom: 10px;
  background: rgba(0, 0, 0, 0.2);
}

.grid>div {
  background: tomato;
  width: 20px;
  text-align: center;
  margin: auto;
}

.grid.no-calc {
  grid-template-columns: repeat(3, 30px);
  border-bottom:3px solid red;
}

.grid.multiplication {
  grid-template-columns: repeat(calc(3 * 1.0), 30px); /*will fail*/
  border-bottom:calc(3px * 1.0) solid red;
}

.grid.division {
  grid-template-columns: repeat(calc(6 / 2), 30px);
  border-bottom:calc(6px / 2) solid red; /*this will work because border accept numbers*/
}
<div class="grid no-calc">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>


<div class="grid multiplication">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>

<div class="grid division">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>

Firefox is behaving differently and never fail even if we explicitely specify numbers. In all the cases Fiferox will try to round the result of calc() to a positive integer one.

All the examples below will fail on Chrome and will work on Firefox:

.grid {
  display: grid;
  grid-gap: 10px;
  grid-template-columns: 1fr;
  margin-bottom: 10px;
  background: rgba(0, 0, 0, 0.2);
}

.grid>div {
  background: tomato;
  width: 20px;
  text-align: center;
  margin: auto;
}

.grid.no-calc {
  grid-template-columns: repeat(calc(2.8), 30px); /*will be converted to 3*/
  border-bottom:calc(calc(2.8) * 1px) solid red;
}

.grid.multiplication {
  grid-template-columns: repeat(calc(3 * 1.55), 30px);  /*will be converted to 4*/
  border-bottom:calc(calc(3 * 1.55) * 1px) solid red;
}

.grid.division {
  grid-template-columns: repeat(calc(6 / 2.8), 30px); /*will be converted to 2*/
  border-bottom:calc(calc(6 / 2.8) * 1px) solid red;
  
}
<div class="grid no-calc">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
</div>


<div class="grid multiplication">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
</div>

<div class="grid division">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
</div>
like image 67
Temani Afif Avatar answered Nov 11 '22 08:11

Temani Afif