Grid items expand to follow offset between columns [duplicate] - html

This question already has answers here:
CSS-only masonry layout
(4 answers)
Closed 1 year ago.
I'm trying to make an html/css card system that automatically places itself on a css grid. This css grid is divided into two columns. In the left column, a div adds an offset to the rest of the column, and has no fixed size. I want to keep this offset between the two columns.
The problem is that the first card on the left (number 2) grows to compensate for the offset, but all cards must have the same size. How can I fix that without fixing the size of each card ?
What I would like to do:
What I currently have:
A simple example of code to reproduce it:
.grid {
display: grid;
background-color: #eee;
grid-gap: 5px 5px;
grid-template-columns: repeat(2, 1fr);
grid-auto-flow: dense;
}
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 60px;
font-size: 150%;
}
.grid__1 {
background-color: #ccc;
grid-column: 1 / 2;
padding: 5px;
font-size: 1rem;
}
.grid__item {
grid-column: span 1;
grid-row: span 2;
}
<div class="grid">
<div class="box grid__1">head</div>
<div class="box grid__item">1</div>
<div class="box grid__item">2</div>
<div class="box grid__item">3</div>
<div class="box grid__item">4</div>
<div class="box grid__item">5</div>
<div class="box grid__item">6</div>
</div>
I made a live example here : https://jsfiddle.net/rLpqt75d/3/

I did some research and it looks like you are trying to replicate a mansonry-layout.
If you don't know what it is, it is the layout used by pintarest.
After a while googleing I found a great article you could look into:
https://kulturbanause.de/blog/responsive-masonry-layout-mit-css/
I'll try to summarize:
In the future we will get a css property: grid-template-rows: masonry;
But until then we will have to stick to flex-box.
I copied the example of the blog post to a fiddle and modified it a little for a better overview:
https://jsfiddle.net/8k1nyg39/41/
Hope I could help someone (:
EDIT:
So I experimented a bit with it and it seems like you need a predetermined height for your container...
If you need your container to change height dynamically the only remaining workaround I know of would be a js library like Magic Grid ...

define a pair of rows for the property grid-auto-rows, this will set the correct size :
.grid {
display: grid;
background-color: #eee;
grid-gap: 5px 5px;
grid-template-columns: repeat(2, 1fr);
grid-auto-flow: dense;
grid-auto-rows: 40px 200px; /* added */
}
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 60px;
font-size: 150%;
}
.grid__1 {
background-color: #ccc;
grid-column: 1 / 2;
padding: 5px;
font-size: 1rem;
}
.grid__item {
grid-column: span 1;
grid-row: span 2;
}
<div class="grid">
<div class="box grid__1">head</div>
<div class="box grid__item">1</div>
<div class="box grid__item">2</div>
<div class="box grid__item">3</div>
<div class="box grid__item">4</div>
<div class="box grid__item">5</div>
<div class="box grid__item">6</div>
</div>

/* height is your var */
.grid {
display: grid;
background-color: #eee;
grid-gap: 5px 5px;
grid-template-columns: repeat(2, 1fr);
grid-auto-rows: 40px 1fr;
height: 100vh;
}
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 60px;
font-size: 150%;
}
.grid__head {
background-color: #ccc;
grid-column: 1 / 2;
padding: 15px;
font-size: 1rem;
}
.grid__item {
grid-column: span 1;
grid-row: span 2;
}
<div class="grid">
<div class="box grid__head">head</div>
<div class="box grid__item">1</div>
<div class="box grid__item">2</div>
<div class="box grid__item">3</div>
<div class="box grid__item">4</div>
<div class="box grid__item">5</div>
<div class="box grid__item">6</div>
</div>
enter link description here

