CSS Grid auto-fit column automatically wraps - css

from the example I have three columns, when resized at a certain view-port it will wrap onto the next row, how can I target that individual div and make it fill the available width?
.boxes {
color: white;
display: grid;
grid-gap: 20px;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}
.box {
background-color: blue;
padding: 10px;
}
<section class = "boxes">
<div class="box">
<p>Box 1</p>
</div>
<div class="box">
<p>Box 2</p>
</div>
<div class="box">
<p>Box 3</p>
</div>
</section>
Codepen:
CodePen

You need flexbox for this:
body {
color: white;
}
.boxes {
display: flex;
flex-wrap: wrap;
}
.box {
background-color: blue;
padding: 10px;
min-width: 250px;
box-sizing:border-box;
margin: 10px;
flex-grow: 1;
}
<section class="boxes">
<div class="box">
<p>Box 1</p>
</div>
<div class="box">
<p>Box 2</p>
</div>
<div class="box">
<p>Box 3</p>
</div>
</section>

Limit columns by max-width
you can stay with grid, but it look good only if you stay with 2 columns.
for more columns its more complicated and you can define what you want, to use grid or to use flex for convenient way.
html {
box-sizing: border-box;
}
body {
background-color: white;
color: white;
}
.boxes {
display: grid;
grid-gap: 20px;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
max-width: 700px;
margin: 0 auto;
text-align: center;
}
.box {
background-color: blue;
padding: 10px;
}
.box:last-child:nth-child(odd) {
grid-column: 1/3;
}
<!DOCTYPE html>
<html>
<head>
<title>Column Resize</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<section class="boxes">
<div class="box">
<p>Box 1</p>
</div>
<div class="box">
<p>Box 2</p>
</div>
<div class="box">
<p>Box 3</p>
</div>
</section>
</body>
</html>

Related

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 -->

How to set equal width for flex elements?

Why blocks .b have different width? How to set it equal?
.parent {
display: flex;
}
.parent>div {
flex: 1 1 auto;
}
.parent .b {
display: flex;
}
<div class="parent">
<div class="cell">
<div class="b"></div>
</div>
<div class="cell">>
<div class="b"></div>
</div>
<div class="cell">>
<div class="b"></div>
</div>
<div class="cell">>
<div class="b"></div>
</div>
<div>
Why blocks <div class="cell"> have different width?
Edit: use CSS grid and auto-fit:
.parent {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
}
.parent {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
}
.parent>div {
background-color: lightblue;
margin-left: 5px;
}
<div class="parent">
<div class="cell">
<div class="b"></div>
</div>
<div class="cell">>
<div class="b"></div>
</div>
<div class="cell">>
<div class="b"></div>
</div>
<div class="cell">>
<div class="b"></div>
</div>
</div>
Second re-edit**
First choice you can do is just set a flex on the parent element as this will only effect the first element below that, which in this case is the cell class, i will add a border on the cell class so you can see this in effect
<div class="parent">
<div class="cell">
<div class="b"></div>
</div>
<div class="cell">
<div class="b"></div>
</div>
<div class="cell">
<div class="b"></div>
</div>
<div class="cell">
<div class="b"></div>
</div>
<div>
.parent {
display: flex;
width: 70%;
}
.cell {
width: 20%;
height: 100px;
border: 1px solid orange;
}
here you can set the size of your parent width which will be the size across your screen, you can then set the width of the .cell childs and they will all then be the same, but only at a maximum of the parent
** second option you can do
Here is a simpler version, and i have added 3 different classes to show how you can choose the sizing you want
<div class="parent">
<div class="a"></div>
<div class="b"></div>
<div class="c"></div>
<div>
.parent {
display: flex;
width: 80%;
height: 100px;
}
.a {
flex: 40%;
border: 1px solid greenyellow;
}
.b {
flex: 20%;
border: 1px solid orange;
}
.c {
flex: 20%;
border: 1px solid blue;
}
Of course you can change them back and have them all be called the same class, and just assign one width and again they will all be the same... i hope this helps
I think they all are in same width. You need to use this css instead of the .parent>div selector
.cell {
flex: 1 1 auto;
}
.parent {
display: flex;
}
.cell {
flex: 1 1 auto;
}
.parent .b {
display: flex;
align-items: center;
justify-content: center;
}
.b {
height: 50px;
}
.cell:nth-child(1) {
background: red;
}
.cell:nth-child(2) {
background: yellow;
}
.cell:nth-child(3) {
background: green;
}
.cell:nth-child(4) {
background: teal;
}
<div class="parent">
<div class="cell">
<div class="b">hi</div>
</div>
<div class="cell">
<div class="b">hi</div>
</div>
<div class="cell">
<div class="b">hi</div>
</div>
<div class="cell">
<div class="b">hi</div>
</div>
<div>

How to centerd 2 columns in a 3 column template

