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>
Related
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;
I want to make a grid in footer where the text is above the grid but also staying in the grid. Position: absolute don't work because it effects both grid and text, and i want to move them independently of each other.
How it looks:
https://i.imgur.com/norbzp1.png
How i want it to be:
https://i.imgur.com/1fYoQIF.png
Code:
<div class="footer">Footer
<div class="icon"></div>
<div class="icon"></div>
<div class="icon"></div>
<div class="icon"></div>
<div class="icon"></div>
<div class="icon"></div>
</div>
And css:
.footer{
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-auto-rows: 50px;
grid-gap: 10px;
}
.icon{
display: flex;
background: rgb(160, 84, 84);
}
You can achieve this by wrapping the grid and the footer with a container.
.footer-header {
text-align: center;
padding:20px;
}
.footer-grid {
grid-column: span 3 / auto;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-auto-rows: 50px;
grid-gap: 10px;
}
.icon{
display: flex;
background: rgb(160, 84, 84);
}
<div class="footer">
<div class="footer-header">
Footer
</div>
<div class="footer-grid">
<div class="icon">1</div>
<div class="icon">2</div>
<div class="icon">3</div>
<div class="icon">4</div>
<div class="icon">5</div>
<div class="icon">6</div>
</div>
</div>
Also you can use grid-template-areas, for example
.footer{
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-areas: "footer-head footer-head footer-head";
grid-auto-rows: 50px;
grid-gap: 10px;
}
.icon{
display: flex;
background: rgb(160, 84, 84);
}
.footer-head {
text-align: center;
grid-area: footer-head;
}
<div class="footer">
<div class="footer-head">Footer</div>
<div id="icon1" class="icon"></div>
<div class="icon"></div>
<div class="icon"></div>
<div class="icon"></div>
<div class="icon"></div>
<div class="icon"></div>
</div>
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.
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>
I'm trying to make a fully responsive grid with different-sized items.
This example works fine with
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr) ) ;
body {
margin: 40px;
}
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
background-color: #fff;
color: #444;
}
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 20px;
font-size: 150%;
}
<div class="wrapper">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box c">C</div>
<div class="box d">D</div>
<div class="box e">E</div>
<div class="box f">F</div>
<div class="box g">G</div>
<div class="box h">H</div>
<div class="box i">I</div>
</div>
All items are the same size and on the smallest screen size they line up on top of each other.
Now if you try the same with this example the items that have left the explicit grid and have to move again are not doing so but are shrinking under the specified minmax value. So on the smallest screen size some items cannot be seen.
body {
margin: 40px;
}
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
background-color: #fff;
color: #444;
}
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 20px;
font-size: 150%;
}
.a {
grid-column: auto / span 2;
}
.k {
grid-column: auto / span 3;
}
.g {
grid-column: auto / span 2;
grid-row: auto / span 2;
}
<div class="wrapper">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box c">C</div>
<div class="box d">D</div>
<div class="box e">E</div>
<div class="box f">F</div>
<div class="box g">G</div>
<div class="box h">H</div>
<div class="box i">I</div>
<div class="box j">J</div>
<div class="box k">K</div>
<div class="box l">L</div>
<div class="box m">M</div>
</div>
Is there a way to get example 2 to behave like example 1, other than adding a media-query?
There's a big hint to the answer in what you wrote:
Now if you try the same with this example, the items that have left the explicit grid and have to move again are not doing so but are shrinking under the specified minmax value.
"...the items that have left the explicit grid..."
This is why your grid items are shrinking below the minmax minimum set in grid-template-columns.
Once you're not in the explicit grid, you're in the implicit grid, and the grid-template-columns property has no effect.
The explicit grid is defined by three properties:
grid-template-columns
grid-template-rows
grid-template-areas
Tracks in the implicit grid ignore these properties. Instead, they are sized using grid-auto-rows and grid-auto-columns.
The default value of grid-auto-columns is auto, which is why your grid items shrink to content size when they exit the explicit grid.
Try this:
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr) ) ;
grid-auto-columns: minmax(200px, 1fr); /* NEW */
}
Then, optionally, to make the grid fill empty cells when re-sizing, add this, too:
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr) ) ;
grid-auto-columns: minmax(200px, 1fr); /* NEW */
grid-auto-flow: dense; /* NEW */
}
body {
margin: 40px;
}
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-auto-columns: minmax(200px, 1fr); /* NEW */
grid-auto-flow: dense; /* NEW */
}
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 20px;
font-size: 150%;
}
.a {
grid-column: auto / span 2;
}
.k {
grid-column: auto / span 3;
}
.g {
grid-column: auto / span 2;
grid-row: auto / span 2;
}
<div class="wrapper">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box c">C</div>
<div class="box d">D</div>
<div class="box e">E</div>
<div class="box f">F</div>
<div class="box g">G</div>
<div class="box h">H</div>
<div class="box i">I</div>
<div class="box j">J</div>
<div class="box k">K</div>
<div class="box l">L</div>
<div class="box m">M</div>
</div>
revised codepen
The simplest answer is no, you can't. The reason is that when you combine auto-fill and minmax(200px, 1fr) you are telling to the browser rendering your code to make grid with columns with the minimum with of 200px and the maximum of 1fr. Then you are telling to your boxes to span 2 or 3 columns which means that they have minimum width of at least 400px or 600px on the big screen. On smaller screens, span rule starts to lose its meaning but auto does not take over. It still has to calculate width of individual columns taking into account individual width differences of .a .b .c etc.
So, unfortunately, you would need to use media queries or find some other type of layout.