How to apply grid-gap in display:grid? - html

I applied grid-gap to each of the two classes. However, the gap area is displayed but not white. and the text position is located at the top of each cell. What should I do?
1)
I applied grid-gap to each of the two classes. However, the gap area appears, but it is not white, but [#96ceb4]. What should I do?
2)
I applied text-align:center, but the text position is located at the top of each cell. I want the text position to be located in the center of each cell area. What should I do?
body {
padding: 50px
}
.container div {
text-align: center;
color: #fff;
font-size: 1.5rem;
}
.container div:nth-child(1) {
background: #96ceb4;
}
.container div:nth-child(2) {
background: #ff6f69;
}
.container div:nth-child(3) {
background: #88d8b0;
}
.container div:nth-child(4) {
background: #ffcc5c;
}
.container div:nth-child(5) {
background: #96ceb4;
}
.container div:nth-child(6) {
background: #ff6f69;
}
.one {
display: grid;
grid-template-columns: 100px auto 100px;
grid-template-rows: 60px 100px;
grid-gap: 10px;
}
.two {
display: grid;
grid-template-columns: 100px auto;
grid-template-rows: 60px 100px;
grid-gap: 10px;
}
<div class="container">
<div class="one">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
</div>
<br>
<div class="two">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
</div>
</div>

