Reputation: 16395
I'm trying to create a very generic dashboard. I have the Bootstrap breakpoints:
I have 3 different types of cards:
On the left and on the right side we have 20px padding.
The 4 column wide card can only be 4 columns wide when we actually have 4 columns. If we force the 4 column width on small screens it breaks the layout. On small screens we only have 1 column. On a tablet we might have only 2 columns. In those scenarios the 4 column card should be as large as possible but never larger than 4 columns.
The underlying question is: How can I specify the width for my cards and at the same time keep the responsive behavior? The challenge is not to specify fixed columns, e.g. grid-column: 1 / 3
. I'm getting the cards from the backend as a flat array. Each card then tells me if it wants to be 1, 2, or 4 columns wide. The cards do not have a certain order and the order might also change.
I also have a demo at StackBlitz - https://stackblitz.com/edit/js-ryxler?file=style.css
My questions are:
body,
html {
margin: 0;
}
/*
We're using the bootstrap breakpoints:
- 576px
- 768px
- 992px
- 1200px
- 1400px
We have 3 different types of cards:
- 1 column wide
- 2 columns wide
- 4 columns wide
On the left and on the right side we have 20px padding.
The 2 column layout appears at 768px => 2*354px + 3*20px = 768px
The 3 column layout appears at 992px => 3*304px + 4*20px = 992px
The 4 column layout appears at 1200px => 4*275px + 5*20px = 1200px
! Problem:
The 4 column wide card can only be 4 columns wide when we actually have 4 columns.
If we force the 4 column width on small screens it breaks the layout.
On small screens we only have 1 column.
On a tablet we might have only 2 columns.
In those scenarios the 4 column card should be as large as possible but never larger than 4 columns.
*/
.wrapper {
padding: 20px;
display: grid;
grid-auto-flow: dense;
grid-template-columns: repeat(auto-fill, minmax(354px, 1fr));
grid-auto-rows: 250px;
gap: 20px;
}
.blue {
background-color: lightblue;
}
.coral {
background-color: lightcoral;
grid-row: span 2;
}
.salmon {
background-color: lightsalmon;
}
.grid-column-2 {
grid-column: span 1;
}
.grid-column-4 {
grid-column: span 1;
}
/* 2 columns */
@media (min-width: 768px) {
.grid-column-2 {
grid-column: span 2;
}
.grid-column-4 {
grid-column: span 2;
}
}
/* 3 columns */
@media (min-width: 992px) {
.wrapper {
grid-template-columns: repeat(auto-fill, minmax(304px, 1fr));
}
.grid-column-4 {
grid-column: span 3;
}
}
/* 4 columns */
@media (min-width: 1200px) {
.wrapper {
grid-template-columns: repeat(auto-fill, minmax(275px, 1fr));
}
.grid-column-4 {
grid-column: span 4;
}
}
<div class="wrapper">
<div class="blue"></div>
<div class="blue"></div>
<div class="salmon grid-column-2"></div>
<div class="blue"></div>
<div class="blue"></div>
<div class="coral grid-column-4"></div>
<div class="salmon grid-column-2"></div>
<div class="blue"></div>
<div class="blue"></div>
<div class="blue"></div>
<div class="coral grid-column-4"></div>
<div class="blue"></div>
<div class="blue"></div>
<div class="blue"></div>
<div class="blue"></div>
<div class="blue"></div>
<div class="salmon grid-column-2"></div>
</div>
Thank you!
Upvotes: 1
Views: 269
Reputation: 2321
You can't specify exact width on exact breakpoint without media query but you can remove some CSS property
For exemple
// This will make it take all the columns available
.grid-column-4 {
grid-column: 1 / -1;
}
body,
html {
margin: 0;
}
.wrapper {
padding: 20px;
display: grid;
grid-auto-flow: dense;
grid-template-columns: repeat(auto-fill, minmax(354px, 1fr));
grid-auto-rows: 250px;
grid-gap: 20px;
}
.blue {
background-color: lightblue;
}
.coral {
background-color: lightcoral;
}
.salmon {
background-color: lightsalmon;
}
.grid-column-4 {
grid-column: 1/-1;
// I saw that you were initialising this value on every breakpoint
// this will make it take all the columns available
}
/* 2 columns */
@media (min-width: 768px) {
.grid-column-2 {
grid-column: span 2;
}
}
/* 3 columns */
@media (min-width: 992px) {
.wrapper {
grid-template-columns: repeat(auto-fill, minmax(304px, 1fr));
}
}
/* 4 columns */
@media (min-width: 1200px) {
.wrapper {
grid-template-columns: repeat(auto-fill, minmax(275px, 1fr));
}
.grid-column-4 {
grid-column: span 4;
}
}
<div class="wrapper">
<div class="blue"></div>
<div class="blue"></div>
<div class="salmon grid-column-2"></div>
<div class="blue"></div>
<div class="blue"></div>
<div class="coral grid-column-4"></div>
<div class="salmon grid-column-2"></div>
<div class="blue"></div>
<div class="blue"></div>
<div class="blue"></div>
<div class="coral grid-column-4"></div>
<div class="blue"></div>
<div class="blue"></div>
<div class="blue"></div>
<div class="blue"></div>
<div class="blue"></div>
<div class="salmon grid-column-2"></div>
</div>
You could also use CSS variables to make it more modular
:root {
--size: 354px;
}
body,
html {
margin: 0;
}
.wrapper {
padding: 20px;
display: grid;
grid-auto-flow: dense;
grid-template-columns: repeat(auto-fill, minmax(var(--size), 1fr));
grid-auto-rows: 250px;
grid-gap: 20px;
}
.blue {
background-color: lightblue;
}
.coral {
background-color: lightcoral;
}
.salmon {
background-color: lightsalmon;
}
.grid-column-4 {
grid-column: 1/-1;
// I saw that you were initialising this value on every breakpoint
// this will make it take all the columns available
}
/* 2 columns */
@media (min-width: 768px) {
.grid-column-2 {
grid-column: span 2;
}
}
/* 3 columns */
@media (min-width: 992px) {
:root {
--size: 304px;
}
}
/* 4 columns */
@media (min-width: 1200px) {
:root {
--size: 275px;
}
.grid-column-4 {
grid-column: span 4;
}
}
<div class="wrapper">
<div class="blue"></div>
<div class="blue"></div>
<div class="salmon grid-column-2"></div>
<div class="blue"></div>
<div class="blue"></div>
<div class="coral grid-column-4"></div>
<div class="salmon grid-column-2"></div>
<div class="blue"></div>
<div class="blue"></div>
<div class="blue"></div>
<div class="coral grid-column-4"></div>
<div class="blue"></div>
<div class="blue"></div>
<div class="blue"></div>
<div class="blue"></div>
<div class="blue"></div>
<div class="salmon grid-column-2"></div>
</div>
Upvotes: 1