How to align half div with css grid? - html

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>

Related

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

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>

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>

List of card with ads on float right using flex or grid

I want to implement this html structure. I tried using flex but doesn't work as last ads column is not the same height and can take up to 2 - 4 rows. and i want to make it responsive too so on resize cards will go on next row if they did not find enough space.
.ads {
display: flex;
flex-direction: column;
justify-content: flex-start;
grid-column: 6 / span 2;
grid-row: 1 / span 3;
margin: 0;
float: none;
}
.container {
display: grid;
grid-gap: 22px;
justify-content: space-between;
}
.card {
margin:0;
}
Good news is - we can add ads in a parent container, which is 3 rows height. Here you go
.main-grid {
display: grid;
grid-template-columns: repeat(7, 1fr); /* determines 7 columns with same width */
grid-auto-rows: minmax(100px, auto); /* determines the height of the row */
grid-column-gap: 10px;
grid-row-gap: 10px;
}
.main-grid>div {
background: #eee;
}
.main-grid>div.ads-grid {
background: none;
grid-area: 1 / 6 / 4 / 8; /* row-start / column-start / row-end / column end */
display: grid;
grid-template-columns: 1fr;
grid-template-rows: repeat(2, 1fr);
grid-column-gap: 10px;
grid-row-gap: 10px;
}
.main-grid>div.ads-grid>div {
background: #000;
}
/* example for screens less than 460 */
#media (max-width: 460px) {
.main-grid {
grid-template-columns: repeat(4, 1fr);
}
.main-grid>div.ads-grid {
grid-area: 1 / 3 / 4 / 5;
}
}
<div class="main-grid">
<div class="ads-grid">
<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></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
Don't forget to correct .main-grid {grid-template-columns: repeat(7, 1fr)} and .main-grid>div.ads-grid {grid-area: 1 / 6 / 4 / 8;} with #media width changing for small screens. More about grid-area here https://developer.mozilla.org/en-US/docs/Web/CSS/grid-area
And not a single flex was given that day.

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>

Is it possible to explicitly make a grid item appear always on the last row or last column?

I want to place a grid item to be always on the last row and / or on the last column of a grid. Even if I don't know how many rows or columns the grid might have. Is something like that possible?
This would be my grid:
.columns {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min-content, 16.5rem));
grid-gap: 1rem;
}
I only found placement by explicit rows or columns:
MDN
Following my comment; from https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Line-based_Placement_with_CSS_Grid#Counting_backwards
We can also count backwards from the block and inline end of the grid, for English that would be the right hand column line and final row line. These lines can be addressed as -1, and you can count back from there – so the penultimate line is -2.
You can use a pseudo element :after to place an element at the end of the grid - see demo below:
.columns {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min-content, 16.5rem));
grid-gap: 1rem;
}
.columns div {
border: 1px solid;
height: 100px;
}
.columns:after {
content:'';
display: block;
border: 1px solid red;
height: 100px;
}
<div class="columns">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
Or you can use order property to place the element to the end - if any other grid item has order property, just give a large value. See demo below:
.columns {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min-content, 16.5rem));
grid-gap: 1rem;
}
.columns div {
border: 1px solid;
height: 100px;
}
.columns .last {
order: 1;
border: 1px solid red;
}
<div class="columns">
<div></div>
<div></div>
<div></div>
<div class="last"></div>
<div></div>
<div></div>
<div></div>
</div>