CSS - Grid positioning if element does not exist - css

Is it possible to prepare the grid in such a way that if a given element is not present, it inserts the elements that are available? For example, if there is no first element, then in the first row we have "item middle item"?
<div class="grid-container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="middle"></div>
</div>
.grid-container {
display: grid;
grid-template-rows: repeat(3, auto);
grid-template-columns: repeat(3, 1fr);
grid-gap: 20px;
grid-template-areas:
"first first first"
". middle ."
". . .";
}
Example

If you add the following, that should do it:
.item:empty {
display: none;
}
You can see in this example, everything will back-fill into empty grid cells.
.grid-container {
display: grid;
grid-template-rows: repeat(3, auto);
grid-template-columns: repeat(3, 1fr);
grid-gap: 20px;
grid-template-areas:
"first first first"
". middle ."
". . .";
}
.item:empty {
display: none;
}
<div class="grid-container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="middle">m</div>
</div>

Related

css grid fit rows heights

I want to remove the worthless margin between rows, so I want every div takes the content height without giving margin to his side div, I tried everything but nothing works.
.grids {
width: 90%;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: minmax(min-content, max-content);
margin: auto;
grid-gap: 32px;
}
.grid {
position: relative;
width: 95%;
height: max-content;
margin: 10px;
padding: 20px;
background: black;
border-radius: 10px;
}
<div class="grids">
<div class="grid"></div>
<div class="grid"></div>
<div class="grid"></div>
<div class="grid"></div>
<div class="grid"></div>
<div class="grid"></div>
</div>
Edit: To make a masonry layout I have wrapped grid items in div tag
so you can nest as many tags as you want.
grid items overflow the content because of the width and height properties.
you're using a grid gap for both rows and columns.
So I guess this might help you out.
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
grid-template-rows: masonry;
grid-gap: 10px;
}
.grid-item {
padding: 20px;
background: red;
border-radius: 10px;
margin-bottom: 24px;
}
<div class="grid">
<div>
<div class="grid-item">
<h1>Hello world</h1>
</div>
<div class="grid-item">
<h1>Hello world</h1>
</div>
</div>
<div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
</div>
<div>
<div class="grid-item">
<h1>Hello
<br>
friend
</h1>
</div>
<div class="grid-item"></div>
</div>
</div>
Also, I renamed the classes for naming purposes only.
MDN docs grid-row: row-gap
MDN docs masonry layout: masonry layout
You can try to set grid-gap: 32px to grid-gap: 0 32px, it will remove the margin between grid rows;

Move only one item in CSS Grid

Okay i know i can move my blocks using grid-template-areas or order.
But my question is: can i move only one item to another place without changing order of every other block? Because that is a few lines more of code and i wonder if it can be made easier?
I have a grid:
grid-template-rows: repeat(3, 1fr);
grid-template-columns: repeat(2, 1fr);
I want the item on the 1-st column and 1-st row to change position to 2-nd column and 1-st row. To switch places with the other block.
Simply specify the position using grid-column (and grid-row if needed) and make sure to use grid-auto-flow:dense to avoid empty areas:
.box {
display:grid;
grid-template-rows: repeat(3, 1fr);
grid-template-columns: repeat(2, 1fr);
grid-auto-flow: dense;
grid-gap:10px;
}
.box * {
height:50px;
background:red;
color:#fff;
}
<div class="box">
<div style="grid-column:2">1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
</div>
You can still use order. Just set all the children to order:1 and then set the order of the chosen item to 0
.grid {
display: grid;
grid-template-rows: repeat(3, 1fr);
grid-template-columns: repeat(2, 1fr);
}
.item {
border: 1px solid green;
padding: 1em;
}
.grid * {
order:1;
}
.grid :nth-child(2) {
order:0;
}
<div class="grid">
<div class="item">Item 1</div>
<div class="item">Item 2</div>
<div class="item">Item 3</div>
<div class="item">Item 4</div>
<div class="item">Item 5</div>
<div class="item">Item 6</div>
</div>

Place all items in the center of the screen using CSS Grid

So basically what i want to do is to have 9 Boxes in the middle of the screen.
This is what i tried:
main {
border: 4px solid black;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr;
width: 100vw;
height: 100vh;
align-items: center;
justify-items: center;
}
.box1 {
background: red;
width: 50%;
}
.box2 {
background: blue;
width: 50%;
}
.box3 {
background: green;
width: 50%;
}
<main>
<div class="box1">
<h1>Box 1</h1>
</div>
<div class="box2">
<h1>Box 2</h1>
</div>
<div class="box3">
<h1>Box 3</h1>
</div>
<div class="box1">
<h1>Box 4</h1>
</div>
<div class="box2">
<h1>Box 5</h1>
</div>
<div class="box3">
<h1>Box 6</h1>
</div>
<div class="box1">
<h1>Box 7</h1>
</div>
<div class="box2">
<h1>Box 8</h1>
</div>
<div class="box3">
<h1>Box 9</h1>
</div>
</main>
This almost does what i want.
So what i get is this:
-b-b-b-
-b-b-b-
-b-b-b-
with - being free space.
What i want is this:
-bbb-
-bbb-
-bbb-
so that the 9 boxes actually touch each other.
Is there a way to do that?
(i want to hold on to the grid-template-columns: 1fr 1fr 1fr and grid-template-rows: 1fr 1fr 1fr)
tyvm :)
Is there a way to do that? (i want to hold on to the grid-template-columns: 1fr 1fr 1fr and grid-template-rows: 1fr 1fr 1fr)
No. There is no way to do this.
Because you've set your columns to 1fr each, they will spread across the width of the container in equal lengths. Therefore, the columns are not centered.
You would have to do something like this: grid-template-columns: 1fr auto auto auto 1fr, with the 1fr columns having no content and used solely for spacing. This set up would pin the three inner columns to the center.