I have grid section that has a grid-template-column for 3 columns. But this content is loaded dynamically so it has 2 columns sometimes. I am trying to center the columns when there is only 2 columns
I checked the documentation of the grid CSS and tried a lot of different CSS but nothing seems to work as I would like to.
.wrapper {
grid-template-columns: repeat(3,1fr);
display: grid;
align-items: stretch;
}
.items {
display: block;
}
Is this the behavior you were expecting?
More about flexbox: https://css-tricks.com/snippets/css/a-guide-to-flexbox/
.parent {
display: flex;
justify-content: center;
}
/* Addition styling */
.parent {
padding: 30px;
background: lightgrey;
opacity: 0.8;
}
.child {
padding: 30px;
text-align: center;
background: black;
margin: 10px;
color: white;
max-width: 300px;
}
<div class="parent">
<div class="child">Column</div>
<div class="child">Column</div>
</div>
<hr>
<div class="parent">
<div class="child">Column</div>
<div class="child">Column</div>
<div class="child">Column</div>
</div>
<hr>
<div class="parent">
<div class="child">Column</div>
<div class="child">Column</div>
<div class="child">Column</div>
<div class="child">Column</div>
</div>
.grid-container {
display: grid;
grid-template-columns: repeat(3,1fr);
grid-column-gap: 50px;
grid-row-gap: 50px;
justify-content: center;
align-content: center;
}
.grid-container div {
text-align: center;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div class="grid-container">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
<div class="grid-item">4</div>
<div class="grid-item">5</div>
<div class="grid-item">6</div>
<div class="grid-item">7</div>
<div class="grid-item">8</div>
<div class="grid-item">9</div>
</div>
</body>
</html>

Is it possible to draw vertical separators in the interior gaps of a CSS grid of varying columns?

I want to have a responsive grid of elements of variable length. The grid should fill the available width of the containing element, with the number of columns varying depending on the width of the container. This is straightforward to achieve using CSS grids; however, I don't know how to add a vertical border between columns (i.e., only in the interior column gaps). The below simple demo manages to achieve a vertical border in the event that there are three columns:
https://codepen.io/yowzadave/pen/OYPvLd?editors=1100
html, body {
box-sizing: border-box
}
.container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(24rem, 1fr));
grid-column-gap: 0.5rem;
}
.item {
border-right: 1px solid black;
padding-right: 0.5rem;
}
.item:nth-child(3n) {
border-right: none;
padding-right: 0;
}
.box {
background-color: pink;
height: 2rem;
margin: 0.5rem;
}
<html>
<body>
<div class="container">
<div class="item"><div class="box"></div></div>
<div class="item"><div class="box"></div></div>
<div class="item"><div class="box"></div></div>
<div class="item"><div class="box"></div></div>
<div class="item"><div class="box"></div></div>
<div class="item"><div class="box"></div></div>
</div>
</body>
</html>
...but in the event that the browser is wider or narrower, the borders will be misplaced. Is there a way to correctly place the borders at all browser widths?
You can use pseudo element on all the grid item where you will simply have overlap and be sure to cover all the gaps:
html,
body {
margin: 0;
}
.container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
grid-column-gap: 0.5rem;
overflow:hidden; /* Hide the overflow */
position:relative;
}
.item {
box-sizing: border-box;
position:relative;
}
.item:before {
content:"";
position:absolute;
top:0;
right:-0.25rem; /* Half the gap */
height:100vh; /* Big height*/
width:1px;
background:#000;
}
.box {
background-color: pink;
height: 2rem;
margin: 0.5rem;
}
<div class="container">
<div class="item">
<div class="box"></div>
</div>
<div class="item">
<div class="box"></div>
</div>
<div class="item">
<div class="box"></div>
</div>
<div class="item">
<div class="box"></div>
</div>
<div class="item">
<div class="box"></div>
</div>
<div class="item">
<div class="box"></div>
</div>
</div>

Vertical scroll bar in div which is a child of css grid column