Switch from grid-row: span 2 to span 3 (or 4) on .grid__item.
.grid {
display: grid;
background-color: #eee;
grid-gap: 5px 5px;
grid-template-columns: repeat(2, 1fr);
grid-auto-flow: dense;
}
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 60px;
font-size: 150%;
}
.grid__1 {
background-color: #ccc;
grid-column: 1 / 2;
padding: 5px;
font-size: 1rem;
}
.grid__item {
grid-column: span 1;
grid-row: span 3; /* ADJUSTMENT */
}
<div class="grid">
<div class="box grid__1">head</div>
<div class="box grid__item">1</div>
<div class="box grid__item">2</div>
<div class="box grid__item">3</div>
<div class="box grid__item">4</div>
<div class="box grid__item">5</div>
<div class="box grid__item">6</div>
</div>
The problem is that the first card on the left (number 2) grows to compensate for the offset, but all cards must have the same size.
If you switch from having the items span two rows (grid-row: span 2) to instead span three (grid-row: span 3), or four, the items can better absorb the offset height.
2 rows (original layout) — notice how the rows are laid out
3 rows (revised layout)
This may also be an alternative: CSS-only masonry layout

Related

grid-column-end: -1; weird behavior

What I intend to achieve is something that looks as follows:
Where the header spans the full width of the container, where there can be 3 or 4 columns having the same width in the second row, and where the footer has the same width as the first column.
I thought I could achieve this with the following HTML and CSS code, but no. grid-column-end is giving me headaches. If I set it to 5, it looks as I want in the case that there are four items in the second row, but not if there are only 3, in which case grid-column-end should be 4. Hence, the solution of using -1, which refers to the last grid-line, but then a grid containing something like 40 columns is created.
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(10px, 1fr));
grid-template-rows: auto minmax(0, 1fr) auto;
grid-gap: 10px;
width: 100%;
}
.header {
grid-column-start: 1;
grid-column-end: -1;
grid-row: 1;
background-color: #bbb;
padding: 20px;
}
.item {
background-color: #ddd;
border: 1px solid #aaa;
padding: 20px;
grid-row: 2;
}
.footer {
grid-column: 1 / 2;
grid-row: 3;
background-color: #bbb;
padding: 20px;
}
<div class="container">
<div class="header">Header</div>
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="footer">Footer</div>
</div>

display dynamic cards with different heights using grid css without gutter

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>

Making grid responsive

Any idea of how to make this grid responsive?
This is my CSS:
body {
margin: 40px;
}
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: 100px 100px 100px;
background-color: #fff;
color: #444;
}
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 20px;
font-size: 150%;
}
.a {
grid-column: 1 / 3;
grid-row: 1;
}
.b {
grid-column: 3 ;
grid-row: 1 / 3;
}
.c {
grid-column: 1 ;
grid-row: 2 ;
}
.d {
grid-column: 2;
grid-row: 2;
}
HTML
<div class="wrapper">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box c">C</div>
<div class="box d">D</div>
</div>
I tried this code:
#media only screen and (max-width:500px) {
.box {
width: 100%;
margin-right: 0;
float: none;
margin-bottom: 20px !important;
}
What's the best way to accomplish this?
I agree with #Petra that you need to use fr, but use a media query if you want to display them stacked on a mobile device. You could also just change the display to block. Make sure you add these after the initial CSS so that it isn't overridden.
#media screen and (max-width: 512px) {
.wrapper {
grid-template-columns: 1fr;
}
}
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: 1fr 1fr 1fr;
background-color: #fff;
color: #444;
}
ith CSS Grid Layout, we get a new flexible unit: the Fr unit. Fr is a fractional unit and 1fr is for 1 part of the available space.

Creating a bootstrap-like container

I am trying to build a container like bootstrap container that has padding from page sides.
Since I'm new in this topic, i really don't think this is the best way to create responsive and standard container.
i just want to know is there any other ways to do something like my project.
<div class="container">
<div>item 1</div>
<div>item 2</div>
<div>item 3</div>
</div>
.container{
width: 75%;
height: auto;
background: red;
margin: 0 auto;
padding: 1px;
}
this is how i created a responsive container with grid
/* white space from sides */
.container {
display: grid;
grid-template-columns: 80px 1fr 80px;
grid-gap: 2px;
}
.container > .grid-system {
grid-column: 2;
min-width: 0;
}
/* inner grid 12 column */
.grid-system {
display: grid;
grid-template-columns: repeat(12,1fr);
grid-gap: 10px;
background: green;
}
.grid-system > div{
background: red;
grid-column: 1;
padding: 12px 16px;
text-align: center;
color: white;
}
<div class="container">
<div class="grid-system">
<div>1</div>
<div>2</div>
<div>3</div>
</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>