George Kendros
George Kendros

Reputation: 824

How to create a variable width squares using css grid layout?

Is there a way to have grid cells whose width is based on fr units that dynamically adjust their height so that they stay square?

Also, I was hoping to do this without JS

The below fiddle has some example code. The divs with the class 'sqaure' are the ones which I want to dynamically adjust their height to match their width (which is 1fr so it changes)

https://jsfiddle.net/bpk0sLvL/403/

.holder {
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: 4px;
  row-gap: 4px;
}

.box {
  background-color: #ccc;
}

.wide {
  grid-column-start: 1;
  grid-column-end: 3;
}
<div class="holder">
  <div class="box wide">
    <p>This can be any height</p>
    <p>All these divs are sized based on fr, so I want to have the two square divs stay square as they dynamically resize </p>
  </div>
  <div class="box sqaure">
    This needs to be a sqaure
  </div>
  <div class="box sqaure">
    This needs to be a square as well
  </div>
</div>

Upvotes: 1

Views: 802

Answers (1)

Rounin
Rounin

Reputation: 29521

You need to:

  1. identify the width of .square; and
  2. ensure that the height of .square is equal to that width.

You can identify the width of .square with one line of javascript:

var squareWidth = document.getElementsByClassName('square')[0].offsetWidth;

You can ensure the height of .square is equal to that width with two lines of javascript:

var holder = document.getElementsByClassName('holder')[0];
holder.style.gridTemplateRows = 'auto ' + squareWidth + 'px';

Working Example:

function calculateSquareHeight() {

    var holder = document.getElementsByClassName('holder')[0];
    var squareWidth = document.getElementsByClassName('square')[0].offsetWidth;
    holder.style.gridTemplateRows = 'auto ' + squareWidth + 'px';
}

window.addEventListener('load', calculateSquareHeight, false);
window.addEventListener('resize', calculateSquareHeight, false);
.holder {
display: grid;
grid-template-columns: 1fr 1fr;
grid-column-gap: 4px;
grid-row-gap: 4px;
}

.box {
background-color: #ccc;
}

.wide {
grid-column-start: 1;
grid-column-end: 3;
}
<div class="holder">
<div class="box wide">
<p>This can be any height</p>
<p>All these divs are sized based on fr, so I want to have the two square divs stay square as they dynamically resize </p>
</div>

<div class="box square">
This needs to be a square
</div>

<div class="box square">
This needs to be a square as well
</div>
</div>

Upvotes: 1

Related Questions