Reputation: 834
I'm building an app that needs a grid system, here's how far I've come:
I have a problem: Each of the blocks should fill up the entire space of the grid
As you can see, the black block is not occupying the rest of the space. I want the boxes to occupy the rest white space(but all their widths should be the same).
I've read Expand a div to fill the remaining width and Make last element take remaining width with wrapping (and with IE9 support), but they don't answer the case of the dynamically wrapping grid that is here the important part since they are made for float
and display: block
.
Now let's look at the code:
HTML:
<div className='container'>
<div className="item"></div>
<div className="item"></div>
<div className="item"></div>
<div className="item"></div>
<div className="item"></div>
<div className="item"></div>
<div className="item"></div>
</div>
CSS:
container {
overflow: hidden;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}
.item {
height: 300px;
min-width: 300px;
background-color: red;
border: 2px solid yellow;
}
.container
is the grid parent and .item
s are the children. Keep in mind that the solution should work with any number of children(.item
). Thank you in advance!
Upvotes: 1
Views: 95
Reputation: 5767
I think with plain css this is not possible using grid. You could use flexbox with flex-grow
instead of grid but when two items wrap in the next line they both are expanded.
Working example (a bit smaller then your example):
I don't know what that className
attribute in your divs is for, i presume you meant just "class" and used that, respectively an id in the container for simplicity.
#container {
overflow: hidden;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.item {
height: 120px;
min-width: 120px;
background-color: red;
border: 2px solid yellow;
flex-grow: 1;
}
#last {
flex-grow: 2;
}
<div id='container'>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item" id="last"></div>
</div>
If it is important to use grid it can be done with a small javascript function. Find out how many columns the grid has and in which column the item starts and set its gridColumnStart
and gridColumnEnd
so that it uses all the remaining grid areas. For beeing responsive you have to add an event listener that reacts on resize
and calls the expand function.
Working example:
const container = document.querySelector('#container');
const last_item = document.querySelector('#last');
function expandLastItem() {
const container_style = window.getComputedStyle(container);
const item_style = window.getComputedStyle(last_item);
const offset_left = last_item.offsetLeft;
const grid_width = parseInt(container_style.width);
const item_width = parseInt(item_style.width);
const row_length = Math.floor(grid_width / item_width);
const grid_column = Math.floor(offset_left / item_width) + 1;
last_item.style.gridColumnStart = grid_column;
last_item.style.gridColumnEnd = row_length + 1;
}
window.addEventListener('resize', function() {
last_item.style.gridColumnStart = '';
last_item.style.gridColumnEnd = '';
expandLastItem();
});
expandLastItem();
#container {
overflow: hidden;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
}
.item {
height: 120px;
min-width: 120px;
background-color: red;
border: 2px solid yellow;
}
<div id='container'>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item" id="last"></div>
</div>
If you are using jQuery the code gets a bit simpler.
Working example:
function expandLastItem() {
const offset_left = $('#last').offset().left;
const grid_width = parseInt($('#container').width());
const item_width = parseInt($('#last').width());
const row_length = Math.floor(grid_width / item_width);
const grid_column = Math.floor(offset_left / item_width) + 1;
$('#last')[0].style.gridColumnStart = grid_column;
$('#last')[0].style.gridColumnEnd = row_length + 1;
}
$(window).on('resize', function() {
$('#last')[0].style.gridColumnStart = '';
$('#last')[0].style.gridColumnEnd = '';
expandLastItem();
});
expandLastItem();
#container {
overflow: hidden;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
}
.item {
height: 120px;
min-width: 120px;
background-color: red;
border: 2px solid yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='container'>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item" id="last"></div>
</div>
Upvotes: 1