GRID CSS — How can I not define the grid-row-end? - css

I'm making a portfolio, using Grid CSS for the first time. I'm pretty new on this, and have a question about grid-row. I never saw the solution on Internet, so that's why I'm asking it here.
I have a container, that has different boxes with the same size. I would like to extend the number of boxes with JavaScript (dynamic). My problem is : Do I need to write a grid-row-end, even if I don't know the height of the container because I actually don't know how many boxes I'll have ?
I made a preview of my problem, here's a preview.
* {
margin: 0;
padding: 0;
}
body {
font-family: -apple-system, roboto, sans-serif;
background: #222f3e;
color: #c8d6e5;
}
.container {
display: grid;
grid-template-columns: repeat(10, 1fr);
grid-auto-rows: 5rem;
grid-gap: 3rem 2rem;
}
.container header,
.container footer {
background: #576574;
grid-column: 1 / span 10;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
.container header {
grid-row: 2 / span 1;
}
.container .content {
grid-column: auto / span 10;
background: #8395a7;
grid-row: auto / span 10;
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-auto-rows: 2.5rem;
grid-gap: 2.5rem 2.5rem;
grid-auto-flow: row;
}
.container .content .box {
grid-column: auto / span 3;
grid-row: auto / span 5;
background: #ff6b6b;
}
.container footer {
grid-row: auto / span 2;
}
<div class="container">
<header>
<h1> Grid CSS </h1>
</header>
<div class="content">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
<footer>
<h2> Mon Footer </h2>
</footer>
</div>
Thanks a lot !
Louis

You don't need to define all those templates. Make it simple and rely on height since you know exactly how tall each item should be and keep the content one auto:
body {
background: #222f3e;
color: #c8d6e5;
margin:0;
}
.container {
display: grid;
padding-top:8rem;
grid-row-gap: 3rem;
}
.container header, .container footer {
background: #576574;
display: flex;
align-items: center;
justify-content: center;
}
.container header {
height:5rem;
}
.container .content {
background: #8395a7;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 2.5rem;
}
.container .content .box {
height:22.5rem;
background: #ff6b6b;
}
.container footer {
height:13rem;
}
<div class="container">
<header>
<h1> Grid CSS </h1>
</header>
<div class="content">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
<footer>
<h2> Mon Footer </h2>
</footer>
</div>

Set the grid-auto-rows of the .container's to minmax(5rem, max-content);:
* {
margin: 0;
padding: 0;
}
body {
font-family: -apple-system, roboto, sans-serif;
background: #222f3e;
color: #c8d6e5;
}
.container {
display: grid;
grid-template-columns: repeat(10, 1fr);
grid-auto-rows: minmax(5rem, max-content);
grid-gap: 3rem 2rem;
}
.container header,
.container footer {
background: #576574;
grid-column: 1 / span 10;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
.container header {
grid-row: 2 / span 1;
}
.container .content {
grid-column: auto / span 10;
background: #8395a7;
grid-row: auto / span 10;
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-auto-rows: 2.5rem;
grid-gap: 2.5rem 2.5rem;
grid-auto-flow: row;
}
.container .content .box {
grid-column: auto / span 3;
grid-row: auto / span 5;
background: #ff6b6b;
}
.container footer {
grid-row: auto / span 2;
}
<div class="container">
<header>
<h1> Grid CSS </h1>
</header>
<div class="content">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
<footer>
<h2> Mon Footer </h2>
</footer>
</div>

Related

how to swap the second row of grid items

help me please, how do i get a result like this in the grid? the result i want - link - img https://ibb.co/XbW025V . here is my code https://jsfiddle.net/o0zjuyqb/1/
<div class="container">
<div class="parent">
<div class="div1"></div>
<div class="div2"></div>
<div class="div3"></div>
<div class="div4"></div>
<div class="div5"></div>
<div class="div6"></div>
</div>
</div>
You can do this by using grid-column: span 2;
.grid {
display: grid;
grid-auto-flow: dense;
grid-template-columns: 250px 290px 290px 250px;
grid-template-rows: repeat(2, 280px);
gap: 40px;
}
.grid div {
background: grey;
}
.grid div.wide {
grid-column: span 2;
background: green;
}
<div class="grid">
<div class="wide"></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div class="wide"></div>
</div>

Make Grid Item Auto Fill

sorry I'm very new to grid-layout
I have a layout that I believe it is really easy for grid system
but I have no idea how to modify it for my layout:
the layout has three type:
if only one item: full width, full height
if two items, left and right; 50% width, full height
if three items, correct code is below
.container {
display: grid;
width: 200px;
height: 200px;
grid-template-columns: 1fr 1fr;
grid-template-rows: 50% 50%;
grid-gap: 8px;
}
.a {
grid-column: 1;
grid-row: 1 / 3;
background: red;
}
.b {
grid-column: 2;
grid-row: 1;
background: blue;
}
.c {
grid-column: 2;
grid-row: 2;
background: green;
}
<div class="container">
<div class="a"></div>
<div class="b"></div>
<div class="c"></div>
</div>
code above is for type 3 and is really correct
how should I modify it let it fit type 1 and 2 ??
You can do it like below:
.container {
display: inline-grid;
margin:5px;
vertical-align:top;
width: 200px;
height: 200px;
grid-gap: 8px;
}
.a { background: red;}
.b { background: blue;}
.c { background: green;}
/* when 2 items we add another column*/
.container :nth-child(2):nth-last-child(1) {
grid-column:2;
}
/* when 3 items we add another row as well */
.container :nth-child(3):nth-last-child(1) {
grid-row:2;
grid-column:2;
}
/* when 3 items, the first one will span 2 rows*/
.container :first-child:nth-last-child(3) {
grid-row:span 2;
}
<div class="container">
<div class="a"></div>
</div>
<div class="container">
<div class="b"></div>
</div>
<div class="container">
<div class="c"></div>
</div>
<div class="container">
<div class="a"></div>
<div class="b"></div>
</div>
<div class="container">
<div class="b"></div>
<div class="c"></div>
</div>
<div class="container">
<div class="a"></div>
<div class="c"></div>
</div>
<div class="container">
<div class="a"></div>
<div class="b"></div>
<div class="c"></div>
</div>

How to create one vertical column in between rows in Flexbox [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
Is there is a way to create this style with Flexbox?
You have two ways to solve this. Either flexbox or CSS grid, both are good, but I prefer the CSS grid way:
Flexbox
.container {
width: 100%;
height: 600px;
display: flex;
align-items: center;
justify-content: center;
}
.column {
display: flex;
flex-direction: column;
height: 90%;
width: 30%;
}
.box {
background-color: gray;
display: flex;
align-items: center;
justify-content: center;
height: 30%;
}
.box1 {
height: 30%;
}
.box2, .box5 {
height: 30%;
margin: 20px 0;
}
.middle {
height: 100%;
}
.column-large {
margin: 0 20px;
width: 30%;
height: 100%;
}
<div class="container">
<div class="column">
<div class="box box1">1</div>
<div class="box box2">2</div>
<div class="box box3">3</div>
</div>
<div class="column-large">
<div class="box middle">middle</div>
</div>
<div class="column">
<div class="box box4">4</div>
<div class="box box5">5</div>
<div class="box box6">6</div>
</div>
</div>
CSS Grid
With CSS grid, this is what you can achieve. If you play around with the widths and heights, you could fit this to your needs. In case you want to know more about CSS grid in general, this article is a very good way to start: https://css-tricks.com/snippets/css/complete-guide-grid/.
.container {
width: 100%;
height: 100%;
display: grid;
grid-template-areas:
". middle ."
"tl middle tr"
"ml middle mr"
"bl middle br"
". middle .";
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 5% 30% 30% 30% 5%;
gap: 20px;
}
.box {
background-color: gray;
display: flex;
align-items: center;
justify-content: center;
}
.box1 {
grid-area: tl;
}
.box2 {
grid-area: tr;
}
.box3 {
grid-area: ml;
}
.box4 {
grid-area: mr;
}
.box5 {
grid-area: bl;
}
.box6 {
grid-area: br;
}
.middle {
grid-area: middle;
}
<div class="container">
<div class="box box1">1</div>
<div class="box box2">2</div>
<div class="box box3">3</div>
<div class="box box4">4</div>
<div class="box box5">5</div>
<div class="box box6">6</div>
<div class="box middle">middle</div>
</div>

CSS Grid auto-fit column automatically wraps

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>

Flexbox space-between but center if one element

I've the following HTML and CSS.
<div class="container-box">
<div class="box"></div>
<div class="box"></div>
</div>
<div class="container-box">
<div class="box"></div>
</div>
.container-box {
width: 200px;
display: flex;
flex-direction: row;
justify-content: space-between;
background-color: red;
margin:50px;
}
.box {
background-color: #9009A0;
height: 50px;
width: 50px;
}
Which gives this layout:
The first layout for multiple items does what I expect, but how can I change the second to position the element in center as it only has one element?
See this codepen: https://codepen.io/dennismadsen/pen/oNvqjjV
For cases where you have one item in the container, you can use the :only-child pseudo-class.
Add this to your code:
.box:only-child {
margin: 0 auto;
}
.container-box {
width: 200px;
display: flex;
flex-direction: row;
justify-content: space-between;
background-color: red;
margin: 50px;
}
.box {
background-color: #9009A0;
height: 50px;
width: 50px;
}
.box:only-child {
margin: 0 auto;
}
<div class="container-box">
<div class="box"></div>
<div class="box"></div>
</div>
<div class="container-box">
<div class="box"></div>
</div>
In such cases, flex auto margins will override justify-content because:
§ 8.1. Aligning with auto
margins
Prior to alignment via justify-content and align-self, any
positive free space is distributed to auto margins in that dimension.
More about :only-child:
§ 6.6.5.10. :only-child
pseudo-class
The :only-child pseudo-class represents an element that has no
siblings. Same as :first-child:last-child or
:nth-child(1):nth-last-child(1), but with a lower specificity.
More about flex auto margins:
In CSS Flexbox, why are there no "justify-items" and "justify-self" properties?
Also, to spotlight some interesting flex behavior, if you were using space-around instead of space-between, you wouldn't need auto margins.
Flex item should align left, not center, when it wraps
For info, You could also use together :first-child and :last-child if you wanted to mind about very old browsers ;)
.container-box {
width: 200px;
display: flex;
flex-direction: row;
justify-content: space-between;
background-color: red;
margin: 50px;
}
.box {
background-color: #9009A0;
height: 50px;
width: 50px;
}
.container-box .box:first-child:last-child {
margin: 0 auto;
}
<div class="container-box">
<div class="box"></div>
<div class="box"></div>
</div>
<div class="container-box">
<div class="box"></div>
</div>
Here is a different idea with only margin:
.container-box {
width: 400px;
display: flex;
background-color: red;
margin: 30px;
}
.box {
background-color: #9009A0;
height: 50px;
width: 50px;
}
.box:first-child {
margin-right: auto;
}
.box:last-child {
margin-left: auto;
}
<div class="container-box">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
<div class="container-box">
<div class="box"></div>
<div class="box"></div>
</div>
<div class="container-box">
<div class="box"></div>
</div>
If you will have more than 3 elements you can add an extra rule
.container-box {
width: 400px;
display: flex;
background-color: red;
margin: 30px;
}
.box {
background-color: #9009A0;
height: 50px;
width: 50px;
}
.box:not(:last-child):not(:first-child) {
margin:auto;
}
.box:first-child {
margin-right: auto;
}
.box:last-child {
margin-left: auto;
}
<div class="container-box">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
<div class="container-box">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
<div class="container-box">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
<div class="container-box">
<div class="box"></div>
<div class="box"></div>
</div>
<div class="container-box">
<div class="box"></div>
</div>

Resources