display dynamic cards with different heights using grid css without gutter - html

How to create a dynamic grid system using css3.
I'd like to achieve an overview page with multiple cards with different heights and order of displaying cards should be the same.
Cards with different heights will be displayed on the dashboard based on the config settings so it should be auto-adjusted.
Please help me to write generic css for it.
HTML:
<div class="wrapper">
<div style="height:50px" id="foo-1">One</div>
<div style="height:50px" id="foo-2">Two</div>
<div style="height:50px" id="foo-3">Three</div>
<div style="height:100px" id="foo-4">Four</div>
<div style="height:50px" class="fifth" id="foo-5">Five</div>
</div>
CSS3:
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(550px, 1fr));
grid-auto-rows: auto;
grid-gap: 10px;
}
Please refer:
https://codepen.io/prashantbiradar92/pen/MWgXGpG?&editable=true
Problem:
The div with id foo-1,foo-3,foo-5 should be in 1 column and foo-2, foo-4 in 2nd column, with no whitespace. It should display in order.
So currently there is gutter for the div foo-5. So I have to adjust the div foo-5.

You need something like this?
https://codepen.io/hisbvdis/pen/XWrYqqO
* {
box-sizing: border-box;
}
.wrapper {
border: 2px solid #f76707;
border-radius: 5px;
background-color: #fff4e6;
}
.wrapper>div {
border: 2px solid #ffa94d;
border-radius: 5px;
background-color: #ffd8a8;
padding: 1em;
color: #d9480f;
}
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fit, minmax(550px, 1fr));
grid-auto-rows: 50px;
grid-gap: 10px;
}
.col-1 {
grid-column-start: 1;
}
.big {
grid-row: span 2;
}
<div class="wrapper">
<div class="col-1" id="foo-1">One</div>
<div id="foo-2">Two</div>
<div class="col-1" id="foo-3">Three</div>
<div class="big" id="foo-4">Four</div>
<div class="col-1" id="foo-5">Five</div>
</div>

Related

How to create a three-column list in with items arranged vertically

I have a problem to style a ul using display: grid. The list should look like the picture below. Elements in this ul can have different heights.
Expected behavior
So far I've added a styles for
ul: grid-template-columns: 1fr 1fr 1fr and grid-auto-flow: column.
For li elements, depending on in which column element should be:
grid-column: 1 or grid-column: 2 or grid-column: 3.
.wrapper {
margin: 0;
padding: 0;
list-style-type: none;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-auto-flow: columns;
row-gap: 10px;
column-gap: 10px;
}
.first-column {
grid-column: 1;
height: 200px;
background-color: skyblue;
}
.second-column {
grid-column: 2;
height: 500px;
background-color: aquamarine;
}
.third-column {
grid-column: 3;
height: 300px;
background-color: silver;
}
<ul class="wrapper">
<li class="first-column"></li>
<li class="first-column"></li>
<li class="second-column"></li>
<li class="second-column"></li>
<li class="third-column"></li>
<li class="third-column"></li>
</ul>
However, this causes the row height to be determined by the highest element in the row. Just like in the picture below.
current behavior
Here's how I did it:
.grid{
display: grid;
grid-template-columns: 100px 200px 100px;
column-gap: 50px; /* The gap you want */
}
.col{
display: grid;
grid-template-rows: repeat(4, 100px);
row-gap: 100px; /* The gap you want */
}
.col.spec{
grid-template-rows: repeat(3, 200px);
row-gap: 50px; /* The gap you want */
}
.elm{
width: 100%;
border: 1px solid black;
}
<div class="grid">
<div class="col">
<div class="elm"></div>
<div class="elm"></div>
<div class="elm"></div>
<div class="elm"></div>
</div>
<div class="col spec">
<div class="elm"></div>
<div class="elm"></div>
<div class="elm"></div>
</div>
<div class="col">
<div class="elm"></div>
<div class="elm"></div>
<div class="elm"></div>
<div class="elm"></div>
</div>
</div>
You can always adjust the stylings and dimensions as you want but make sure to make it responsive.

How to use CSS grid to create 3x3 grid but place items in specific grid columns

