CSS Grid auto-flow dense only changes flow of narrow elements - html

My grid has 1fr and 3fr wide elements. Both elements have the same height.
This is how the grid looks with normal row flow:
This is how grid looks with "grid-auto-flow: dense":
As you can observe, the last narrow element moves upwards to fill the gap, but still leaves a gap before the 3fr cell.
This is how I would expect the "grid-auto-flow: dense" to work:
Is there any way to make the grid-auto-flow: dense reflow wide elements to completely avoid gaps?
Thank you.

Grid can't change order of element than way. As a solution I can suggest a little trick. Lats agree that our 3fr element will always be the last one in query. So at that point we could add to it some simple check using :nth-child()
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: auto;
grid-gap: 10px;
margin-bottom: 100px;
}
.grid>div {
height: 100px;
background: #ddd;
}
.three {
grid-column: 1 / 4;
grid-row: 1; /* starts form the fist row gap*/
}
.three:nth-child(4),
.three:nth-child(5),
.three:nth-child(6) {
grid-row: 2;
}
.three:nth-child(7),
.three:nth-child(8),
.three:nth-child(9),
.three:nth-child(n+9) /* for any element position > 9 */ {
grid-row: 3;
}
<div class="grid">
<div></div>
<div></div>
<div class="three"></div>
</div>
<div class="grid">
<div></div>
<div></div>
<div></div>
<div></div>
<div class="three"></div>
</div>
<div class="grid">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div class="three"></div>
</div>

Related

Is it possible to place all the items in grid in one row when I don't know the number of columns?

I'm trying to make a grid container that has undefined number of columns and I want it to be one row. Is there any way to do this in CSS?
.grid {
display: grid;
grid-gap: 5px;
}
.grid > div {
background: #ccc;
min-height: 100px;
}
<div class="grid">
<div></div>
<div></div>
<div></div>
</div>
There is two ways actually.
Using grid-template-columns: repeat(auto-fit, minmax(1px, 1fr));. Fits new columns automatically and determines it's mimimum and maximum width. More about Grid Template Columns and auto-fit/auto-fill.
Using grid-auto-flow: column;. Determines automatically placement behavior of grid cells. More about Grid auto flow.
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(1px, 1fr));
grid-gap: 5px;
margin-bottom: 5px;
}
.grid2 {
display: grid;
grid-auto-flow: column;
grid-gap: 5px;
margin-bottom: 5px;
}
.grid > div, .grid2 > div {
background: #ccc;
min-height: 100px;
}
<div class="grid">
<div></div>
<div></div>
<div></div>
</div>
<div class="grid2">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>

Is it possible to have a large cell in the middle of a Bootstrap 3 grid?

Is it possible to have a larger nested cell that spans rows and columns using the Bootstrap 3 Grid CSS?
No need any bootstrap. You only need to setup one cell using grid-area. More about it here https://developer.mozilla.org/en-US/docs/Web/CSS/grid-area
Browsers support of grid-area https://caniuse.com/#search=grid-area thanks to Gerard
.grid {
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: repeat(4, 1fr);
grid-column-gap: 5px;
grid-row-gap: 5px;
min-height: 300px;
}
.grid > div {
background: #ccc;
}
.grid > div.my-big-sell {
grid-area: 2 / 2 / 4 / 6;
background: #000;
}
<div class="grid">
<div class="my-big-sell"> </div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>

How to align half div with css grid?

I have four divs. How do I align the second and third in one line? (50% each)
I have tried to do the following:
.wrap { display:grid; grid-template-columns:1fr; grid-template-rows:1fr "auto auto" 1fr; }
.wrap > div {border:1px solid; background:#4472C4;}
<div class="wrap">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
But chrome doesn't apply this style. maybe I am doing this wrong.
How do I fix it?
grid-template-rows:1fr "auto auto" 1fr;
This is nonsense. grid-template-rows provides a template for the size of each column in every row.
It doesn't describe each row one by one.
"auto auto" is not a valid size.
Create a 2x3 grid, then make the first and last elements span multiple cells in it.
div {
border: solid #aaa 1px
}
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
grid-template-areas: "Top Top" "Left Right" "Bottom Bottom";
}
.Top {
grid-area: Top;
}
.Left {
grid-area: Left;
}
.Right {
grid-area: Right;
}
.Bottom {
grid-area: Bottom;
}
<div class="grid-container">
<div class="Top">Top</div>
<div class="Left">Left</div>
<div class="Right">Right</div>
<div class="Bottom">Bottom</div>
</div>
You can specify a grid of two columns, and set grid-column: span 2 for the items you want to have full width.
.wrap {
display: grid;
grid-template-columns: 1fr 1fr;
}
.wrap>div {
border: 1px solid;
background: #4472C4;
min-height: 2em;
margin:0.3em;
}
.wrap>div:nth-child(3n+1) {
grid-column: span 2;
}
<div class="wrap">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>

How to reverse the css grid columns order?

