This question already has answers here:
How to create a CSS Grid Layout box that spans 2 columns and 2 rows?
(3 answers)
Make grid container fill columns not rows
(6 answers)
Closed 2 months ago.
I have a css-grid layout set up as 3 columns. When a certain media-query matches, i want it to instead flow as rows where the first column becomes the first row, covering the full with. Column two and three should become one row and share the space equally. How can i achieve that? (i know how to write a media query, code is for demonstrating only)
.thegrid {
display: grid;
grid-template-columns: 1fr auto auto;
gap: 40px;
}
<div class="thegrid">
<div>
content 1
</div>
<div>
content 2
</div>
<div>
content 3
</div>
</div>
If you keep the columns, and add grid-column: 1/-1 to the first div (this makes sure the div covers the complete grid area). Does that give the desired look?
You must display grid then when your #media screen hits its threshold it will begin to flex. You have to tell which rows you want to combine within your flexed column and how far to extend them. Hopefully this helps and makes sense. good luck!
.thegrid {
display: grid;
grid-template-columns: auto auto auto;
grid-template-rows: 80px 200px;
gap: 10px;
background-color: #2196F3;
padding: 10px;
}
#media only screen and (max-width: 600px) {
.thegrid {
display: grid;
grid-template-columns: auto auto auto;
grid-template-rows: 80px 200px;
gap: 10px;
background-color: #2196F3;
padding: 10px;
}
.row-1 {
grid-column: 1/ span 2;
grid-row: 1;
}
.row-2 {
grid-row: 2;
}
}
<div class="thegrid">
<div class="row-1">
content 1
</div>
<div class="row-2">
content 2
</div>
<div class="row-2">
content 3
</div>
</div>
Related
Is it possible to use CSS grid to auto-fit the columns in a row to always take up the whole width?
I know this would be possible if you knew the number of columns, but is it possible with a dynamic number of columns?
Image for reference of what I'd like to achieve.
column example image
This is what I have so far, but you can see that the lower row item doesn't take up all the row width.
.wrapper {
display: grid;
grid-template-columns: 200px 200px;
column-gap: 20px;
}
.grid {
border: solid #FF8181 1px;
display: grid;
grid-template-rows: 40px repeat(8, minmax(0, 1fr));
width: 200px;
grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
}
.row-item {
background: #FFC555;
border: 1px solid #835600;
width: 100%;
height: 40px;
}
.item-1, .item-1 {
grid-row: 2 / span 1;
}
.item-2 {
grid-row: 6 / span 1;
font-size: 12px;
}
<div class='wrapper'>
<div class='grid'>
<div class='row-item item-1'></div>
<div class='row-item item-1'></div>
<div class='row-item item-2'>I'm too short</div>
</div>
<div class='grid'>
<div class='row-item item-1'></div>
<div class='row-item item-1'></div>
<div class='row-item item-1'></div>
<div class='row-item item-2'>Should be the whole width</div>
</div>
</div>
you can stretch a element in a grid over the whole width by using:
grid-column: 1 / all;
or
grid-column: 1 / -1;
unfortunately does it affect the other elements in the same grid.
A solution like "span last-column" doesnt exist yet, but is already discussed: https://github.com/w3c/csswg-drafts/issues/2402
Maybe they will implement the function soon. Good luck anyways
What I need doesn't exist yet. This does indeed look like the latest update:
A solution like "span last-column" doesnt exist yet, but is already
discussed: https://github.com/w3c/csswg-drafts/issues/2402
I calculated overlapping grid items and rendered items in subgrids based on this answer:
Group multiple overlapping timeblocks that may not have a direct overlap
With js its different.
Find the grid
Get the Style of the Grid
Filter the Style of the Grid for grid-template-columns
Set the Element grid-column to the number of columns
Your code will look like this:
window.addEventListener("DOMContentLoaded", function(){
// find the elemen by the class and safe it as grid
let grid = document.querySelector(".grid")
// sage the style of the element
const gridComputedStyle = window.getComputedStyle(grid);
// get the grid-template-columns style poperty of the element and format them to a useful value
const gridColumnCount = gridComputedStyle.getPropertyValue("grid-template-columns").split(" ").length
// log for debug
console.log(gridColumnCount)
// set the column style of the element to the span of the variable
document.getElementById("item-2").style.gridColumn = "1 / span " + gridColumnCount;
// set the row style because it got overwritten by the line above
document.getElementById("item-2").style.gridRow = "6 / span " + gridColumnCount;
})
note that i have changed your html and css too:
html:
<div class='grid'>
<div class='row-item item-1'></div>
<div class='row-item item-1'></div>
<div class='row-item item-1'></div>
<div class="row-item" id="item-2">whole width</div>
</div>
Just deleted the wrapper for a better overview
CSS:
.grid {
border: solid #FF8181 1px;
display: grid;
grid-template-rows: repeat(8, minmax(0, 1fr));
width: 300px;
grid-template-columns: repeat(auto, minmax(0, 1fr));
}
.row-item {
background: #FFC555;
border: 1px solid #835600;
width: 100%;
height: 40px;
}
.item-1, .item-1 {
grid-row: 2;
}
.item-2 {
grid-row: 5;
font-size: 12px;
}
I had to change the grid-template-value of grid from auto-fit to auto. Otherwise there would be a bug when counting the columns
I want to achieve 12 column grid behavior similar to what Bootstrap has,
but using CSS grids.
I need to have a fixed gaps in pixels
And have a 12 column grid, so I can decide how to place the children.
I'm facing the issue, that combination of grid-template-columns and column-gap doesn't shrink the columns on a smaller screens, but cause horizontal overflow on a screen.
How can I achieve expected behavior with shrinking without reducing the number of columns and keeping the gap in pixels.
DEMO:
.parent {
max-width: 300px;
height: 500px;
overflow: auto;
border: 1px solid blue;
}
.box {
grid-column: span 6 / span 6;
background: red;
height: 40px;
}
.grid {
display: grid;
grid-template-columns: repeat(12, minmax(0, 1fr));
gap: 40px;
}
<div class="parent">
<div class="grid">
<div class="box"></div>
<div class="box"></div>
</div>
</div>
In this case, there are multiple input fields across multiple rows.
Each field width given as no of characters that field should support
If field width is 10, it should support 10 characters
There is a fixed margin between fields
Ex:
First row have 3 input fields with widths as (10, 10 ,10)
Second row have 4 input fields with widths as (10, 5, 5, 10)
Third row have 2 input fields with widths as (15, 15)
In this case summation of field's widths is 30 in all three rows
So left and right ends of row's should be in a same vertical line
How to calculate field's widths?
Is that possible to keep alignment between rows?
Thanks
You can do it quite easily with CSS grid. Your html may change, but the solution lay on grid.
div {
display: grid;
grid-gap: 1rem;
grid-template-columns: repeat(6, 5fr);
grid-template-rows: repeat(3, 1fr);
}
section:nth-child(1),
section:nth-child(2),
section:nth-child(3),
section:nth-child(4),
section:nth-child(7) {
grid-column: span 2;
border: 3px solid orange;
}
section:nth-child(8),
section:nth-child(9) {
grid-column: span 3;
border: 3px solid red;
}
<div>
<section>10</section>
<section>10</section>
<section>10</section>
<section>10</section>
<section>5</section>
<section>5</section>
<section>10</section>
<section>15</section>
<section>15</section>
</div>
You could use flex grow, for example like this:
<div class="flexContainer">
<div class="flexItem10">…</div>
<div class="flexItem5>…</div>
<div class="flexItem5>…</div>
<div class="flexItem10">…</div>
.flexContainer {
display: flex;
gap: 20px;
}
.flexItem5 {
flex-grow: 5;
}
.flexItem10 {
flex-grow: 10;
}
I have a set of children inside a display: grid container - each child is numbered. At the 600px breakpoint, child 4 completely loses composure and deflates to its inner content size. Why doesn't 4 hop on down below 3?
.box {
background: yellow;
display: flex;
justify-content: center;
align-items: center;
font-size: 48px;
font-weight: bold;
}
.box.md {
grid-column: span 2;
}
.box.lg {
grid-column: span 2;
grid-row: span 2;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
grid-auto-rows: 240px;
grid-auto-flow: dense;
grid-gap: 8px;
}
#media (max-width: 920px) {
max-width: 800px;
}
#media (max-width: 600px) {
grid-auto-rows: 120px;
}
<div class="container">
<div class="box lg">1</div>
<div class="box md">2</div>
<div class="box sm">3</div>
<div class="box sm">4</div>
</div>
https://jsfiddle.net/amw273vq/
Why doesn't 4 hop on down below 3?
Because items 1 & 2 both have grid-column: span 2 applied. Meaning there are two columns already available, and item 4 has no reason to move to the next row.
Make all columns take a full row.
Add this to your code:
#media (max-width: 600px) {
.container > div {
grid-column: span 1 !important; (you need to override the span 2 rules higher up)
}
}
revised demo
And the reason for the collapse of item 4 has nothing to do with your media query.
If you look closely, you'll find the item 4 collapses when the screen width is 640px. This is before the 600px media query is reached.
Here's the issue:
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr))
At 640px screen width, item 3 reaches 280px, the minimum width it can be.
As a result, item 4 is pushed to the second column, which was created by grid-column: span 2 on its siblings.
However, at this screen size, there is only space for one explicit (i.e., defined) column. The second column must be generated in the implicit (i.e., undefined) grid.
And, because the default value of grid-auto-columns – the property that sizes implicit columns – is auto, the second column takes the width of the widest cell.
I want to use CSS grid and the following is a mock-up of the aim:
I'm building an interface that should expand rightward to fill the browser screen; my current code causes column 2 of the outer grid to be as wide as the browser in addition to column 1; or maybe one of it's children is causing this and it's just expanding to accommodate. Either way, it's spilling off the page horizontally
So the code:
#main {
width: 100%;
display: grid;
grid-template-columns: 250px 100%;
grid-template-rows: 100px 100%;
}
#col-2-outer {
display: grid;
grid-template-columns: 250px auto;
grid-template-rows: 100%;
}
#row-1-inner {
grid-column: span 2;
}
#col-2-inner table {
width: 100%;
}
<div id="main">
<div id="col-1-outer"></div>
<div id="col-2-outer">
<div id="row-1-inner"></div>
<div id="row-2-inner">
<div id="col-1-inner"></div>
<div id="col-2-inner">
<table></table>
</div>
</div>
</div>
</div>
FYI, for the time being I've forgone template areas until I get a handle on the basics (unless this somehow solves my problem but I gather this is strictly a code organization feature?).
I'd suggest to change your markup with a 3x2 grid like below:
Remove the hierarchical structure like you have in your code and add one element for each section in the grid.
Note that in the rule grid-template-columns: 250px 150px auto, 250px is the width of your col-1-outer and 150px is the width of the col-1-inner.
Span the first column over the two rows by using grid-row: span 2
Span the first row in the second column by using grid-column: span 2.
Extend the table over the last grid item by using 100% width and height.
See demo below:
* {
border: 1px solid; /* For illustration */
}
#main {
width: 100%;
display: grid;
grid-template-columns: 250px 150px auto;
grid-template-rows: 100px auto;
}
#col-1-outer {
grid-row: span 2;
}
#row-1-inner {
grid-column: span 2;
}
#col-2-inner table {
width: 100%;
height: 100%;
}
<div id="main">
<div id="col-1-outer">col-1-outer</div>
<div id="row-1-inner">col2-row-1-inner</div>
<div id="col-1-inner">col2-row2-inner</div>
<div id="col-2-inner">
<table><tr><td>table</td></tr></table>
</div>
</div>
The 100% for the 2nd column in your grid-template-columns is based on the width of the container - rather than occupying the space outstanding within the container, it will push out to the right because the 2nd column is trying to match the width of the container.
Try changing this to auto and this should rectify the issue, as it will only take up the space up to the end of the container and no further.
Source: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns