I'm trying to create a two-column layout with CSS grid with items flow in a column direction and I managed to create the layout but the problem is when the child items are dynamic it breaks. here's the snippet that I've tried. so basically grid-template-rows: repeat(4, auto); <4> should be dynamic it should be half of the total number of items. Is there any way that I can achieve it through CSS. Click here for fiddle
<div class="grid-container">
<div class="item1">1</div>
<div class="item2">2</div>
<div class="item3">3</div>
<div class="item4">4</div>
<div class="item5">5</div>
<div class="item6">6</div>
<div class="item7">7</div>
<div class="item8">8</div>
</div>
.grid-container {
display: grid;
grid-template-columns: 50% 50%;
grid-template-rows: repeat(4, auto);
grid-auto-flow: column;
grid-gap: 10px;
background-color: #2196F3;
padding: 10px;
}
.grid-container > div {
background-color: rgba(255, 255, 255, 0.8);
text-align: center;
padding: 20px 0;
font-size: 30px;
}
examples provided in earlier comments with column CSS did not seem to suits your needs : https://jsfiddle.net/hLnvk2b8/ , https://jsfiddle.net/hLnvk2b8/1 .
If you want to stick to the grid flowing into column with an unknown amount of rows Javascript could help you update the row's amount needed.
SASS is unable to access the document, it only compiles CSS selectors and CSS rules ,that is why you would need a script (it can be on server side too) to inspect the DOM:
example via javascript on browser's side :
window.onload = resetgrid('2');
function resetgrid(varcol) {
var colnum = varcol;/* how many columns do you want ? */
var child = document.getElementById("gridrow").childElementCount;/* how many children */
var els = child / colnum;/* how many rows could that make */
var rows = Math.round(els);/* row's number cannot be decimal */
var resetrow = document.createElement("STYLE");/* prepare to insert a style sheet */
var rowstyle = document.createTextNode(".grid-container { grid-template-columns:repeat(" + colnum + ",1fr);grid-template-rows: repeat(" + rows + ",auto);}");/* finalize the rules */
resetrow.appendChild(rowstyle);/* insert the rules inside style tag*/
document.head.appendChild(resetrow);/* insert the style tag inside head */
}
.grid-container {
display: grid;
grid-template-columns: 50% 50%;
grid-auto-flow: column;
grid-gap: 10px;
background-color: #2196F3;
padding: 10px;
}
.grid-container>div {
background-color: rgba(255, 255, 255, 0.8);
text-align: center;
padding: 20px 0;
font-size: 30px;
}
/*demo purpose*/
[data-table] {
display: table;
text-align: center;
margin: auto;
}
<!--demo purpose-->
<div data-table>
<p>reset numbers of columns </p>
<button onclick="resetgrid(1)">1</button>
<button onclick="resetgrid(2)">2</button>
<button onclick="resetgrid(3)">3</button>
</div>
<!--end demo-->
<div id="gridrow" class="grid-container">
<div class="item1">1</div>
<div class="item2">2</div>
<div class="item3">3</div>
<div class="item4">4</div>
<div class="item5">5</div>
<div class="item6">6</div>
<div class="item7">7</div>
<div class="item8">8</div>
</div>
.two-columns{
width: 300px;
height: 400px;
border: 1px solid;
display: grid;
grid-template-columns: repeat(2, 1fr);
overflow: auto;
}
Have you tried using grid-auto-flow:row; it should ideally work. Here is a fiddle for the same. I have used your fiddle for the same and made changes to only one property.jsFiddle
Related
I'm trying to solve a simple task but the solutions seem not be that simple.
Basically, I want many blocks with the same size to be aligned in center but I nee 1 block that is twice bigger than the others.
If I use FLEX - there are blank spaces around the big block.
If I use GRID - I can't align the blocks in the center.
Please help!
#all {
width: 100%;
border: 1px solid #ff0000;
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, 150px);
grid-template-rows: repeat(auto-fill, 150px);
}
#all div {
width: 150px; height: 150px;
border: 1px solid #ff0000;
}
#all .big {
width: 310px; height: 312px;
grid-column: 2/ 4;
grid-row: 2 / 4;
}
<html>
<head>
<style>
</style>
</head>
<body>
<div id=all>
<div></div>
<div></div>
<div class=big></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></div><div></div><div></div>
</div>
</body>
</html>
I need them to be aligned in the center
Here is an edited answer from W3Schools.
NOTE: there must be enough items to circle the one in the middle.
First, you need to add odd items in the grid.
Then, add odd columns to align them properly as you want.
Last, use grid-area to start any of the items from the 2nd row and column. then end it at the other corner according to the number of items in the grid.
and the good thing about this is that it's responsive and you can select any item to put it in the middle.
here is the code.
.grid-container {
display: grid;
grid-template-columns: auto auto auto ; /* odd column */
gap: 10px;
background-color: #2196F3;
padding: 10px;
}
.grid-container > div {
background-color: rgba(255, 255, 255, 0.8);
text-align: center;
padding: 20px 0;
font-size: 30px;
}
.item5 {
grid-area: 2 / 2 / 4 / 3; /* start and end the selected item */
display: flex;
justify-content: center;
align-items: center;
}
<h1>The grid-column Property</h1>
<p>Use the <em>grid-column</em> property to specify where to place an item.</p>
<div class="grid-container">
<!-- add odd items in the grid -->
<div class="item1">1</div>
<div class="item2">2</div>
<div class="item3">3</div>
<div class="item4">4</div>
<div class="item5">5</div>
<div class="item6">6</div>
<div class="item7">7</div>
<div class="item8">8</div>
<div class="item9">9</div>
<div class="item10">10</div>
<div class="item11">11</div>
</div>
The desired layout for wide screens:
The desired layout for narrow screens:
Initial CSS:
.Layout {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
grid-gap: 24px 40px;
}
If I'll set grid-column-start: span 2 for the third element, the layout will be simply broken (it' happen in CSS grid ignores minimal width specified in minmax() in second column question).
Please don't use the media queries because it will nullify the announced free-space-based responsiveness which became available in CSS grid.
Grid has two extremely powerful features for dealing with changes in
available space.
<...>
Layout that relies on media queries is tied to the view-port, this
isnβt modular β components within a system need to be able to adapt to
the space they have available.
π
Getting to know CSS Grid Layout
Please say clearly: "it's impossible" if you are sure that it so and skilled in CSS grid.
Use grid-column: 1/-1;
.box {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
grid-gap: 24px 40px;
}
span {
height: 50px;
background: blue;
}
.more {
grid-column: 1/-1;
background: red;
}
<div class="box">
<span></span>
<span></span>
<span class="more"></span>
<span></span>
<span></span>
</div>
That you can edit like below if you want to always have a maximum of 2 columns:
.box {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(max(240px,40vw), 1fr));
grid-gap: 24px 40px;
}
span {
height: 50px;
background: blue;
}
.more {
grid-column: 1/-1;
background: red;
}
<div class="box">
<span></span>
<span></span>
<span class="more"></span>
<span></span>
<span></span>
</div>
Finally I think I could handle your problem, but by using flex instead of grid. It is pretty tricky.
The main element is a class called wrapper, which has display: flex;.
You can insert your "grid items" there, now called wrapper-container.
I need this helper class to recreate the grid-gap property. Now I am using padding instead. Note that padding works a bit ditterent to grid-gap so I had to divide your gap by 2.
Each wrapper-container has a wrapper-container__item child, which contains your content. When you inspect these elements, you will notice, that they have at least a width of 240px which is caused by their min-width property.
When you want an element to span over two "columns" add the class wrapper-container__stretched to the wrapper-container. It is applying width: 100% so that the element will be fullsized. Elements which do not have the class, has flex: 1, so they will stay next to each other (just like a 2-column grid).
Feel free to ask when there are any ambiguities.
Codepen:
Responsive grid without media queries using flex-box
.wrapper{
position: relative;
width: 100%;
background: #dedede;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.wrapper-container{
position: relative;
padding: 12px 20px;
}
.wrapper-container:not(.wrapper-container__stretched){
flex: 1;
}
.wrapper-container.wrapper-container__stretched{
width: 100% !important;
}
.wrapper-container__item{
position: relative;
min-width: 240px;
min-height: 64px;
width: 100%;
}
.red{
background: #e53935;
}
.green{
background: #388e3c;
}
<section class="wrapper">
<!-- Row 1 -->
<div class="wrapper-container">
<div class="wrapper-container__item green">Item 1</div>
</div>
<div class="wrapper-container">
<div class="wrapper-container__item green">Item 2</div>
</div>
<!-- Row 2 -->
<div class="wrapper-container wrapper-container__stretched">
<div class="wrapper-container__item red">Item 3</div>
</div>
<!-- Row 3 -->
<div class="wrapper-container">
<div class="wrapper-container__item green">Item 4</div>
</div>
<div class="wrapper-container">
<div class="wrapper-container__item green">Item 5</div>
</div>
</section>
A posible solution using flex, like MichaelT
.layout {
border: solid 1px black;
margin: 2px;
position: relative;
}
.innerlayout {
display: flex;
flex-wrap: wrap;
position: relative;
left: -10px;
right: 10px;
width: calc(100% + 20px);
}
span {
background-color: green;
height: 40px;
min-width: 240px;
width: 40%;
margin: 15px 10px;
flex-grow: 1;
}
.wide {
width: 100%;
background-color: red;
}
#narrow {
width: 300px;
}
<div class="layout">
<div class="innerlayout">
<span></span>
<span></span>
<span class="wide"></span>
<span></span>
<span></span>
</div>
</div>
<div class="layout" id="narrow">
<div class="innerlayout">
<span></span>
<span></span>
<span class="wide"></span>
<span></span>
<span></span>
</div>
</div>
I have a row of items of arbitrary width. They are centered within the container (note white space on the left and right sides of the red container):
Sometimes the container gets smaller than the width of all items:
When this happens, I want the items in the end to wrap to the next row like this:
It is very imporant for me that each row's content must be left-aligned, but the grid as a whole must be centered:
Initially, I tried implementing it with FlexBox. After a lot of frustration and hair pulling, I've learned that this is impossible witn FlexBox: https://stackoverflow.com/a/32811002/901944
Another answer on the same page suggests using CSS grid instead of flexbox.
CSS grid produces a slightly different result, but that also suits me:
Here's the code that makes it work:
.red-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(210px, max-content));
justify-content: center;
}
This code contains a lot of keywords that I don't understand: grid-template-columns, repeat, auto-fit, minmax and max-content. I tried reading up on them and failed. None of guides and API docs explicitly explain how this particualr combination works. MDN docs are way too short and cryptic.
What I specifically struggle with is this 210px magic number. Why is it necessary? (Erm, I know it's necessary because how the spec is designed, but this does not help me understand.)
The sizes of items in my grid are arbitrary, so I can't use a fixed value. Also, setting this fixed value makes the result slightly off: small items grow and large items overflow the container.
What I essentially want is:
grid-template-columns: repeat(auto-fit, minmax(min-content, max-content));
but that rule is recognized by browsers as faulty.
I've stumbled upon this answer that explains that using both min-content and max-content together is forbidden by the spec in this context. The answer's suggested solution is... to use Flexbox!
The loop has closed. I'm back to where I started, expect that I'm now lacking hair on my head for another round.
How to do I center my grid while left-aligning each row's content, with items having arbitrary widths?
Here's a boilerplate to fiddle with for your convenience: https://jsbin.com/vuguhoj/edit?html,css,output
The container can be resized by dragging it by the bottom-right corner.
PS No display: inline and float: left please.
.page {
border: 1px solid black;
overflow: hidden;
resize: horizontal;
max-width: 500px;
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(max-content, 50px));
justify-content: center;
}
.item {
border: 1px solid black;
margin: 1px;
}
<div class="page">
<div class="grid">
<div class="item">
Foofoofoo
</div>
<div class="item">
Bar
</div>
<div class="item">
BazBaz
</div>
<div class="item">
QuuxQuuxQuux
</div>
</div>
</div>
CSS grid approach-
root answer - joe82
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(179px, max-content));
grid-gap: 10px;
justify-content: center;
background: #999;
overflow: hidden;
padding: 10px;
}
.background {
width: 179px;
height: 64px;
background: #99d9ea;
}
.background .child {
border: 2px solid #000;
}
.background:nth-child(1) .child {
width: 110px;
height: 50px;
}
.background:nth-child(2) .child {
width: 120px;
height: 60px;
}
.background:nth-child(3) .child {
width: 50px;
height: 55px;
}
.background:nth-child(4) .child {
width: 175px;
height: 40px;
}
<div class="container">
<div class="background"><div class="child"></div></div>
<div class="background"><div class="child"></div></div>
<div class="background"><div class="child"></div></div>
<div class="background"><div class="child"></div></div>
</div>
Newbie here!
I admit that the above one isn't the output you desired, but it is my best attempt towards it, with the use of CSS grids. Here, you can understand that if we want to make it responsive then a minimum width is required after which, the column(content) will get carried to the next line, and that width is defined here(grid-template-columns: repeat(auto-fit, minmax(204px, max-content));) 204px. But because of it each column will take that much width at least, that's why I represented the actual dimension of a column with blue background and the actual content within the border.I just post it for your acknowledgment and approach so that you can get closer to the actual answer.
By the way, Flex Approach-
root idea - random COSMOS
.container {
min-width: 130px;
max-width: 340px;
overflow: auto;
background: #999;
padding: 10px 40px;
resize: horizontal;
border: 1px solid #000;
}
.main-content {
display: flex;
flex-wrap: wrap;
background: #fff;
max-width: 340px;
overflow: hidden;
}
.child {
margin: 5px;
padding: 5px;
background: #99d9ea;
border: 1px solid black;
}
<div class="container">
<div class="main-content">
<div class="child">Foofoofoo</div>
<div class="child">Bar</div>
<div class="child">BazBaz</div>
<div class="child">QuuxQuuxQuux</div>
</div>
</div>
Resize the window or the above div to see the results
The above tells that the div is centered and the content is at left but not resizing according to content.
My personal opinion -
You should use #media for making it responsize, just as the way you want it to be, It is just like coding a lot for a simple output but it can give you the best and satisfying results out of your hard work and time!
Kindly inform me if you want me to make it responsize for you, I mean just like a demo-
Regard,
Om Chaudhary
If we go for center we don't get the left-align thing:
.page {
border: 1px solid black;
max-width: 500px;
resize: horizontal;
overflow: hidden;
display: flex;
justify-content: center;
padding: 0 50px;
}
.grid {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.item {
border: 1px solid black;
margin: 1px;
}
<div class="page">
<div class="grid">
<div class="item">Foofoofoo</div>
<div class="item">Bar</div>
<div class="item">BazBaz</div>
<div class="item">QuuxQuuxQuux</div>
</div>
</div>
Now with left-align (as in #Michael Benjamin answer) it doesn't do the center stuff:
.page {
border: 1px solid black;
max-width: 500px;
resize: horizontal;
overflow: hidden;
display: flex;
justify-content: center;
padding: 0 50px;
}
.grid {
display: flex;
flex-wrap: wrap;
}
.item {
border: 1px solid black;
margin: 1px;
}
<div class="page">
<div class="grid">
<div class="item">Foofoofoo</div>
<div class="item">Bar</div>
<div class="item">BazBaz</div>
<div class="item">QuuxQuuxQuux</div>
</div>
</div>
Why?
Because in the second code and in #Michael Benjamin code the .grid is technically centered. Visual:
See the whole div is centered. The problem is that the .grid div doesn't change its width according to the content inside it. But, according to the width of its parent div (.page).
I know it doesnt solve your problem, but I am just trying to make sure that now you understand the main problem. So, maybe you can find the solution in another way.
For this case, I see the only solution is to use JavaScript.
In this code we get each .item width. Then we set .flex width = total .item width. If the total .item width is smaller then the .page width - we set .flex width = ((total .item width) - (last .item width)). I hope the JS is pretty readable. If you need more explanation - can give it in comments.
Note that this is not wary flexible and universal solution, But it works good in this particular case, because it was written for it.
This snippet you can test only on browser window size change. Better to check in using Snippet Full page and Chrome console with Devise toolbar mode. Or here https://jsfiddle.net/focusstyle/sh6dnLvt/1/
window.addEventListener("resize", function() {
flexWidth();
});
function flexWidth() {
let page = document.querySelector('.page');
let flex = document.querySelector('.flex');
let totalWidth = biggesWidth = itemWidth = lastWidth = 0;
let flexItem = document.querySelectorAll('.item');
for (let i = 0; i < flexItem.length; i += 1) {
itemWidth = flexItem[i].offsetWidth;
if (biggesWidth<itemWidth) {
biggesWidth = itemWidth;
}
biggesWidth = flexItem[i].offsetWidth;
totalWidth += itemWidth;
lastWidth = itemWidth;
}
if (totalWidth > page.clientWidth) {
totalWidth = totalWidth - lastWidth;
}
totalWidth += 1;
flex.style.cssText = "min-width: "+biggesWidth+"px; max-width: "+totalWidth+"px;";
}
.page {
border: 1px solid black;
overflow: hidden;
text-align: center;
}
.flex {
display: inline-flex;
flex-wrap: wrap;
justify-content: flex-start;
}
.item {
border: 1px solid black;
}
<div class="page">
<div class="flex">
<div class="item">
Foofoofoo
</div>
<div class="item">
Bar
</div>
<div class="item">
BazBaz
</div>
<div class="item">
QuuxQuuxQuux
</div>
</div>
</div>
Let's understand the 210px first. When you write the below code:
grid-template-columns: repeat(auto-fit, minmax(210px, max-content));
The browser knows when to wrap the items around. It ensures that your grid items will always be wider than 210px or at least equal to 210px.
If the browser has 420px width available, it will put 2 items in a row.
If the browser has 630px width available, it will put 3 items in a row, and so on...
You can learn about CSS grids here
If you still don't want to have a min-content of 210px, you can always wite media queries in CSS.
Another thing that may suit your requirements is giving a min-width and max-width to your grid-items.
Hopefully, it saves some of your hair.
You have two containers available β .page and .grid.
This enables you to distribute the two tasks β centering and left-alignment.
Use the top-level container for centering.
Use the nested container for wrapping and left alignment.
Here's a code concept:
.page {
display: grid;
grid-template-columns: 50px 1fr 50px;
border: 1px solid black;
max-width: 500px;
}
.grid {
grid-column: 2;
justify-self: center;
display: flex;
flex-wrap: wrap;
}
.item {
border: 1px solid black;
margin: 1px;
}
<div class="page">
<div class="grid">
<div class="item">Foofoofoo</div>
<div class="item">Bar</div>
<div class="item">BazBaz</div>
<div class="item">QuuxQuuxQuux</div>
</div>
</div>
jsFiddle demo
I don't know if I'm missing something but I think this is possible to achieve this with flexboxes.
You have to get this structure :
<div class="container">
<div class="row">
<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>
</div>
where the row has a max size and margin: 0 auto (to be centered)
Here is my example on Codepen
I'm trying to achieve a certain column layout in CSS. I've explored using Flexbox as well as CSS Grid, but all of my peers I've talked to cannot figure out a way to make this work. I know I can achieve it using JavaScript, but I'd like to avoid that if at all possible.
I want to create a layout of three columns. Column 1 and Column 3 should be matching in width (defined by the content of the longer column), and column 2 should shrink and grow to allow content to fit (but not expand to fill the parent container).
It's a bit difficult to paint a picture of what I'm going for, so please take a look at this CodePen where I've broken down the rudimentary code and showed a mocked up example of what I'm going for.
Here's the HTML structure
<div class="container">
<div class="col col--Z">Let's match cols, but also collapse!</div>
<div class="col col--Y">No! π£ Let me shrink!</div>
<div class="col col--Z">Yes!</div>
</div>
And here's the SCSS structure
.container {
display: grid;
justify-content: center;
grid-template-columns: 1fr auto 1fr;
.col {
padding-left: 6px;
padding-right: 6px;
&.col--Z {
background: rgba(0,255,55,0.2);
}
&.col--Y {
background: rgba(0,0,255,0.2);
}
}
}
* {
font-family: 'Arial', Sans-Serif;
}
.container {
display: grid;
justify-content: center;
grid-template-columns: 1fr auto 1fr;
}
.container .col {
padding-left: 6px;
padding-right: 6px;
}
.container .col.col--Z {
background: rgba(0, 255, 55, 0.2);
}
.container .col.col--Y {
background: rgba(0, 0, 255, 0.2);
}
.container-faked {
display: grid;
justify-content: center;
grid-template-columns: 260px auto 260px;
}
.container-faked .col {
padding-left: 6px;
padding-right: 6px;
}
.container-faked .col.col--Z {
background: rgba(0, 255, 55, 0.2);
}
.container-faked .col.col--Y {
background: rgba(0, 0, 255, 0.2);
}
<!-- This is the actual code -->
<h1>CSS Grid Attempt (actual code)</h1>
<div class="container">
<div class="col col--Z">Let's match cols, but also collapse!</div>
<div class="col col--Y">No! π£ Let me shrink!</div>
<div class="col col--Z">Yes!</div>
</div>
<br>
<hr>
<br>
<!-- This is the objective, mocked up! -->
<h1>CSS Grid Attempt (faked example)</h1>
<div class="container-faked">
<div class="col col--Z">Let's match cols, but also collapse!</div>
<div class="col col--Y">No! π£</div>
<div class="col col--Z">Yes!</div>
</div>
And the CodePen containing both the rudimentary code (not working) as well as the mocked up example of what I'd like to achieve, but using fixed pixel values to simulate equal width columns.
https://codepen.io/seanmaisch/pen/MZdqoW
You can use display: inline-grid to make grid container width according to content. To center it you can use some .wrapper block.
* {
font-family: 'Arial', Sans-Serif;
}
.wrapper {
display: flex;
justify-content: center;
}
.container {
display: inline-grid;
grid-template-columns: 1fr auto 1fr;
}
.container .col {
padding-left: 6px;
padding-right: 6px;
}
.container .col.col--Z {
background: rgba(0, 255, 55, 0.2);
}
.container .col.col--Y {
background: rgba(0, 0, 255, 0.2);
}
<div class="wrapper">
<div class="container">
<div class="col col--Z">Let's match cols, but also collapse!</div>
<div class="col col--Y">No! π£ Let me shrink!</div>
<div class="col col--Z">Yes!</div>
</div>
</div>
I'm creating a layout using CSS Grids, and I want to have different space between each row.
I can create the layout fine by just using margin on each element, but this kind of obscures the simplicity of the code. Is there any grid tricks I can do achieve this, grid-row-gap only seems to take one value, which it uses for all rows.
What I'm trying to achieve is a layout like this:
https://jsfiddle.net/8swzgk0b/1/
.grid {
display: grid;
grid-template-columns: auto 25% 25%;
grid-template-rows: auto auto auto;
width 100%;
margin: 20px;
grid-column-gap: 40px;
/* grid-row-gap: 40px 60px; */
}
div {
background: #838383;
height: 80px;
}
.wide {
grid-column: 1 / span 3;
margin-bottom: 5px;
}
.row-2 {
background: green;
margin-bottom: 10px;
}
.row-3 {
background: blue;
margin-bottom: 30px;
}
.row-4 {
background: red;
margin-bottom: 20px;
}
<div class="grid">
<div class="wide"></div>
<div class="row-2"></div>
<div class="row-2"></div>
<div class="row-2"></div>
<div class="row-3"></div>
<div class="row-3"></div>
<div class="row-3"></div>
<div class="row-4"></div>
<div class="row-4"></div>
<div class="row-4"></div>
</div>
Is there any grid trick I can do to achieve this, grid-row-gap only seems to take one value, which it uses for all rows.
With the grid-row-gap, grid-column-gap and grid-gap properties, you cannot apply different widths to different gaps. Like you noted, only one value can be used for each axis: One for row gaps and another for column gaps (spec).
You could use margins (or padding) to show extra space, but this doesn't actually change the width of the gap. It only expands the row.
In the example below (based on your code), grid-row-gap is set to 20px. Grid items have the margin-bottom variations you set. Notice how the grip-row-gap size never changes. All changes occur inside the row.
.grid {
display: grid;
grid-template-columns: auto 25% 25%;
grid-template-rows: auto auto auto;
grid-column-gap: 40px;
grid-row-gap: 20px;
}
div {
background: #838383;
height: 80px;
}
.wide {
grid-column: 1 / span 3;
margin-bottom: 5px;
}
.row-2 {
background: green;
margin-bottom: 10px;
}
.row-3 {
background: blue;
margin-bottom: 30px;
}
.row-4 {
background: red;
margin-bottom: 20px;
}
<div class="grid">
<div class="wide"></div>
<div class="row-2"></div>
<div class="row-2"></div>
<div class="row-2"></div>
<div class="row-3"></div>
<div class="row-3"></div>
<div class="row-3"></div>
<div class="row-4"></div>
<div class="row-4"></div>
<div class="row-4"></div>
</div>
If you want to apply different size gaps between rows, then consider using actual rows for the job:
Now the gaps between rows have their own unique heights.
.grid {
display: grid;
grid-template-columns: auto 25% 25%;
grid-template-rows: 80px 5px 80px 10px 80px 30px 80px 20px; /* adjusted */
grid-column-gap: 40px;
}
.wide {
grid-column: 1 / span 3;
background: #838383;
}
.row-2 {
grid-row-start: 3;
background: green;
}
.row-3 {
grid-row-start: 5;
background: blue;
}
.row-4 {
grid-row-start: 7;
background: red;
}
<div class="grid">
<div class="wide"></div>
<div class="row-2"></div>
<div class="row-2"></div>
<div class="row-2"></div>
<div class="row-3"></div>
<div class="row-3"></div>
<div class="row-3"></div>
<div class="row-4"></div>
<div class="row-4"></div>
<div class="row-4"></div>
</div>
you can't set different values for the column or row gaps, however, you can use css custom properties such as margin or display or you can create extra rows and columns and assign different values to them using them as gaps.