Grid-column-end property leaves blank area
I am trying to display the last 3 elements of a container in a horizontal line. The first 2 take up fixed space and the last item takes up all columns.
I am trying to achieve this result using CSS Grid.
So far I have been able to make a working prototype when the grid is full (more than 3 elements).
But as you can see in the snippet below, if there are less than 3 items, the last column ends up on the right in the grid, but leaves a gap in the grid.
I have tried indicating grid-column: auto / -1;
instead grid-column-end
with no luck.
I am using Chrome but tested it in Firefox too.
What could be causing this gap and is there a good way to fix it using just CSS?
EDIT: Completed script and added expected output
.demo {
max-width: 500px;
background-color: #abcdef;
border-radius: 3px;
padding: 5px;
margin-bottom: 5px;
}
.demo>.demo {
background-color: #fedcba;
}
.main {
display: grid;
grid-template-columns: repeat(2, 100px) 1fr;
grid-gap: 1px;
}
.main>.column:last-child {
grid-column-end: -1;
}
.main>.column:nth-last-child(n+4) {
display: none;
}
<div class="demo main">
<div class="demo column">1</div>
<div class="demo column">2</div>
<div class="demo column">3</div>
<div class="demo column">4</div>
</div>
<div class="demo main">
<div class="demo column">1</div>
<div class="demo column">2</div>
<div class="demo column">3</div>
</div>
<div class="demo main">
<div class="demo column">1</div>
<div class="demo column">2</div>
</div>
<div class="demo main">
<div class="demo column">1</div>
</div>
Expected Result:
You hide the elements using this CSS.
.main > .column:nth-last-child(n+4) {
display: none;
}
So, you need some additional adjustments:
-
Select the first child and add
grid-column-start: 1;
using.main > .column:first-child { grid-column-start: 1; }
-
Select a second child, he is the brother of the first visible child and add
grid-column-start: 2;
using.main > .column:not(:nth-last-child(n+4)) + .column:nth-child(2) { grid-column-start: 2; }
Result:
.demo {
max-width: 500px;
background-color: #abcdef;
border-radius: 3px;
padding: 5px;
margin-bottom: 5px;
}
.demo > .demo {
background-color: #fedcba;
}
.main {
display: grid;
grid-template-columns: repeat(2, 100px) 1fr;
grid-gap: 1px;
}
.main > .column:first-child {
grid-column-start: 1;
}
.main > .column:not(:nth-last-child(n+4)) + .column:nth-child(2) {
grid-column-start: 2;
}
.main > .column:last-child {
grid-column-end: -1;
}
.main > .column:nth-last-child(n+4) {
display: none;
}
<div class="demo main">
<div class="demo column">1</div>
<div class="demo column">2</div>
<div class="demo column">3</div>
<div class="demo column">4</div>
</div>
<div class="demo main">
<div class="demo column">1</div>
<div class="demo column">2</div>
<div class="demo column">3</div>
</div>
<div class="demo main">
<div class="demo column">1</div>
<div class="demo column">2</div>
</div>
<div class="demo main">
<div class="demo column">1</div>
</div>
I think you want to do the second cell collapse if there is no content for it.
You can achieve this with
grid-template-columns: 100px auto 1fr;
.demo {
max-width: 500px;
background-color: #abcdef;
border-radius: 3px;
padding: 5px;
}
.demo>.demo {
background-color: #fedcba;
}
.main {
display: grid;
grid-template-columns: auto auto 1fr;
grid-gap: 1px;
}
.main>.column:last-child {
grid-column-end: -1;
}
.main > .column:nth-last-child(n+2) {
width: 100px;
}
.main>.column:nth-last-child(n+5) {
display: none;
}
<div class="demo main">
<div class="demo column">6</div>
<div class="demo column">7</div>
</div>
<div class="demo main">
<div class="demo column">5</div>
<div class="demo column">6</div>
<div class="demo column">7</div>
</div>
With two grid items, there is a gap in the grid because you have the last child starting at the end of the container:
.main > .column:last-child {
grid-column-end: -1;
}
This can work well if there are at least three items in the container, because all the cells are occupied. But with less than three, will grid-column-end: -1
move the last element to the last column. ( Negative integers start from the end of the container. )
You showed the problem with two items. The same problem exists even with one element:
.main {
display: grid;
grid-template-columns: repeat(2, 100px) 1fr;
grid-gap: 1px;
}
.main>.column:last-child {
grid-column-end: -1;
}
.demo {
max-width: 500px;
background-color: #abcdef;
border-radius: 3px;
padding: 5px;
}
.demo>.demo {
background-color: #fedcba;
}
.main>.column:nth-last-child(n+5) {
display: none;
}
<div class="demo main">
<div class="demo column">7</div>
</div>
If you want the last child to occupy the second column, instead:
grid-column-end: -1;
Try the following:
grid-column: 2 / -1;
.main {
display: grid;
grid-template-columns: repeat(2, 100px) 1fr;
grid-gap: 1px;
}
.main>.column:last-child {
grid-column: 2 / -1;
}
.demo {
max-width: 500px;
background-color: #abcdef;
border-radius: 3px;
padding: 5px;
}
.demo>.demo {
background-color: #fedcba;
}
.main>.column:nth-last-child(n+5) {
display: none;
}
<div class="demo main">
<div class="demo column">6</div>
<div class="demo column">7</div>
</div>
Or, if you want the last element when there are less than three to take up the second column, instead of using, :last-child
use nth-child()
, for example:
.main > .column:nth-child(3) {
grid-column-end: -1;
}
.main {
display: grid;
grid-template-columns: repeat(2, 100px) 1fr;
grid-gap: 1px;
}
.main>.column:nth-child(3) {
grid-column-end: -1;
}
.demo {
max-width: 500px;
background-color: #abcdef;
border-radius: 3px;
padding: 5px;
}
.demo>.demo {
background-color: #fedcba;
}
.main>.column:nth-last-child(n+5) {
display: none;
}
<div class="demo main">
<div class="demo column">6</div>
<div class="demo column">7</div>
</div>