I am new to CSS grid, I have a nested grid layout page. I could not get a scroll bar for grid child div.fieldsContainer.
html,body,
.wrapper{
height: 100%;
width: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
.wrapper{
display: grid;
grid-template-rows: 50px 1fr 50px;
}
.header{
border: 1px solid #ddd;
background: lightyellow;
}
.footer{
background: lightpink;
}
.content{
display: grid;
grid-template-columns: 250px 1fr 300px;
grid-gap: 10px;
overflow: hidden;
}
.fieldTypes{
display: grid;
grid-template-rows: 40px 1fr;
}
.fieldTypes .search{
border: 1px solid red;
}
.fieldTypes .fieldsContainer{
display: grid;
grid-template-columns: repeat(3, minmax(70px,1fr));
grid-auto-rows: 50px;
grid-gap: 10px;
}
.card{
padding: 10px;
background: #ddd;
}
<div class="wrapper">
<div class="header">
Header
</div>
<div class="content">
<div class="fieldTypes">
<div class="search">search</div>
<div class="fieldsContainer">
<div class="card">1</div>
<div class="card">2</div>
<div class="card">3</div>
<div class="card">4</div>
<div class="card">5</div>
<div class="card">6</div>
<div class="card">7</div>
<div class="card">8</div>
<div class="card">9</div>
<div class="card">10</div>
<div class="card">11</div>
<div class="card">12</div>
<div class="card">10</div>
<div class="card">11</div>
<div class="card">12</div>
<div class="card">10</div>
<div class="card">11</div>
<div class="card">12</div>
</div>
</div>
<div class="inndercontent">
innder content
</div>
<div class="graphs">
graphs
</div>
</div>
<div class="footer">
Footer
</div>
</div>
One solution would be to set overflow-y:auto on the parent ( .fieldTypes ) and overflow-y:scroll on .fieldsContainer
There is no ' story ' behind this. Just that you have to set a default overflow for the parent to accept it, and then specify overflow-y:scroll( as you want vertical scroll ) on the child.
html,body,
.wrapper{
height: 100%;
width: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
.wrapper{
display: grid;
grid-template-rows: 50px 1fr 50px;
}
.header{
border: 1px solid #ddd;
background: lightyellow;
}
.footer{
background: lightpink;
}
.content{
display: grid;
grid-template-columns: 250px 1fr 300px;
grid-gap: 10px;
overflow: hidden;
}
.fieldTypes{
display: grid;
grid-template-rows: 40px 1fr;
overflow-y:auto;/*added*/
}
.fieldTypes .search{
border: 1px solid red;
}
.fieldTypes .fieldsContainer{
display: grid;
grid-template-columns: repeat(3, minmax(70px,1fr));
grid-auto-rows: 50px;
grid-gap: 10px;
overflow-y:scroll;/*added*/
}
.card{
padding: 10px;
background: #ddd;
}
<div class="wrapper">
<div class="header">
Header
</div>
<div class="content">
<div class="fieldTypes">
<div class="search">search</div>
<div class="fieldsContainer">
<div class="card">1</div>
<div class="card">2</div>
<div class="card">3</div>
<div class="card">4</div>
<div class="card">5</div>
<div class="card">6</div>
<div class="card">7</div>
<div class="card">8</div>
<div class="card">9</div>
<div class="card">10</div>
<div class="card">11</div>
<div class="card">12</div>
<div class="card">10</div>
<div class="card">11</div>
<div class="card">12</div>
<div class="card">10</div>
<div class="card">11</div>
<div class="card">12</div>
</div>
</div>
<div class="inndercontent">
innder content
</div>
<div class="graphs">
graphs
</div>
</div>
<div class="footer">
Footer
</div>
</div>
Here's a more reduced case (to cut through the irrelevant parts)
html, body, .A {
height: 100%; /* matters */
width: 100%;
margin: 0;
padding: 0;
}
.A {
max-height: 300px; /* matters */
display: grid; /* matters */
overflow: hidden; /* matters */
}
.B {
display: grid; /* matters */
overflow-y: auto; /* matters */
}
.D {
overflow-y: scroll; /* matters */
}
.C {
padding: 10px;
background-color: #07f;
}
.E {
padding: 10px;
background-color: #eee;
}
<div class="A">
<div class="B">
<div class="C">search</div>
<div class="D">
<div class="E">1</div>
<div class="E">2</div>
<div class="E">3</div>
<div class="E">4</div>
<div class="E">5</div>
<div class="E">6</div>
<div class="E">7</div>
<div class="E">8</div>
<div class="E">9</div>
<div class="E">10</div>
<div class="E">11</div>
<div class="E">12</div>
<div class="E">10</div>
<div class="E">11</div>
<div class="E">12</div>
<div class="E">10</div>
<div class="E">11</div>
<div class="E">12</div>
</div>
</div>
</div>
Set the parent's height to 100vh. Then overflow-y: scroll will work on the children.
See this example (based on the reduced case answer).
html, body, .A {
margin: 0;
padding: 0;
}
.A {
height: 100vh; /* matters */
display: grid; /* matters */
}
.B {
padding: 10px;
background-color: #07f;
}
.C {
overflow-y: scroll; /* matters */
}
.D {
padding: 10px;
background-color: #eee;
}
<div class="A">
<div class="B">search</div>
<div class="C">
<div class="D">1</div>
<div class="D">2</div>
<div class="D">3</div>
<div class="D">4</div>
<div class="D">5</div>
<div class="D">6</div>
<div class="D">7</div>
<div class="D">8</div>
<div class="D">9</div>
<div class="D">10</div>
<div class="D">11</div>
<div class="D">12</div>
<div class="D">10</div>
<div class="D">11</div>
<div class="D">12</div>
<div class="D">10</div>
<div class="D">11</div>
<div class="D">12</div>
</div>
</div>

Resources