CSS Grid is being vertical - css

I'm new to CSS Grid and I want to create a grid of divs. I want the grids to be fill up horizontally--filling up the pink div, but instead they go vertical like in the snippet below. I've tried everything, how do I fix it
.mygrid
{
background-color: pink;
display: grid;
gap: 2px;
grid-template-columns: 30px 40px;
}
.item
{
background-color: blue;
}
<div class="mygrid">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
<div class="item">11</div>
<div class="item">12</div>
</div>

You should define the columns to half and half, using the "fr" unit.
.mygrid
{
background-color: pink;
display: grid;
gap: 2px;
grid-template-rows: 1fr 1fr;
grid-template-columns: 1fr 1fr;
}
.item
{
background-color: blue;
}
<div class="mygrid">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
<div class="item">11</div>
<div class="item">12</div>
</div>

Your problem comes from grid-template-columns property.
You can use the auto param get the same size of columns.
Follow this doc for more information : https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template-columns
.mygrid
{
background-color: pink;
display: grid;
gap: 2px;
grid-template-columns: auto auto auto;
}
.item
{
background-color: blue;
}
<div class="mygrid">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
<div class="item">11</div>
<div class="item">12</div>
</div>

use grid-template-columns: auto auto; to fill the entire pink box,
.mygrid
{
background-color: pink;
display: grid;
grid-template-columns: auto auto auto;
gap: 2px;
}
View on codepen for more detail : link

Related

Shrink inner grid column to zero if it has no content