Bootstrap Column Width Ratios

The Bootstrap grid system is of course 12 columns.
I want to have and use all the 12 columns across the page.
But I want the first 6 left-hand columns to be half the width (i.e 50%) of the right-hand columns width.
So that the right 6 column will always be double width of the ones on the left.
This width ratio should remain across changing page/window resizing.
How can I do that? Thanks.
This task is not for a boostrap grid system. 12 parts mean 12 equal width parts. And you want not equal 12 block. This is a task for display: grid;.
grid-template-columns: repeat(6, 2fr) repeat(6, 1fr); this part means that we take 6 times for 2fr and then 6 times for 1fr. fr is a new measure for grid. It means all grid is devides on a sum all frs in one row. So 2fr is a block twice bigger then 1fr. In our case we have 2fr 2fr 2fr 2fr 2fr 2fr 1fr 1fr 1fr 1fr 1fr 1fr = 18 parts in a row. It's just for you to know hove does fr works.
Links for some CSS Grid documentation:
Basic Concepts of grid layout
grid-template-columns
.grid-row {
display: grid;
grid-template-columns: repeat(6, 2fr) repeat(6, 1fr);
grid-auto-rows: auto;
grid-row-gap: .5rem;
grid-column-gap: .5rem;
}
.grid-col {
background: #000;
min-height: 50px;
}
/* example of adaptivity for smaller screens */
#media (max-width: 500px) {
.grid-row {
grid-template-columns: repeat(3, 2fr) repeat(3, 1fr);
}
}
<div class="grid-row">
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
</div>
Not sure, but if you want not twice, but 1.5 times wider cols, use next one. Updated only grid-template-columns: repeat(6, 3fr) repeat(6, 2fr);
.grid-row {
display: grid;
grid-template-columns: repeat(6, 3fr) repeat(6, 2fr);
grid-auto-rows: auto;
grid-row-gap: .5rem;
grid-column-gap: .5rem;
}
.grid-col {
background: #000;
min-height: 50px;
}
/* example of adaptivity for smaller screens */
#media (max-width: 500px) {
.grid-row {
grid-template-columns: repeat(3, 3fr) repeat(3, 2fr);
}
}
<div class="grid-row">
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
<div class="grid-col"></div>
</div>

Center CSS grid when there are less items than columns

Let's say I have a simple grid which puts items in 4 columns filling the entire container width:
.container {
background: lightyellow;
padding: 10px 20%;
text-align: center;
}
.grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 10px;
justify-content: center;
}
.item {
height: 100px;
background-color: red;
}
.container + .container {
margin-top: 30px;
}
<div class="container">
<h1>News</h1>
<div class="grid">
<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>
</div>
<div class="container">
<h1>News</h1>
<div class="grid">
<div class="item"></div>
<div class="item"></div>
</div>
</div>
As you can see, this works perfectly but only until I have 4 or more items. If I have less items, they are placed into the corresponding cells but as the right cells are empty, visually the grid starts to look "left aligned". This is not cool if the container itself is centered on the page, as in the example above.
How do I center the grid when it has 3 or less items? I tried using repeat(auto-fit, 25%) but it doesn't take grid-gap into account. repeat(auto-fit, minmax(25%, 1fr)) stretches content instead of centering it.
May be this is what you want:
It's using auto columns instead of template columns.
.grid {
display: grid;
grid-auto-columns: 22%;
grid-gap: 10px;
justify-content: center;
width: 200px;
border: solid 1px black;
grid-auto-flow: column;
}
.item {
height: 50px;
background-color: red;
}
<div class="grid">
<div class="item"></div>
</div>
<div class="grid">
<div class="item"></div>
<div class="item"></div>
</div>
<div class="grid">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="grid">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
maybe it is a late answer but here is what i came up with :
If you want to use repeat so the content automatically fits 4 columns (in this case), all you have to do is :
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, 25%);
justify-content: center;
justify-items: center;
}
That is because the container is lets say 100%, and if you want to fit 4 columns, then simply calculate 1/4 of 100% which is 25%.
"grid-template-columns" has 25% but I have to put 20% because of the gap between the cards.
if there is no gap, just increase %.
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, 20%);
grid-gap: 10px;
justify-content: center;
}
.item {
height: 100px;
background-color: red;
}
<div class="grid">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>

Resources