I'm trying to create a layout that looks like this:
The blue blocks are divs. It's essentially a 3x3 grid but with gaps in the 3rd and 4th grid column.
How can I create a gap within CSS grid to achieve this layout? I've tried it with flexbox, but couldn't achieve the above, so hoping a grid layout is the answer.
Here's my code:
.container{
border: 1px solid;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
gap: 0px 0px;
grid-template-areas:
". . ."
". . .";
}
.item{
border: 1px solid lightgrey;
padding: 10px;
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
CSS grid allows you to choose which row and column an element will start in (and indeed, though not needed in your case, how many columns/rows it is to span).
This snippet gives the 3rd and 4th children of the wrapper specific grid positions.
.container {
border: 1px solid;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-gap: 10px;
}
.item {
border: 1px solid lightgrey;
padding: 10px;
}
.item:nth-child(3) {
grid-column: 2;
grid-row: 2;
}
.item:nth-child(4) {
grid-column: 3;
grid-row: 2;
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
Note: just for a demo it has also introduced a non-zero grid-gap. The grid-area settings have been removed as not needed if the above method is followed.
A simplified version of the CSS grid solution with only the necessary code:
.container{
border: 1px solid;
display: grid;
grid-auto-columns: 1fr;
grid-auto-rows: 1fr;
grid-gap:5px;
}
.item{
border: 1px solid lightgrey;
padding: 10px;
}
.item:nth-child(3) {
grid-column:2;
}
.item:nth-child(4) {
grid-column:3;
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
How about padding/margin?
.container {
border: 1px solid #777;
display: inline-grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
gap: 0 0;
grid-template-areas:
". . ."
". . .";
}
.item {
border: 1px solid lightgrey;
padding: 2px 0;
width: 55px !important;
height: 50px !important;
margin: 1px !important;
background: #1657c9;
text-align: center;
font-family: Arial, Helvetica, sans-serif;
color: white;
}
.item-text {
position: relative;
top: 38%;
margin: 0;
font-size: normal;
}
.item-3, .item-4 {
position: relative;
left: 100%;
}
<div class="container">
<div class="item item-1"><span class="item-text">1</span></div>
<div class="item item-2"><span class="item-text">2</span></div><br>
<div class="item item-3"><span class="item-text">3</span></div>
<div class="item item-4"><span class="item-text">4</span></div>
</div>
You can try this:
This is HTML:
<div class="parent">
<div class="div1"> </div>
<div class="div2"> </div>
<div class="div3"> </div>
<div class="div4"> </div>
</div>
and CSS
.parent {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-rows: repeat(5, 1fr);
grid-column-gap: 0px;
grid-row-gap: 0px;
}
.div1 {
grid-area: 1 / 1 / 2 / 2;
background: blue;
height: 3rem;
margin: 1rem;
}
.div2 {
grid-area: 1 / 2 / 2 / 3;
background: blue;
height: 3rem;
margin: 1rem;
}
.div3 {
grid-area: 2 / 2 / 3 / 3;
background: blue;
height: 3rem;
margin: 1rem;
}
.div4 {
grid-area: 2 / 3 / 3 / 4;
background: blue;
height: 3rem;
margin: 1rem;
}

How to make a css grid item larger

I think this question has been asked multiple times, but I wasn't able to find an answer about when items are in the same grid-row.
I have 2 items inside a grid. I would like that the item on the right takes 2 times the space of the one on the left
I have the following.
Thanks
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
grid-gap: 12px;
grid-template-areas: "icon text text";
border: 1px solid black;
}
.item-left {
grid-area: icon;
border: 1px solid red;
}
.item-right {
grid-area: text;
border: 1px solid blue;
}
<div class='container'>
<div class='item-left'>Left grid item: Icon I want to be small</div>
<div class='item-right'>Right grid item: Some text I want to be larger</div>
</div>
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.left {
grid-column: 1;
background-color: red; /* Just so we can see it */
}
.right {
grid-column: 2 / end;
background-color: blue; /* ^^^ */
}
<div class="container">
<div class="left">Left</div>
<div class="right">Right</div>
</div>
Just use three grid columns and order the elements as such.
<style>
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.item-left {
grid-area: icon;
grid-column: 1;
border: 1px solid red;
}
.item-right {
grid-area: text;
grid-column: 2 / end;
border: 1px solid blue;
}
</style>
<div class='container'>
<div class='item-left'>Left grid item: Icon I want to be small</div>
<div class='item-right'>Right grid item: Some text I want to be larger</div>
</div>

CSS grid auto-fill and full-width cell - empty columns

I'm trying to build a CSS layout with one or two columns (depending on page width), and a full-width "navbar" above them. I don't want to use a media query, if possible.
* { word-wrap: break-word; }
#grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}
nav {
grid-column: 1 / -1;
}
/* only for visualisation */
#grid > * { margin: 5px; }
.col { border: 1px dashed black; }
nav { border: 1px solid blue; }
#grid { border: 1px solid red; }
<div id="grid">
<nav>full width nav</nav>
<div class="col">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</div>
<div class="col">bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div>
</div>
Narrow screen:
Normal screen:
However, it decides to add a third or even more empty columns if the screen is too wide. I can sort of fix it by increasing the min value in minmax, but then it overflows when the page is too narrow.
This glitch does not happen if I remove the full-width cell.
How can I fix it?
Here is a jsfiddle demo
You can simply increase the minmax width here repeat(auto-fit, minmax(300px, 1fr)) from 300px to 450px but this will cause the layout to shrink into two rows to early but in full screen will fit into it so if you don't have any problem with the shrinking to early just the bellow
Example
* {
word-wrap: break-word;
}
#grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(450px, 1fr));
border: 1px solid red;
grid-gap: 10px;
}
nav {
grid-column: 1 / -1;
border: 1px solid blue;
}
.col {
border: 1px dashed black;
}
<div id="grid">
<nav>full width nav</nav>
<div class="col">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</div>
<div class="col">bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div>
</div>
But if you don't like the early shrinking the only best possible way to achieve it in ride into media queries by detecting the screen size that you want your layout to shrink into two rows then there put repeat(1, minmax(300px, 1fr)); to respect one column otherwise use repeat(2, minmax(300px, 1fr)); for two columns.
And also by that way you can easily set the minmax to zero like repeat(2, minmax(0, 1fr)); which will look great when the screen is too small
Example
* {
word-wrap: break-word;
}
#grid {
display: grid;
grid-template-columns: repeat(2, minmax(300px, 1fr));
border: 1px solid red;
grid-gap: 10px;
}
nav {
grid-column: 1 / -1;
border: 1px solid blue;
}
.col {
border: 1px dashed black;
}
#media (max-width: 750px) {
#grid {
grid-template-columns: repeat(1, minmax(300px, 1fr));
}
}
<div id="grid">
<nav>full width nav</nav>
<div class="col">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</div>
<div class="col">bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div>
</div>
this is a flexbox job:
* {
word-wrap: break-word;
}
#grid {
display: flex;
flex-wrap:wrap;
gap:10px;
border: 1px solid red;
}
nav {
width:100%;
border: 1px solid blue;
}
.col {
border: 1px dashed black;
flex-basis:300px;
min-width:0;
flex-grow:1;
}
<div id="grid">
<nav>full width nav</nav>
<div class="col">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</div>
<div class="col">bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb</div>
</div>

