I have a set of div tiles that I've arranged through the CSS Grid Layout as "automatically" as possible; my final idea is that even if I don't know how many tiles there are, they all get sized and placed correctly. This is working fine.
Now, I'm looking to double the area of any tile that is clicked on. As far as I know, that means increasing the span of this tile:
grid-row: span 2;
grid-column: span 2;
I'm happy with the results if I click on any tile that is not in the right-most column. When the rightmost tiles get expanded, they are wrapped down onto the next line.
Is there any way to force these tiles to expand to the left, so that other non-active tiles are wrapped instead?
Codepen example here
$('div.tile').click(function() {
$('div.tile').not(this).removeClass('chosen');
$(this).toggleClass('chosen');
/*
Attempt to find current placement, to see if we could change the span rules based on results. Probably disregard.
*/
var colCount = $('div.wrapper').css('grid-template-columns').split(' ').length;
console.log(colCount);
var placement = $(this).css('grid-row');
console.log(placement);
});
body {
margin: 0;
padding: 0;
background-color: #eee;
}
.wrapper {
display: grid;
margin: 18px;
grid-template-columns: repeat(auto-fill, minmax(252px, 1fr));
grid-auto-rows: 286px;
grid-gap: 18px;
}
.tile {
position: relative;
background-color: #eee;
background-color: #149;
text-align: center;
box-shadow:
0 3px 12px rgba(0,0,0, 0.15),
0 4px 6px rgba(0,0,0, 0.25);
}
.tile.chosen {
grid-row: span 2;
grid-column: span 2;
}
.tile.chosen::before {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
content: " ";
background-color: rgba(255,255,255,.2);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="tile">A</div>
<div class="tile">B</div>
<div class="tile">C</div>
<div class="tile">D</div>
<div class="tile">E</div>
<div class="tile">F</div>
<div class="tile">G</div>
<div class="tile">H</div>
<div class="tile">I</div>
</div>
The CSS grid-auto-flow
property controls how auto-placed grid items are placed in the grid.
This property has three possible values:
row
(the default)column
dense
With dense
, the auto-placement algorithm fills unoccupied cells with items that fit.
Here's your code, with grid-auto-flow: dense
on the grid container:
$('div.tile').click(function() {
$('div.tile').not(this).removeClass('chosen');
$(this).toggleClass('chosen');
var colCount = $('div.wrapper').css('grid-template-columns').split(' ').length;
console.log(colCount);
var placement = $(this).css('grid-row');
console.log(placement);
});
body {
margin: 0;
padding: 0;
background-color: #eee;
}
.wrapper {
display: grid;
margin: 18px;
grid-template-columns: repeat(auto-fill, minmax(252px, 1fr));
grid-auto-rows: 286px;
grid-gap: 18px;
grid-auto-flow: dense; /* NEW */
}
.tile {
position: relative;
background-color: #eee;
background-color: #149;
text-align: center;
box-shadow: 0 3px 12px rgba(0, 0, 0, 0.15), 0 4px 6px rgba(0, 0, 0, 0.25);
}
.tile.chosen {
grid-row: span 2;
grid-column: span 2;
}
.tile.chosen::before {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
content: " ";
background-color: rgba(255, 255, 255, .2);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="tile">A</div>
<div class="tile">B</div>
<div class="tile">C</div>
<div class="tile">D</div>
<div class="tile">E</div>
<div class="tile">F</div>
<div class="tile">G</div>
<div class="tile">H</div>
<div class="tile">I</div>
</div>
revised codepen
From the spec:
7.7. Automatic Placement: the
grid-auto-flow
propertyGrid items that aren’t explicitly placed are automatically placed into an unoccupied space in the grid container by the auto-placement algorithm.
grid-auto-flow
controls how the auto-placement algorithm works, specifying exactly how auto-placed items get flowed into the grid.
row
The auto-placement algorithm places items by filling each row in turn, adding new rows as necessary. If neither
row
norcolumn
is provided,row
is assumed.
column
The auto-placement algorithm places items by filling each column in turn, adding new columns as necessary.
dense
If specified, the auto-placement algorithm uses a “dense” packing algorithm, which attempts to fill in holes earlier in the grid if smaller items come up later. This may cause items to appear out-of-order, when doing so would fill in holes left by larger items.
The CSS Grid specification provides many properties and methods for sizing and positioning grid items. So if you don't have to rely on auto placement, use defined placement for more control.
grid-container {
display: grid;
grid-template-rows: repeat(4, 25%);
grid-template-columns: repeat(4, 25%);
grid-gap: 5px;
width: 400px;
height: 400px;
}
[left]:hover {
grid-column: -1 / -3;
grid-row: 1 / 2;
background-color: orange
}
[right]:hover {
grid-column: 1 / 3;
grid-row: 2 / 3;
background-color: orange
}
[down]:hover {
grid-column: -1 / -2;
grid-row: 2 / 4;
background-color: orange
}
[up]:hover {
grid-column: 3 / 4;
grid-row: -4 / -2;
background-color: orange
}
grid-item {
background-color: lightgreen;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
}
<grid-container>
<grid-item></grid-item>
<grid-item></grid-item>
<grid-item></grid-item>
<grid-item left>HOVER<br>to go left</grid-item>
<grid-item right>HOVER<br>to go right</grid-item>
<grid-item></grid-item>
<grid-item></grid-item>
<grid-item down>HOVER<br>to go down</grid-item>
<grid-item></grid-item>
<grid-item></grid-item>
<grid-item up>HOVER<br>to go up</grid-item>
<grid-item></grid-item>
</grid-container>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With