Make Grid Item Auto Fill - css

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>

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>

How do I mimic floats with flexbox?

I am trying to use flexbox like floats. I would like 1 child to form a column on the right and the remaining children to form another column on the left. I can't add in additional HTML -- I can only work with CSS.
I've figured out how to do this, but I just need both columns to align at the top. My current code has the left column slightly below the right column.
https://jsfiddle.net/o2fbtuLc/
.parent {
display: flex;
flex-wrap: wrap;
flex-direction: column;
}
.child {
max-width: 48%;
}
.right {
margin-left: auto;
}
<div class="parent">
<div class="child right">Right</div>
<div class="child">Left</div>
<div class="child">Left</div>
<div class="child">Left</div>
</div>
You can use order. Also I removed flex-direction: column and added max-width: 100% for elements after second element.
.parent {
display: flex;
flex-wrap: wrap;
}
.child {
width: 100%;
max-width: 48%;
}
.child:nth-child(2) {
order: 1;
}
.child:nth-child(3) {
order: 3;
}
.child:nth-child(4) {
order: 4;
}
.right {
order: 2;
}
.child:nth-child(n + 3) {
max-width: 100%;
}
<div class="parent">
<div class="child right">Right</div>
<div class="child">Left</div>
<div class="child">Left</div>
<div class="child">Left</div>
</div>
If .right is taller, we can consider using grid-area.
.parent {
display: grid;
grid-template-areas: "left1 right"
"left2 right"
"left3 right";
}
.child {
width: 100%;
background: blue;
height: 30px;
}
.child:nth-child(2) {
grid-area: left1;
}
.child:nth-child(3) {
grid-area: left2;
}
.child:nth-child(4) {
grid-area: left3;
}
.right {
background: red;
height: 80px;
grid-area: right;
}
<div class="parent">
<div class="child right">Right</div>
<div class="child">Left</div>
<div class="child">Left</div>
<div class="child">Left</div>
</div>
CSS-Grid can do that:
.parent {
display: grid;
grid-template-columns: auto auto;
grid-auto-flow: column;
}
.child {
max-width: 48%;
grid-column: 1;
border: 1px solid green;
}
.right {
grid-column: 2;
}
<div class="parent">
<div class="child right">Right</div>
<div class="child">Left</div>
<div class="child">Left</div>
<div class="child">Left</div>
<div class="child right">Right</div>
</div>
If you want to avoid grid (IE 11 involved maybe ?) , the old way via the table-display, can do too :
.parent {
display: table;
width: 100%;
direction: rtl;/* alike a flow column reverse here */
text-align: left;
border: solid;
}
.child {
direction: ltr;/* ! reset flow direction ;)*/
border: solid;
}
.right {/* i will also expand if first col is longer than myself */
display: table-cell;
width: 50%;/* set column width here ! left over will be for the other one(s). */
}
/* margins ? */
.bis {border-spacing:2px;}
.bis .child {margin-right:2px;}
.bis .right + .child ~ .child {margin-top:2px;}
.bis .right{text-align:center;vertical-align:middle;
<div class="parent">
<div class="child right">Right</div>
<div class="child">Left</div>
<div class="child">Left</div>
<div class="child">Left</div>
</div>
<hr>
<div class="parent bis">
<div class="child right">possible gaps / VH-align</div>
<div class="child">Left</div>
<div class="child">two<br>lines</div>
<div class="child">Left</div>
</div>
just use flexbox as it was intended!
.parent {
display: flex;
justify-content:space-between;
}
<div class="parent">
<div>
<div class="child">Left</div>
<div class="child">Left</div>
<div class="child">Left</div></div>
<div class="child right">Right</div>
</div>

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 do I remove grid gaps when columns are not present?

I have a section of html that needs to be displayed in a certain way but some elements may be optional and I'm not sure if I can do it with display:grid.
I need to have 3 columns, but the first and last one are optional and I need to remove the gap when they are not present.
Note that the markup needs to be this one without extra wrapper :
.grid {
display: grid;
grid-template-columns: auto 1fr auto;
grid-gap: 0 20px;
align-items: center;
background-color: lightgrey;
}
.grid > .image {
grid-column: 1;
grid-row: 1 / span 2;
background-color: red;
}
.grid > .title {
grid-column: 2;
background-color: blue;
}
.grid > .description {
grid-column: 2;
background-color: purple;
}
.grid > .button {
grid-column: 3;
grid-row: 1 / span 2;
background-color: green;
}
<div class="grid">
<div class="image">image</div>
<div class="title">title</div>
<div class="description">description</div>
<div class="button">button</div>
</div>
<p> </p>
<p>Unwanted gap when no image :</p>
<div class="grid">
<div class="title">title</div>
<div class="description">description</div>
<div class="button">button</div>
</div>
<p> </p>
<p>Unwanted gap when no image or button :</p>
<div class="grid">
<div class="title">title</div>
<div class="description">description</div>
</div>
Rely on implicit column creation and keep only one explicit column
.grid {
display: grid;
grid-template-columns: 1fr; /* one column here */
grid-gap: 0 20px;
align-items: center;
background-color: lightgrey;
}
.grid > .image {
grid-column: -3; /* this will create an implicit column at the start */
grid-row: span 2;
background-color: red;
}
.grid > .title {
background-color: blue;
}
.grid > .description {
background-color: purple;
}
.grid > .button {
grid-column: 2; /* this will create an implicit column at the end */
grid-row:1/ span 2;
background-color: green;
}
<div class="grid">
<div class="image">image</div>
<div class="title">title</div>
<div class="description">description</div>
<div class="button">button</div>
</div>
<p> </p>
<div class="grid">
<div class="title">title</div>
<div class="description">description</div>
<div class="button">button</div>
</div>
<p> </p>
<div class="grid">
<div class="image">image</div>
<div class="title">title</div>
<div class="description">description</div>
</div>
<p> </p>
<div class="grid">
<div class="title">title</div>
<div class="description">description</div>
</div>
Instead of using grid gaps, use margins on the individual elements.
.grid {
display: grid;
grid-auto-columns: auto 1fr auto;
/* grid-gap: 0 20px; */
align-items: center;
background-color: lightgrey;
}
.grid > .image {
margin-right: 20px; /* new */
grid-column: 1;
grid-row: 1 / span 2;
background-color: red;
}
.grid > .button {
margin-left: 20px; /* new */
grid-column: 3;
grid-row: 1 / span 2;
background-color: green;
}
.grid > .title {
grid-column: 2;
background-color: blue;
}
.grid > .description {
grid-column: 2;
background-color: purple;
}
<div class="grid">
<div class="image">image</div>
<div class="title">title</div>
<div class="description">description</div>
<div class="button">button</div>
</div>
<p> </p>
<p>NO unwanted gap when no image :</p>
<div class="grid">
<div class="title">title</div>
<div class="description">description</div>
<div class="button">button</div>
</div>
<p> </p>
<p>NO unwanted gap when no image or button :</p>
<div class="grid">
<div class="title">title</div>
<div class="description">description</div>
</div>

Four items in two columns

I have this HTML
<div class='wrapper'>
<div class='item-1'>One</div>
<div class='item-2'>Two</div>
<div class='item-3'>Three</div>
<div class='item-4'>Four</div>
</div>
In CSS, is it possible for me to create a two column grid where item-1 and item-2 are in the first column, and item-3 and item-4 are in the second?
The heights of the divs are variable, so this is not strict 2x2 grid.
Basically, I'd like it to look like the example below, but I do not have the luxury of wrapping my items.
THANKS!
.wrapper {
display:grid;
grid-template-columns: 1fr 1fr;
}
<div class='wrapper'>
<div class='wrapper-1'>
<div class='item-1' style='height:100px;background-color:red;'>One</div>
<div class='item-2' style='height:80px;background-color:blue;'>Two</div>
</div>
<div class='wrapper-2'>
<div class='item-3' style='height:40px;background-color:orange;'>Three</div>
<div class='item-4' style='height:40px;background-color:green;'>Four</div>
</div>
</div>
The CSS for the wrapper is correct. The only thing you need to specify is from which line of the grid should each item start and end.
.item-1,
.item-2{
grid-column: 1/2;
width: 100%;
}
.item-3,
.item-4{
grid-column: 3/4;
width: 100%;
}
This should suit your needs. Note that the wrapper needs to have an explicit height in order for the columns to wrap, otherwise it's going to endlessly expand.
.wrapper {
display: flex;
flex-flow: column wrap;
height: 200px;
}
.item {
width: 50%;
}
.i-1 {
height: 100px;
background-color: green;
}
.i-2 {
height: 80px;
background-color: red;
}
.i-3 {
height: 40px;
background-color: blue;
}
.i-4 {
height: 40px;
background-color: yellow;
}
<div class='wrapper'>
<div class='item i-1'>One</div>
<div class='item i-2'>Two</div>
<div class='item i-3'>Three</div>
<div class='item i-4'>Four</div>
</div>

Resources