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?
Related
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>
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
.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>
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.
Is there a way to have a CSS grid (display: grid) that has a 1px border around all items and also fills incomplete rows? The approach of setting the background-color seems to not be a viable solution.
My goals would be to have a grid without the grey area in the code snippet where items are missing and the grid lines always extending all the way through the table. This should work for responsive combinations of items per row.
It almost seems like special pseudo classes would be needed for doesn't have item below and doesn't have item to the right to make this work in responsive layouts because last-of-type has too little information about the grid to use it for styling.
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
background-color: #d4d4d4;
grid-gap: 1px;
border: 1px solid #d4d4d4;
}
.grid > div {
padding: 15px;
text-align: center;
background-color: white;
}
<div class="grid">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>
You should apply
the same background-color for grid container and grid items
right and bottom borders for grid items with negative
margins (this will be compensated by grid gaps).
Demo:
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
background-color: white;
grid-gap: 1px;
border: 1px solid #d4d4d4;
}
.grid > div {
padding: 15px;
text-align: center;
background-color: inherit;
border-right: inherit;
margin-right: -1px;
border-bottom: inherit;
margin-bottom: -1px;
}
<div class="grid">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
</div>