I want to be able to reverse the order of columns (the 2 small to the left, the big one right). I've tried several solutions but didn't find one that works.
Here's the code:
.images-block-box{
display: grid;
grid-gap: 16px;
grid-template-columns: 708fr 340fr;
& > div:first-child{
grid-row: span 2;
}
&.reverse{
grid-template-columns: 340fr 708fr;
& > div:first-child{
order: 2; // doesn't work (I want to place the first item at the end of the 3)
}
}// reverse
}// images-block-box
Note that I really want to reverse the order of the columns themselves, not just their dimensions.
Simply adjust grid-column and conisder grid-auto-flow:dense; to allow the next elements to be placed before:
.grid {
display: grid;
grid-gap: 16px;
grid-template-columns: 2fr 1fr;
grid-auto-flow:dense;
margin:5px;
}
.grid div {
min-height: 50px;
border: 1px solid;
}
.grid div:first-child {
grid-row: span 2;
}
.grid.reverse {
grid-template-columns: 1fr 2fr;
}
.grid.reverse div:first-child {
grid-column:2;
}
<div class="grid">
<div></div>
<div></div>
<div></div>
</div>
<div class="grid reverse">
<div></div>
<div></div>
<div></div>
</div>
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.ref
Another option is to place the big box to the last column by using grid-column-end: -1 - see demo below:
.images-block-box {
display: grid;
grid-gap: 16px;
grid-template-columns: 708fr 340fr;
grid-template-rows: 100px 100px;
grid-auto-flow: column;
}
.images-block-box>div {
border: 1px solid;
}
.images-block-box>div:first-child {
grid-row: span 2;
}
.images-block-box.reverse {
grid-template-columns: 340fr 708fr;
}
.images-block-box.reverse>div:first-child {
grid-column-end: -1;
}
<div class="images-block-box">
<div></div>
<div></div>
<div></div>
</div>
<br/>
<div class="images-block-box reverse">
<div></div>
<div></div>
<div></div>
</div>
grid-column-end
<integer> && <custom-ident>?
Contributes the nth grid line to the grid
item’s placement. If a negative integer is given, it instead counts in
reverse, starting from the end edge of the explicit grid.
Since there are 2 answers that could be marked as accepted (thanks to #kukkuz and #Temani Afif) I'm posting here a sum up. The working techniques pointed out till now are:
grid-auto-flow: dense (container) + grid-column: 2 (first-child)
grid-auto-flow: column (container) + grid-column-end: -1 (first-child)
The rest of the code remains the same. Please take a look at the related answers.
Both are currently working well (at least in major/modern browsers).
Then Maybe You can use a different approach
.grid {
display: grid;
grid-template-columns: 5fr 2fr;
grid-template-rows: 1fr 1fr;
height: 500px;
grid-gap: 2rem;
}
.one {
background-color: red;
grid-row: 1 / 3;
}
.two {
background-color: green;
}
.three {
background-color: blue;
}
.reverse > .one {
grid-column: 2 / 3;
grid-row: 2 / 3;
}
.reverse > .three {
grid-column: 1 / 2;
grid-row: 1 / 3;
}
<h1>Without Reverse</h1>
<div class="grid">
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
</div>
<h1>With Reverse</h1>
<div class="grid reverse">
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
</div>

CSS Grid Column Stretch to Fill Entire Row / Or Centered In Row? [duplicate]

This question already has answers here:
Aligning grid items across the entire row/column (like flex items can)
(3 answers)
Closed 4 years ago.
I have a basic grid setup as follows:
.grid-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(33rem, 1fr));
grid-gap: 1rem;
}
When the grid auto-breaks into new rows, I either want the elements on the new rows to take up a proportional amount of space or be centered so that they look nice.
For example, if I have 3 elements in one row, then I want each to take up 33% of the container space. But when the grid breaks and only 1 element is on the new row, I want that element to either take up 100% of the row width, or at least look centered -- which is contrary to the default behavior of placing the element all the way to the left and taking up only 1fr of space.
Similarly, if there are 2 elements on the new row, then each should take up 50% of the row space or the two together should look centered.
I don't know how many elements there will be in total. Ideally, the solution should work for a minimum of 1 up to an arbitrary number of elements.
If anyone has any ideas, please let me know. Thanks.
This is a job for flexbox, I don't think it will be easy to achieve with CSS grid:
.grid-container {
display: flex;
flex-wrap:wrap;
border:1px solid;
margin:2px;
}
.grid-container>div {
height: 50px;
background: red;
margin: .5rem;
flex: 1 1 calc(33% - 1rem);
}
<div class="grid-container">
<div></div>
<div></div>
<div></div>
</div>
<div class="grid-container">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div class="grid-container">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
If you want the element to be centred simply do this:
.grid-container {
display: flex;
flex-wrap:wrap;
border:1px solid;
margin:2px;
justify-content:center;
}
.grid-container>div {
height: 50px;
background: red;
margin: .5rem;
flex: 0 1 calc(33% - 1rem); /*disable the flex-grow*/
}
<div class="grid-container">
<div></div>
<div></div>
<div></div>
</div>
<div class="grid-container">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div class="grid-container">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>