In the following example mid-left and mid-right should equally share space left by all other elements. But if there is only one of them, it should take all this space. It's not known which of them would be present. Supporting of gap is NOT needed.
I can make this only via :has selector. How can I make the same thing without it?
Markup should NOT be changed. Otherwice I would wrap mid-left and mid-right into container and used flex or grid-auto-columns: 1fr on it.
Here are 5 examples how it should work:
section {
display: grid;
grid-template: "l t t t" 2em
"l mt mt r" 1fr
"l ml mr r" 1fr / 5em 1fr 1fr 5em;
min-height: 8em;
}
section + section {
margin-top: 2em;
}
div {
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
.left { grid-area: l; background: antiquewhite; }
.top { grid-area: t; background: silver; }
.right { grid-area: r; background: antiquewhite; }
.mid-top { grid-area: mt; background: yellow; }
.mid-left { grid-area: ml; background: aquamarine; }
.mid-right { grid-area: mr; background: lightsalmon; }
section:not(:has(.mid-left)) {
grid-template-columns: 5em 0 1fr 5em;
}
section:not(:has(.mid-right)) {
grid-template-columns: 5em 1fr 0 5em;
}
<section>
<div class="left">Left</div>
<div class="top">Top</div>
<div class="right">Right</div>
<div class="mid-top">Mid top</div>
<div class="mid-left">Mid left takes half of space</div>
<div class="mid-right">Mid right takes half of space</div>
</section>
<section>
<div class="left">Left</div>
<div class="top">Top</div>
<div class="right">Right</div>
<div class="mid-top">Mid top</div>
<div class="mid-left">Mid left should take all width</div>
</section>
<section>
<div class="left">Left</div>
<div class="top">Top</div>
<div class="right">Right</div>
<div class="mid-top">Mid top</div>
<div class="mid-right">Mid right should take all width</div>
</section>
<section>
<div class="left">Left</div>
<div class="top">Top</div>
<div class="right">Right</div>
<div class="mid-top">Mid top</div>
<div class="mid-left">Mid left should have equal width even if it has more content</div>
<div class="mid-right">Mid right</div>
</section>
<section>
<div class="left">Left</div>
<div class="top">Top</div>
<div class="right">Right</div>
<div class="mid-top">Mid top</div>
<div class="mid-left">Mid left</div>
<div class="mid-right">Mid right should have equal width even if it has more content</div>
</section>
PS: Actually I have several divs with display: contents on them and the elements mid-left and mid-right are not on the same level.
PPS: Anyway, I think answers based on provided markup are usefull for future viewers or maybe even for me if I could adopt selectors.
Actually I was not going to add examples with wrappers into the question, but as I was asked, here they are:
section {
display: grid;
grid-template: "l t t t" 2em
"l mt mt r" 1fr
"l ml mr r" 1fr / 5em 1fr 1fr 5em;
min-height: 8em;
}
section + section {
margin-top: 2em;
}
div {
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
some-wrapper {
display: contents;
}
.left { grid-area: l; background: antiquewhite; }
.top { grid-area: t; background: silver; }
.right { grid-area: r; background: antiquewhite; }
.mid-top { grid-area: mt; background: yellow; }
.mid-left { grid-area: ml; background: aquamarine; }
.mid-right { grid-area: mr; background: lightsalmon; }
section:not(:has(.mid-left)) {
grid-template-columns: 5em 0 1fr 5em;
}
section:not(:has(.mid-right)) {
grid-template-columns: 5em 1fr 0 5em;
}
<section>
<div class="left">Left</div>
<some-wrapper>
<div class="top">Top</div>
<div class="right">Right</div>
<div class="mid-top">Mid top</div>
<div class="mid-right">Mid right</div>
</some-wrapper>
<some-wrapper>
<div class="mid-left">Mid left</div>
</some-wrapper>
</section>
<section>
<div class="left">Left</div>
<some-wrapper>
<div class="top">Top</div>
<div class="right">Right</div>
<div class="mid-top">Mid top</div>
</some-wrapper>
<some-wrapper>
<div class="mid-left">Mid left</div>
</some-wrapper>
</section>
<section>
<div class="left">Left</div>
<some-wrapper>
<div class="top">Top</div>
<div class="right">Right</div>
<div class="mid-top">Mid top</div>
<div class="mid-right">Mid right</div>
</some-wrapper>
<some-wrapper>
</some-wrapper>
</section>
<section>
<div class="left">Left</div>
<some-wrapper>
<div class="mid-right">Mid right</div>
<div class="mid-top">Mid top</div>
<div class="top">Top</div>
</some-wrapper>
<div class="right">Right</div>
</section>
<section>
<div class="left">Left</div>
<div class="top">Top</div>
<some-wrapper>
<div class="mid-right">Mid right</div>
<div class="mid-top">Mid top</div>
</some-wrapper>
<some-wrapper>
<div class="mid-left">Mid left</div>
</some-wrapper>
<div class="right">Right</div>
</section>
Same question in Russian.

CSS Grid with vertical and horizontal overflow

I'm trying to use display: grid to make a layout with a variable amount of columns, with horizontal and vertical overflow and the first column being a specific width.
Each of the columns, besides the first, should be the same width.
For example,
grid-template-columns: 49px repeat(auto-fill, 300px);
makes the first column the correct width, and columns after 300px - until reaching the overflowing columns, which ignore the 300px.
The vertical scroll is achieved with overflow-y and a specified height.
overflow-y: scroll;
height: 70vh;
And the horizontal css so far is:
grid-template-columns: 49px repeat(auto-fit, 300px);
grid-auto-flow: column;
overflow-x: scroll;
width: 100%;
Stack snippet:
.grid-container {
display: grid;
grid-template-columns: 49px repeat(auto-fit, 300px);
grid-auto-flow: column;
overflow-x: scroll;
width: 100%;
overflow-y: scroll;
height: 70vh;
}
<div class="grid-container">
<div class="first-item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
</div>
Paint attempt to visualise the goal:
You could solve this by omitting grid-template-columns and defining the width separately:
.grid-container {
display: grid;
grid-auto-flow: column;
overflow-x: scroll;
width: 100%;
overflow-y: scroll;
height: 70vh;
}
.first-item {
width: 49px;
}
.item {
width: 300px;
}
<div class="grid-container">
<div class="first-item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
</div>
Use grid-auto-columns and you don't need to specify any CSS on the child items
.grid-container {
display: grid;
grid-template-columns: 49px; /* 1st column */
grid-auto-columns: 300px; /* all the others */
grid-auto-flow: column;
overflow-x: scroll;
height: 70vh;
}
<div class="grid-container">
<div class="first-item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
</div>

Adding Text beneath each column 4X4 using CSS GRID

I am very new to CSS Grid and am trying to create a 2 X 2 grid. I am able to create the four image divs ( 2 on each row and 2 on each column) but I want the text to appear underneath each one. I have tried to use the grid-template-areas property but all the text just appears under one div all overlapped.
Any help would be appreciated, please.
.image {
width: 526px;
height: 360px;
border: 1px solid #000;
border-radius: 10px;
margin-top: 35px;
margin-bottom: 35px;
}
.grid-container {
display: grid;
grid-template-rows: auto;
grid-template-columns: 1fr 1fr;
column-gap: 10px;
row-gap: 1em;
grid-template-areas: "image image " "text text";
}
.text {
grid-area: text;
}
<div class="banner">
<div class="wrapper">
<div class="grid-container">
<div class="image"></div>
<p class="text">TEXT 1</p>
<div class="image"></div>
<p class="text">
TEXT 2
</p>
<div class="image"></div>
<p class="text">TEXT 3</p>
<div class="image"></div>
<p class="text">TEXT 4</p>
</div>
</div>
<!-- wrapper -->
</div>
<!-- banner -->
You can use nth-child() to correctly place your elements instead of grid-area:
.image {
width: 200px;
height: 150px;
border: 1px solid #000;
border-radius: 10px;
margin-top: 35px;
margin-bottom: 35px;
}
.grid-container {
display: grid;
grid-auto-flow: dense; /* this one is important to fill all the cells */
grid-auto-columns: 1fr;
column-gap: 10px;
}
.image:nth-child(4n + 3) {
grid-column: 2;
}
.text:nth-child(4n + 2) {
grid-column: 1;
}
<div class="banner">
<div class="wrapper">
<div class="grid-container">
<div class="image"></div>
<p class="text">TEXT 1</p>
<div class="image"></div>
<p class="text">TEXT 2</p>
<div class="image"></div>
<p class="text">TEXT 3</p>
<div class="image"></div>
<p class="text">TEXT 4</p>
</div>
</div>
</div>
This will work even if you add more image/text:
.image {
width: 200px;
height: 150px;
border: 1px solid #000;
border-radius: 10px;
margin-top: 35px;
margin-bottom: 35px;
}
.grid-container {
display: grid;
grid-auto-flow: dense; /* this one is important to fill all the cells */
grid-auto-columns: 1fr;
column-gap: 10px;
}
.image:nth-child(4n + 3) {
grid-column: 2;
}
.text:nth-child(4n + 2) {
grid-column: 1;
}
<div class="banner">
<div class="wrapper">
<div class="grid-container">
<div class="image"></div>
<p class="text">TEXT 1</p>
<div class="image"></div>
<p class="text">TEXT 2</p>
<div class="image"></div>
<p class="text">TEXT 3</p>
<div class="image"></div>
<p class="text">TEXT 4</p>
<div class="image"></div>
<p class="text">TEXT 5</p>
<div class="image"></div>
<p class="text">TEXT 6</p>
<div class="image"></div>
<p class="text">TEXT 7</p>
<div class="image"></div>
<p class="text">TEXT 8</p>
</div>
</div>
</div>
Manage placement without template areas using nth-of-type and flow via columns.
.image {
width: 100px;
height: 100px;
border: 1px solid #000;
border-radius: 10px;
margin-top: 35px;
margin-bottom: 35px;
}
.grid-container {
display: grid;
grid-template-rows: auto;
grid-template-columns: 1fr 1fr;
column-gap: 10px;
row-gap: 1em;
grid-auto-flow: column;
}
p:nth-of-type(odd),
.image:nth-of-type(odd) {
grid-column: 1;
}
p:nth-of-type(even),
.image:nth-of-type(even) {
grid-column: 2;
}
<div class="banner">
<div class="wrapper">
<div class="grid-container">
<div class="image"></div>
<p class="text">TEXT 1</p>
<div class="image"></div>
<p class="text">
TEXT 2
</p>
<div class="image"></div>
<p class="text">TEXT 3</p>
<div class="image"></div>
<p class="text">TEXT 4</p>
</div>
</div>
<!-- wrapper -->
</div>
<!-- banner -->
I removed the grid-area configuration from CSS code. Also, I have rearranged the sequence of your image and text HTML code. I hope this is what you expected.
.image {
width: 526px;
height: 360px;
border: 1px solid #000;
border-radius: 10px;
margin-top: 35px;
margin-bottom: 35px;
/*grid-area: image;*/
}
.grid-container {
display: grid;
grid-template-rows: auto;
grid-template-columns: 1fr 1fr;
column-gap: 10px;
row-gap: 1em;
/* grid-template-areas: "image image" "text text"; */
}
.text {
text-align: center; /* Aligning the text to center */
/* grid-area: text;*/
}
<div class="banner">
<div class="wrapper">
<div class="grid-container">
<div class="image"></div>
<div class="image"></div>
<p class="text">TEXT 1</p>
<p class="text">TEXT 2</p>
<div class="image"></div>
<div class="image"></div>
<p class="text">TEXT 3</p>
<p class="text">TEXT 4</p>
</div>
</div>
<!-- wrapper -->
</div>
<!-- banner -->

change order of grid style (masonry)

i have a grid style:
<div class="masonry">
<div class="item">10</div>
<div class="item">9</div>
<div class="item">8</div>
<div class="item">7</div>
<div class="item">6</div>
<div class="item">5</div>
<div class="item">4</div>
<div class="item">3</div>
<div class="item">2</div>
<div class="item">1</div>
</div>
css:
.masonry {
column-count: 5;
column-gap: 1em;
margin-top: 20px;
}
.item {
display: inline-block;
margin: 0 0 1em;
width: 100%;
}
the result is in this picture (items orders by column):
Current image
but i want to order items by row.First, fill in the first row, then second row and etc.like this photo my favorite state
I did with flexbox see below code, I believe this is what you are looking for
.masonry {
margin-top: 20px;
display: flex;
flex-direction: row-reverse;
align-items: flex-end;
flex-wrap: wrap;
}
.item {
margin: 0 0 1em;
width: 20%;
}
<div class="masonry">
<div class="item">10</div>
<div class="item">9</div>
<div class="item">8</div>
<div class="item">7</div>
<div class="item">6</div>
<div class="item">5</div>
<div class="item">4</div>
<div class="item">3</div>
<div class="item">2</div>
<div class="item">1</div>
</div>

CSS Grid: dynamically span the last column

Is it possible to automatically span the last column to occupy the remaining space in the grid? Basically I'm trying to achieve this:
.row {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.col {
background: blue;
padding: 20px;
border: 1px solid red;
}
.col:last-child {
background: yellow;
/* missing magic here */
}
<div class="row">
<div class="col"></div>
<div class="col"></div>
<div class="col"></div>
</div>
<div class="row">
<div class="col"></div>
<div class="col"></div>
</div>
<div class="row">
<div class="col"></div>
</div>
Unfortunately, it seems that in current version of CSS grid there is no true magic like grid-column: span auto / -1 as a universal solution. But for this particular case of 3x1 grid you can do something like the following:
.row {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.col {
background: blue;
padding: 20px;
border: 1px solid red;
}
.col:last-child {
background: yellow;
grid-column-end: -1;
}
.col:nth-child(1):last-child {
grid-column-start: 1;
}
.col:nth-child(2):last-child {
grid-column-start: 2;
}
<div class="row">
<div class="col"></div>
<div class="col"></div>
<div class="col"></div>
</div>
<div class="row">
<div class="col"></div>
<div class="col"></div>
</div>
<div class="row">
<div class="col"></div>
</div>

Resources