css grid overlap extra items without shifting elements

Viewed 79

I have a grid element with a set number of rows and columns that has one more element than rows * columns. I'm trying to overlap this extra item on top of one of the cells (changes overtime) but the whole layout shifts whenever I try to set a specific row/column on the extra cell.

.grid {
  display:grid;
  width: 60px;
  height: 60px;
  grid-template-rows: repeat(2, 1fr);
  grid-template-columns: repeat(2, 1fr)
}

.cell {
  width: 30px;
  height: 30px;
  background: grey;
  box-sizing: border-box;
}
<div class="grid">
  <div class="cell">1</div>
  <div class="cell">2</div>
  <div class="cell">3</div>
  <div class="cell">4</div>
  <div class="cell extra">5</div>
</div>

results in something like

result

but when I set a specific row and column via:

.extra {
  grid-row: 1/2;
  grid-column: 1/2;
} 

I get the following

result

but what I actually want

enter image description here

3 Answers

You need to specify where the first div will be as well as the extra div

.grid {
  display: grid;
  width: 60px;
  height: 60px;
  grid-template-rows: repeat(2, 1fr);
  grid-template-columns: repeat(2, 1fr)
}

.cell {
  width: 30px;
  height: 30px;
  line-height: 30px;
  background: grey;
  box-sizing: border-box;
  text-align: center;
}

.grid .cell:first-child,
.cell.extra {
  grid-row: 1 / 2;
  grid-column: 1 / 2;
}
<div class="grid">
  <div class="cell">1</div>
  <div class="cell">2</div>
  <div class="cell">3</div>
  <div class="cell">4</div>
  <div class="cell extra">5</div>
</div>

You can use 1/-1 for the positioning on the grid-column and grid-row

.grid {
  display: grid;
  width: 60px;
  height: 60px;
  grid-template-rows: repeat(2, 1fr);
  grid-template-columns: repeat(2, 1fr);
  margin-bottom: 30px;
}

.cell {
  width: 30px;
  height: 30px;
  background: grey;
  box-sizing: border-box;
}

.cell.extra {
  grid-column: 1/-1;
  grid-row: 1/-1;
}
<div class="grid">
  <div class="cell">1</div>
  <div class="cell">2</div>
  <div class="cell">3</div>
  <div class="cell">4</div>
  <div class="cell extra">5</div>
</div>


<div class="grid">
  <div class="cell">1</div>
  <div class="cell">2</div>
  <div class="cell">3</div>
  <div class="cell">4</div>
  <div class="cell">5</div>
  <div class="cell">6</div>
  <div class="cell extra">7</div>
</div>

Grid items will never overlap unless you explicitely specify this. Since you have 4 areas you will need 4 rules to make sure your items (whataver their number) will never create more areas:

.grid {
  display:grid;
  margin:5px;
  width: 60px;
  height: 60px;
  grid-template-rows: repeat(2, 1fr);
  grid-template-columns: repeat(2, 1fr)
}

.cell {
  width: 30px;
  height: 30px;
  background: grey;
  box-sizing: border-box;
}

.cell:nth-child(4n + 1) {grid-area:1/1}
.cell:nth-child(4n + 2) {grid-area:1/2}
.cell:nth-child(4n + 3) {grid-area:2/1}
.cell:nth-child(4n + 4) {grid-area:2/2}
<div class="grid">
  <div class="cell">1</div>
  <div class="cell">2</div>
  <div class="cell">3</div>
  <div class="cell">4</div>
  <div class="cell">5</div>
</div>

<div class="grid">
  <div class="cell">1</div>
  <div class="cell">2</div>
  <div class="cell">3</div>
  <div class="cell">4</div>
  <div class="cell">5</div>
  <div class="cell">6</div>
  <div class="cell">7</div>
  <div class="cell">8</div>
</div>

Related