How to achieve grid row with more than one element vertically?

I have a two column grid layout that holds boxes of heights X and 2X (fiddle, screenshot below)
Box number two has empty space underneath it, enough empty space to fit box 3:
I want to know if it is possible to have card 3 placed in that empty space (and have card 4 take card 3's place, and card 5 take card 4's place)
I attempted this layout with flex, but I reached this same situation.
.boxes {
display: grid;
grid-template-columns: 1fr 1fr;
grid-column-gap: 25px;
grid-row-gap: 25px;
}
.smallbox {
border: 2px solid black;
padding: 1em;
height: 50px;
}
.bigbox {
border: 1px solid black;
padding: 1em;
background: red;
height: 150px;
}
<div class="boxes">
<div class="bigbox">1</div>
<div class="smallbox">2</div>
<div class="smallbox">3</div>
<div class="smallbox">4</div>
<div class="smallbox">5</div>
</div>
Don't set the height on the grid items themselves.
Use grid-auto-rows at the container level, then span for the grid areas.
.boxes {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-rows: 50px; /* new */
grid-column-gap: 25px;
grid-row-gap: 25px;
}
.smallbox {
grid-row: span 1; /* new */
border: 2px solid black;
padding: 1em;
}
.bigbox {
grid-row: span 3; /* new */
border: 1px solid black;
padding: 1em;
background: red;
}
<div class="boxes">
<div class="bigbox">1</div>
<div class="smallbox">2</div>
<div class="smallbox">3</div>
<div class="smallbox">4</div>
<div class="smallbox">5</div>
</div>