To change the background color of the gap area to white, add the following CSS rule:
.container {
background-color: white;
}
To center the text vertically in each cell, add the following CSS rule:
.container div {
display: flex;
align-items: center;
justify-content: center;
}
Updated code:
.container {
background-color: white;
}
body{padding:50px}
.container div {text-align: center; color:#fff;font-size: 1.5rem;}
.container div:nth-child(1) {background: #96ceb4;}
.container div:nth-child(2) {background: #ff6f69;}
.container div:nth-child(3) {background: #88d8b0;}
.container div:nth-child(4) {background: #ffcc5c;}
.container div:nth-child(5) {background: #96ceb4;}
.container div:nth-child(6) {background: #ff6f69;}
.one {
display: grid;
grid-template-columns: 100px auto 100px;
grid-template-rows: 60px 100px;
grid-gap:10px;
}
.two {
display: grid;
grid-template-columns: 100px auto;
grid-template-rows: 60px 100px;
grid-gap:10px;
}
.container div {
display: flex;
align-items: center;
justify-content: center;
}
To change the background color of the gap area to white, add the following CSS rule:
<div class="container">
<div class="one">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
</div>
<br>
<div class="two">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
</div>
</div>

Related

Can I order a grid of divs by column using flexbox properties?

This is what I need to achieve:
(Note the empty grey slots)
Which in flexbox layout should normally behave like this: (if flex-wrap is set to wrap)
I know that this could be achieved with a CSS grid layout
.parent {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
grid-column-gap: 0px;
grid-row-gap: 0px;
height: 400px;
}
.parent div {
border: 1px solid;
box-sizing: border-box;
}
div:nth-child(1) { grid-area: 1 / 1 / 2 / 2; }
div:nth-child(2) { grid-area: 1 / 2 / 2 / 3; }
div:nth-child(3) { grid-area: 1 / 3 / 2 / 4; }
div:nth-child(4) { grid-area: 2 / 1 / 3 / 2; }
div:nth-child(5) { grid-area: 2 / 2 / 3 / 3; }
div:nth-child(6) { grid-area: 3 / 1 / 4 / 2; }
div:nth-child(7) { grid-area: 3 / 2 / 4 / 3; }
<div class="parent">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
The thing is that I would like to use with justify-content: space-between or gap as in my scenario the child elements are narrower and not feeling so comfortable with css grid.
Example:
.parent {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.parent div {
border: 1px solid;
box-sizing: border-box;
width: calc(33% - 4px);
height: 150px;
margin-bottom: 8px;
}
/* just to illustrate: child(6) */
.parent div:nth-child(6) { transform: translate(calc(-100% - 8px), calc(100% + 8px)); }
<div class="parent">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
Can this be done with flex?
There are 7 elements now but there will be more eventually, so this needs to be scaleable. Also, I'd rather not have to change the markup if possible.
Let me do a little summary of the request:
You have a flex container with 3 columns. When there are 3n + 1 items, the last 2 elements must be in the last row, leaving a gap in the previous row.
You can get this result using 2 pseudo elements as fillers (the second one could be skipped for some flex configurations). You need to use order to set them correctly, using some advanced nth-child selectors.
See in the snippet how this selectors trigger, as the background color shows.
The pseudo elements have a border of 0 pixels, You can change this for them to be visible.
.parent {
display: inline-flex;
flex-wrap: wrap;
justify-content: space-between;
border: solid 1px blue;
margin: 5px;
width: 100px;
}
.parent div {
border: 1px solid;
box-sizing: border-box;
width: calc(33% - 4px);
height: 30px;
margin-bottom: 8px;
}
.parent div:nth-child(3n):nth-last-child(2) {
background-color: yellow;
order: 3;
}
.parent div:nth-child(3n+1):nth-last-child(1) {
background-color: lightgreen;
order: 3;
}
.parent:before {
content: "";
box-sizing: border-box;
width: calc(33% - 4px);
height: 0px;
order: 2;
}
.parent:after {
content: "";
box-sizing: border-box;
width: calc(33% - 4px);
height: 0px;
order: 4;
}
.parent:before, .parent:after {
border: 0px solid red; /* change to 1px to show them */
}
<div class="parent">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
</div>
<div class="parent">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</div>
<div class="parent">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
</div>
<div class="parent">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
</div>
I would rely on pseudo-elements and this can work up to 9 elements. I am adding some coloration to better understand the trick:
.parent {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.parent div {
border: 1px solid;
box-sizing: border-box;
width: calc(33% - 4px);
height: 150px;
margin-bottom: 8px;
}
.parent:before,
.parent:after {
content: "";
flex-basis: 100%;
/* to illustrate */ border-bottom:2px solid red;
}
.parent :nth-child(-n + 5) {
order:-1;
/* to illustarte */ background: lightgreen;
}
.parent :nth-child(n + 8) {
order:1;
/* to illustarte */ background: lightblue;
}
<div class="parent">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
</div>
It wouldn't technically be semantically incorrect to use the <hr> element as a line-break for your flex children. It essentially acts as a placeholder, and will force the following flex children to a new line.
Using margin or padding with transform to try and break it to the next line may cause overlapping issues when resizing.
In CSS2 we were able to use break-after and break-before for these types of things. But it is not widely supported in CSS3.
I hope there is this sort of functionality in the future, but for now, CSS grid handles this type of design well.
.parent {
display: flex;
flex-wrap: wrap;
}
.parent > div {
background-color: #1b6b34;
height: 100px;
width: calc(100%/3);
}
.parent > div:nth-child(even) {
background-color: #685219;
}
hr {
border: transparent;
width: .1px;
}
.parent > div:nth-child(6) {
align-self: flex-end;
}
<div class="parent">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div><hr>
<div></div>
<div></div>
</div>
writing-mode can wrap it downward in the desired shape
.parent {
display: flex;
flex-flow: wrap;
width: 100%;
writing-mode: vertical-lr;
}
and if needed you can order within

Why isn't my grid-container positioning the grid-cells the way I want it to?

.grid-container {
display: grid;
grid-template-columns: repeat(auto-fit, 10%);
border: 1px solid red;
background-color: white;
}
.grid-container > div:nth-child(1) {
background-color: #B10DC9;
}
.grid-container > div:nth-child(2) {
background-color: antiquewhite;
}
.grid-container > div:nth-child(3) {
background-color: aquamarine;
}
<div class="grid-container">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
GC = grid-container.
GI = grid-item.
So far I can add in any number of GIs into the GC and have each GI take up only 10% of the GC's width. Is there a way to make it so that for any number of GIs I add, each GI takes up an equal portion of the GC - achieving this through CSS (not javascript)? fr units did not do the trick.
You set 10%, which means that your divs will not creep out to the entire free width.
But you can do it like this using minmax():
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
This means that when your divs reach 100px wide, these divs will blend under each other.
.grid-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
border: 1px solid red;
background-color: white;
}
.grid-container > div:nth-child(1) {
background-color: #B10DC9;
}
.grid-container > div:nth-child(2) {
background-color: antiquewhite;
}
.grid-container > div:nth-child(3) {
background-color: aquamarine;
}
<div class="grid-container">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
fr units did not do the trick.
Use it correctly and it will do it:
.grid-container {
display: grid;
grid-auto-columns: 1fr; /* all columns eqaul to each other */
grid-auto-flow: column; /* use a column flow */
border: 1px solid red;
}
.grid-container>div:nth-child(1) {
background-color: #B10DC9;
}
.grid-container>div:nth-child(2) {
background-color: antiquewhite;
}
.grid-container>div:nth-child(3) {
background-color: aquamarine;
}
<div class="grid-container">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
<div class="grid-container">
<div>1</div>
<div>2</div>
</div>
<div class="grid-container">
<div>1</div>
</div>

Can I get my grid to behave like I want without having to manually add in grid-items with Javascript?

.grid-container1 {
display: grid;
grid-auto-flow: column;
grid-auto-columns: 1fr;
grid-template-rows: 100%;
border: 1px solid pink;
background-color: grey;
}
.grid-container2 {
display: grid;
grid-template-columns: 75%;
grid-auto-flow: column;
grid-auto-columns: 1fr;
grid-template-rows: 100%;
border: 1px solid pink;
background-color: grey;
}
.one {
background-color: aqua;
}
.two {
background-color: beige;
}
.three {
background-color: orangered;
}
<div class="grid-container1">
<div class="one">1</div>
<div class="two">2</div>
<div class="three">3</div>
</div>
<div class="grid-container2">
<div></div>
<div class="one">1</div>
<div class="two">2</div>
<div class="three">3</div>
</div>
Grid-container = GC.
Grid-item = GI.
The first GC successfully allows me to add any number of GIs and have each GI take up an equal amount of space.
At some point (using a media-query) I want the layout to look like I have in GC2 - any number of background-color'd GIs equally take up the last 25% of the width of their GC. But notice how I have to introduce an empty GI, it's cell spanning 75% of GC width, at the start in order to achieve this. To me, this seems annoying as I'd have to use JavaScript. Is there anyway I can achieve what I want just using CSS?
EDIT
Just thought of this idea: keep my empty div and just set its display: block/none when I need it, changing grid-auto-columns: initial/75% when I need it too. Thoughts?
Pseudo element can help here. Resize the screen to see the result:
.grid-container {
display: grid;
grid-auto-flow: column;
grid-auto-columns: 1fr;
border: 1px solid pink;
background-color: grey;
}
#media (min-width:800px) {
.grid-container {
grid-template-columns: 75%;
}
.grid-container::before {
content: "";
}
}
.grid-container :nth-child(odd) {
background-color: aqua;
}
.grid-container :nth-child(even) {
background-color: beige;
}
<div class="grid-container">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
<div class="grid-container">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</div>
Another idea is to simply use padding since it's supposed to be an empty space:
.grid-container {
display: grid;
grid-auto-flow: column;
grid-auto-columns: 1fr;
border: 1px solid pink;
background-color: grey;
}
#media (min-width:800px) {
.grid-container {
padding-left: 75%;
}
}
.grid-container :nth-child(odd) {
background-color: aqua;
}
.grid-container :nth-child(even) {
background-color: beige;
}
<div class="grid-container">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
<div class="grid-container">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</div>
You can use CSS-Grid's concept grid-areas to achieve this in Pure CSS.
Codepen Link : https://codepen.io/emmeiWhite/pen/gOwzdar
.grid-container1 {
display: grid;
grid-auto-flow: column;
grid-auto-columns: 1fr;
grid-template-rows: 100%;
border: 1px solid pink;
background-color: grey;
}
/* You can use CSS-Grid. Grid-Areas*/
.grid-container2 {
display: grid;
grid-template-columns:repeat(12,1fr);
background:#777;
grid-template-areas:
". . . . . . . . . one-2 two-2 three-2"
}
.one,.one-2{
background-color: aqua;
}
.two,.two-2 {
background-color: beige;
}
.three,.three-2 {
background-color: orangered;
}
/* --- CSS-Grids -- */
.one-2{
grid-area:one-2;
}
.two-2{
grid-area:two-2;
}
.three-2{
grid-area:three-2;
}
<div class="grid-container1">
<div class="one">1</div>
<div class="two">2</div>
<div class="three">3</div>
</div>
<div class="grid-container2">
<div class="one-2">1</div>
<div class="two-2">2</div>
<div class="three-2">3</div>
</div>

CSS Grid resizable cell

In the following layout, I want to make the green color section to be re sizable. When it's resized, cell 8 should take the whatever the space left without affecting any other cells in other rows.
.App {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: 50px 1fr 200px 30px;
width: 100%;
height: 100%;
}
.App > div {
border: 2px solid black;
}
.nav {
background: green;
}
<div class="App">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div class="nav">7</div>
<div>8</div>
<div>9</div>
<div>10</div>
<div>11</div>
<div>12</div>
</div>
Size change will be done by the user. But to demonstrate, consider changing width of the .nav element to 100px. After size of .nav is changed, 8 cell should take the remaining space and grow.
.nav {
background: green;
width: 100px;
}
Is this kind of a behavior is possible using CSS Grid?
You can't change nav width and expect that it only affect the element next to it - it affect the whole first column. You can try resizing the nav in the demo below (using grid-template-columns: auto 1fr 200px) along with sufficient min-width and max-width:
.App {
display: grid;
grid-template-columns: auto 1fr 200px; /* changed */
grid-template-rows: 50px 1fr 200px 30px;
}
.App > div {
border: 2px solid black;
}
.nav {
background: green;
width: 100px; /* default width */
max-width: calc(100vw - 260px); /* do go beyond the third column */
min-width: 25px; /* min width of nav */
resize: horizontal; /* resize the div */
overflow: hidden; /* resize works if overflow not visible */
}
<div class="App"><div>1</div><div>2</div><div>3</div><div>4</div><div>5</div><div>6</div><div class="nav">7</div><div>8</div><div>9</div><div>10</div><div>11</div><div>12</div></div>
That's as far as you can have with the current markup. If you can change your html by wrapping the 8 and 7 into a 2-column grid item and make if a flexbox, you can have the desired effect - see demo below:
* {
box-sizing: border-box;
}
.App {
display: grid;
grid-template-columns: 1fr 1fr 200px;
grid-template-rows: 50px 1fr 200px 30px;
}
.App > div {
border: 2px solid black;
}
.nav {
grid-column: span 2;
display: flex;
}
.nav > div:first-child {
background: green;
resize: horizontal;
overflow: hidden;
width: 50%;
}
.nav > div:last-child {
flex: 1;
width: 50%;
}
<div class="App">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div class="nav">
<div>7</div>
<div>8</div>
</div>
<div>9</div>
<div>10</div>
<div>11</div>
<div>12</div>
</div>
You can read more about flexboxes with a resizable slider in these posts:
Change width proportions of two blocks with a slider
How do you allow a user to manually resize a <div> element vertically?

Css-Grid, Grid-auto-rows dosen't work and the page it's not reponsive as it should

I'm following a course on CSS Grid, and I don't understand why my mockup doesn't behave as it's shown in the course. I have 12 div, and if I reduce the page's width, despite the fact that I have in my CSS the option to auto-generate rows, it stops behave responsively.
This is my index.html
.container {
display: grid;
grid-gap: 5px;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
grid-auto-rows: 100px;
}
.container>div {
display: flex;
justify-content: center;
align-items: center;
font-size: 2em;
color: #ffeead;
}
html,
body {
background-color: #ffeead;
margin: 10px;
}
.container>div:nth-child(1n) {
background-color: #96ceb4;
}
.container>div:nth-child(3n) {
background-color: #88d8b0;
}
.container>div:nth-child(2n) {
background-color: #ff6f69;
}
.container>div:nth-child(4n) {
background-color: #ffcc5c;
}
<div class="container">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
<div>11</div>
<div>12</div>
</div>
Can someone tell me what am I doing wrong, and why is not responsive?
Thank you.