Need assist with CSS grid layout of cards - html

I have this grid over here:
and i want the first big card to take the whole height of the wrapper and remain the same width, while the bottom two cards go to the right, somehow like this:
here's my css/html code where item-1 is the bigger card on the top-left:
.cards-wrapper {
background-color: #43cbff;
width: 1240px;
height: 380px;
margin: 0 auto;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: auto;
grid-gap: 20px;
#media (min-width: 30em) {
grid-template-columns: 1fr 1fr;
}
#media (min-width: 60em) {
grid-template-columns: repeat(4, 1fr);
}
}
.cards {
display: flex;
flex-direction: column;
min-height: 100%;
position: relative;
top: 0;
background-color: aquamarine;
border: 1px solid lightgrey;
border-radius: 8px;
}
.item-1 {
#media (min-width: 60em) {
grid-column: 1 / span 2;
h1 {
font-size: 24px;
}
}
}

You can keep the grid layout and use grid-template-areas to make that first item take up the full height whilst retaining its existing width.
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-auto-columns: 1fr;
grid-auto-rows: 1fr;
gap: 8px 8px;
grid-auto-flow: row;
grid-template-areas:
"one one two three"
"one one four five";
}
.container * {
background: orange;
}
.one { grid-area: one; }
.two { grid-area: two; }
.three { grid-area: three; }
.four { grid-area: four; }
.five { grid-area: five; }
<div class="container">
<div class="one">1</div>
<div class="two">2</div>
<div class="three">3</div>
<div class="four">4</div>
<div class="five">5</div>
</div>

Flex version
I dont know you entire structure and your requirement. But by using only flexbox you can archive this also quite easy.:
.cards-wrapper {
background: gray;
}
.flex {
display: flex;
gap:5px;
}
.left, .right {
width: 50%;
}
.right {
flex-wrap: wrap;
justify-content: center;
}
.right > div {
width: 49,2%;
background-color: lightgreen;
height:100px;
}
.big {
background-color: green;
width: 100%;
}
<div class="cards-wrapper flex">
<div class="left flex">
<div class="big">BIG</div>
</div>
<div class="right flex">
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</div>
</div>

Related

CSS layout - grid or flex [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I'm trying to create this layout.
https://pasteboard.co/K1C5o3k.jpg
I tried to use display: grid but the spacing was strange. What would be the best solution? Use grid or flexbox? How do I achieve this spacing using grid or flexbox?
<div class="wrap">
<div class="test-grid">
<div class="card box1">some text</div>
<div class="card box2">some text</div>
<div class="card">some text</div>
<div class="card box4">some text</div>
</div>
</div>
.wrap {
max-width: 600px;
}
.test-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, 1fr);
gap: 1em;
}
.card {
background-color: tomato;
width: 160px;
min-height: 220px;
}
.box1 {
margin-top: 40px;
}
.box4 {
grid-column-start: 2;
grid-column-end: 4;
grid-row-start: 2;
grid-row-end: 3;
}
On your grid layout, I use grid-template-row/columns to define the fraction amount and then grid-template-areas to layout the elements, for each child element you want to define the unique class as its grid-area. You can use gap to control the spacing between the elements. Once you define a height and width for the parent element, the children will fill in their respective fraction, along with any defined gap.
Then use a media query with flex for your mobile layout. You may need to tweek the CSS a bit to get it to look just as you want, but the following example should do the trick.
.test-grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr 1fr;
gap: 20px 20px;
grid-template-areas:
". two ."
"one two four"
"one three four"
". three .";
width: 100vw;
height: 100vh;
}
.one {
grid-area: one;
background-color: tomato;
}
.two {
grid-area: two;
background-color: tomato;
}
.three {
grid-area: three;
background-color: tomato;
}
.four {
grid-area: four;
background-color: tomato;
}
.box {
display: flex;
justify-content: center;
align-items: center;
}
#media only screen and (max-width: 600px) {
.test-grid {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100vw;
height: 100vh;
}
.box {
width: 100%;
height: 100%;
}
}
<div class="test-grid">
<div class="one box">some text</div>
<div class="two box">some text</div>
<div class="three box">some text</div>
<div class="four box">some text</div>
</div>
Both Grid and flex will do the work, it just based on your preferences.
Snippet below will do the trick and when the screen became small (less than 500px). The grid will show as a list.
.wrap {
max-width: 600px;
}
.test-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, 1fr);
gap: 1em;
}
.card {
background-color: tomato;
width: 160px;
min-height: 220px;
}
.box1 {
grid-column: 1/span 1;
grid-row: 2/span 2;
}
.box2 {
grid-column: 2/span 2;
grid-row: 1/span 1;
}
.box3 {
grid-column: 3/span 2;
grid-row: 2/span 2;
}
.box4 {
grid-column: 2/span 2;
grid-row: 3/span 3;
}
#media (max-width: 500px) {
.test-grid {
display: flex;
flex-direction: column;
justify-content: space-between;
}
}
<div class="wrap">
<div class="container">
<div class="test-grid">
<div class="card box1">box1</div>
<div class="card box2">box2</div>
<div class="card box3">box3</div>
<div class="card box4">box4</div>
</div>
</div>
Here's an option using only grid. In this example we create many small grid rows (10px each) which then allows you to start each element at a specific row and adjust the boxes by 10 pixel increments.
.test-grid {
display: grid;
grid-template-columns: repeat(3, 160px);
grid-template-rows: repeat(45, 10px);
column-gap: 10px;
}
.card {
background-color: tomato;
width: 160px;
min-height: 220px;
}
.box1 {
grid-row-start: 10;
}
.box2 {
grid-row-start: 0;
grid-column-start: 2;
}
.box3 {
grid-row-start: 24;
grid-column-start: 2;
}
.box4 {
grid-row-start: 8;
grid-column-start: 3;
}
<div class="wrap">
<div class="test-grid">
<div class="card box1">some text</div>
<div class="card box2">some text</div>
<div class="card box3">some text</div>
<div class="card box4">some text</div>
</div>
</div>

Avoiding dead DIVs in an HTML grid

The objective is to insert side margins for wider screens, while keeping the header span the entire width.
Normally we'd write
.inner {
margin: 0 5%;
}
to get such margins, but it turns out that HTML grids are so flexible that they make side margins possible through dead grid DIVs.
But somehow using dead DIVs does not seem quite right. Is there a way to obtain side margins within a grid. I see how this can be done with a blend of flex and grid. Here I'm wondering if it can be done with grids alone.
body {
height: 100vh; margin: 0; display: flex;
}
.outer{
margin: 5px; border: 5px; padding: 5px;
display: flex;
flex-grow: 1;
}
.inner {
flex-grow: 1;
margin: 5px; border: 5px; padding: 5px; grid-gap: 5px;
display: grid;
grid-template-rows: 100px 5fr 100px;
grid-template-columns: 1fr;
grid-template-areas: "header" "content" "side";
}
#media screen and (min-width: 600px) {
.inner {
grid-template-rows: 100px 6fr;
grid-template-columns: 5fr 100px;
grid-template-areas:
"header header"
"content side";
}
}
#media screen and (min-width: 800px) {
.inner {
grid-template-rows: 100px 6fr;
grid-template-columns: 1fr 5fr 100px 1fr;
grid-template-areas:
"header header header header"
"leftmargin content side rightmargin";
}
}
.box {
padding: 10px; margin: 5px;
border: 5px solid #444;
background-color: #eee;
font-size: 150%;
position: relative;
}
.header { grid-area: header; }
.content { grid-area: content; }
.side { grid-area: side; }
.leftmargin { grid-area: leftmargin; }
.rightmargin { grid-area: rightmargin; }
<div class="outer">
<div class="inner">
<div class="box header">Header</div>
<div class="box content">Content</div>
<div class="box side">Side</div>
</div>
</div>
Use dots (.) to declare empty grid areas:
grid-template-areas:
"header header header header"
". content side .";
Example:
body {
height: 100vh;
margin: 10px;
}
.inner {
display: grid;
grid-template-rows: 100px 5fr 100px;
grid-template-columns: 1fr;
grid-template-areas: "header" "content" "side";
grid-gap: 5px;
}
#media screen and (min-width: 600px) {
.inner {
grid-template-rows: 100px 6fr;
grid-template-columns: 5fr 100px;
grid-template-areas:
"header header"
"content side";
}
}
#media screen and (min-width: 800px) {
.inner {
grid-template-rows: 100px 6fr;
grid-template-columns: 5% 5fr 100px 5%;
grid-template-areas:
"header header header header"
". content side .";
}
}
.box {
padding: 10px; margin: 5px;
border: 5px solid #444;
background-color: #eee;
font-size: 150%;
position: relative;
}
.header { grid-area: header; }
.content { grid-area: content; }
.side { grid-area: side; }
<div class="inner">
<div class="box header">Header</div>
<div class="box content">Content</div>
<div class="box side">Side</div>
</div>

CSS Grid not working in ie11 despite prefixes

I have the following simple layout example using CSS grid
.container {
width: 100%;
display: -ms-grid;
display: grid;
-ms-grid-columns: 1fr auto 1fr;
grid-template-columns: 1fr auto 1fr;
}
.item1 {
text-align:center;
background:red;
color:white;
padding:20px
}
.item2 {
text-align:center;
background:green;
color:white;
padding:20px
}
.item3 {
text-align:center;
background:blue;
color:white;
padding:20px
}
<div class="container">
<div class="item1">
Item 1
</div>
<div class="item2">
Item 2
</div>
<div class="item3">
Item 3
</div>
</div>
I have prefixed with ie specific prefixes but the grid is not working correctly in ie11. Am I missing a prefix?
Anyone any ideas why?
IE does not have auto-flow of grid elements. You need to assign a specific grid position to each grid element, otherwise each non-placed element ends up stacked in 1,1.
.container {
width: 100%;
display: -ms-grid;
display: grid;
-ms-grid-columns: 1fr auto 1fr;
grid-template-columns: 1fr auto 1fr;
}
.item1 {
text-align: center;
background: red;
color: white;
padding: 20px;
-ms-grid-column: 1;
}
.item2 {
text-align: center;
background: green;
color: white;
padding: 20px;
-ms-grid-column: 2;
}
.item3 {
text-align: center;
background: blue;
color: white;
padding: 20px;
-ms-grid-column: 3;
}
<div class="container">
<div class="item1">
Item 1
</div>
<div class="item2">
Item 2
</div>
<div class="item3">
Item 3
</div>
</div>

When using CSS grid, i don't want some grid areas to expand

I'm starting to use CSS grid. So far, so good. I want some grid areas NOT to expand when other areas do.
This is what i have now
I'm designing mobile first, then desktop. The grid on the desktop, if you notice, the 'album' area expands when the body expands. I don't want that. I want the areas 'album', 'credits', 'version' to retain the height even if the 'body' or the 'comment' area expand. In other words, when a grid area expands, the other areas height remain intact.
https://jsfiddle.net/e9n4ac5d/
.grid {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: auto;
grid-template-areas: "body" "album" "credit" "version" "comment";
}
#media screen and (min-width: 400px) {
.grid {
grid-template-columns: 2fr 1fr;
grid-template-rows: auto;
grid-template-areas: "body album" "comment credit" "comment version";
}
}
.body {
grid-area: body;
background-color: red;
}
.album {
grid-area: album;
background-color: pink;
}
.credit {
grid-area: credit;
background-color: green;
}
.version {
grid-area: version;
background-color: yellow;
}
.comment {
grid-area: comment;
background-color: #eee;
}
<div class="grid">
<div class="body">body
<br><br><br><br><br><br>
</div>
<div class="album">album</div>
<div class="credit">credits</div>
<div class="version">version</div>
<div class="comment">comments</div>
</div>
You can change your HTML structure like this:
.grid {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: auto;
grid-template-areas: "body" "album" "credit" "version" "comment";
}
#media screen and (min-width: 400px) {
.right {
grid-area: right;
}
.grid {
grid-template-columns: 2fr 1fr;
grid-template-rows: auto;
grid-template-areas: "body right" "comment right";
}
}
.body {
grid-area: body;
background-color: red;
}
.album {
grid-area: album;
background-color: pink;
height: 50px;
}
.credit {
grid-area: credit;
background-color: green;
height: 50px;
}
.version {
grid-area: version;
background-color: yellow;
height: 50px;
}
.comment {
grid-area: comment;
background-color: #eee;
}
<div class="grid">
<div class="body">body
<br><br><br><br><br><br>
</div>
<div class="right">
<div class="album">album</div>
<div class="credit">credits</div>
<div class="version">version</div>
</div>
<div class="comment">comments</div>
</div>
Just set fixed height and width... To make it non expandable and non compressible...

Nested CSS grid layout different behavior in Chrome and Firefox

I'm trying to use CSS grid layout to simulate some responsive behavior, specifically with:
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
My example https://codepen.io/elgs/pen/goNxeL works well in Chrome, however, it doesn't seem to work in Firefox. You will find it when you resize the browser horizontally.
Another example https://codepen.io/elgs/pen/YYoxOq works well in both Chrome and Firefox.
html,body {
height: 100%;
width: 100%;
margin: 0 auto;
padding: 0;
}
body {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 100px 1fr 50px;
}
.header {
grid-column: 1/2;
grid-row: 1/2;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
background-color: #57324f;
}
.header .title {
grid-column: 1/2;
grid-row: 1/2;
align-self: center;
justify-self: center;
width: 100%;
max-width: 1000px;
color: aliceblue;
}
.footer {
grid-column: 1/2;
grid-row: 3/4;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
background-color: #57324f;
}
.footer .copyright {
grid-column: 1/2;
grid-row: 1/2;
align-self: center;
font-size: 12px;
justify-self: center;
width: 100%;
max-width: 1000px;
color: aliceblue;
}
.content {
grid-column: 1/2;
grid-row: 2/3;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 0;
background-color: aliceblue;
}
.content .main {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-gap: 10px;
grid-auto-flow: dense;
justify-self: center;
width: 100%;
margin-top: 10px;
max-width: 1000px;
}
.placeholder {
height: 100px;
position: relative;
border: 1px solid red;
}
<div class="header">
<div class="title">
<h2>Header</h2>
</div>
</div>
<div class="content">
<div class="main">
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
</div>
</div>
<div class="footer">
<div class="copyright">
<span>Footer</span>
</div>
</div>
I'm wondering whether I have done anything wrong or it's the browser's bug.
Firefox version: 58.0 (64-bit)
Chrome version: Version 64.0.3282.119 (Official Build) (64-bit)
This appears to be a bug in Firefox. But I'm not sure.
Here's what is clear:
The fact that you have nested grid containers matters.
Your second demo, which works in both Chrome and Firefox, has only one grid container.
The first demo, which only works in Chrome, has nested grid containers. If you eliminate that nesting, and use only one grid container, the layout works in both browsers.
So, as a possible cross-browser solution, minimize the nesting of grid containers.
In this revised demo, I've commented out display: grid on the body and .content elements. The only grid container left is on .main, the parent of the red boxes:
revised demo
html,
body {
height: 100%;
width: 100%;
margin: 0 auto;
padding: 0;
}
body {
/* display: grid; */
grid-template-columns: 1fr;
grid-template-rows: 100px 1fr 50px;
}
.header {
grid-column: 1/2;
grid-row: 1/2;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
background-color: #57324f;
}
.header .title {
grid-column: 1/2;
grid-row: 1/2;
align-self: center;
justify-self: center;
width: 100%;
max-width: 1000px;
color: aliceblue;
}
.footer {
grid-column: 1/2;
grid-row: 3/4;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
background-color: #57324f;
}
.footer .copyright {
grid-column: 1/2;
grid-row: 1/2;
align-self: center;
font-size: 12px;
justify-self: center;
width: 100%;
max-width: 1000px;
color: aliceblue;
}
.content {
grid-column: 1/2;
grid-row: 2/3;
/* display: grid; */
grid-template-columns: 1fr;
grid-template-rows: 0;
background-color: aliceblue;
}
.content .main {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-gap: 10px;
grid-auto-flow: dense;
justify-self: center;
width: 100%;
margin-top: 10px;
max-width: 1000px;
}
.placeholder {
height: 100px;
position: relative;
border: 1px solid red;
}
<div class="header">
<div class="title">
<h2>Header</h2>
</div>
</div>
<div class="content">
<div class="main">
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
</div>
</div>
<div class="footer">
<div class="copyright">
<span>Footer</span>
</div>
</div>
In Firefox, a fixed value on max-width prevents the box from shrinking to accommodate smaller screen sizes.
Firefox has a problem shrinking the .main container with a pixel value on the max-width. Chrome does not.
A typical solution that comes to mind is to override the min-width: auto default setting on grid items. This prevents items from shrinking past the size of their content or their defined width.
However, that solution, described here: Prevent content from expanding grid items ... doesn't work in this case.
(Probably because there is no content in and no defined widths on the grid items. The only widths defined are on the grid columns, set on the grid container. So the solution, which applies only to grid items, probably doesn't even apply.)
As a possible workaround, if you must keep the nested containers, then instead of using a fixed value with max-width, use a percentage value. That may work for you.
revised codepen
body {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 100px 1fr 50px;
height: 100vh;
margin: 0;
}
.header {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
background-color: #57324f;
}
.content {
display: grid;
grid-template-columns: 1fr;
/* grid-template-rows: 0; */
align-content: start; /* new */
background-color: aliceblue;
}
.content .main {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-auto-rows: 100px; /* new */
grid-gap: 10px;
grid-auto-flow: dense;
justify-self: center;
width: 100%;
margin-top: 10px;
/* max-width: 1000px; */
max-width: 75%; /* new */
}
.placeholder {
border: 1px solid red;
}
.footer {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr;
background-color: #57324f;
}
.header .title,
.footer .copyright {
align-self: center;
justify-self: center;
width: 100%;
max-width: 1000px;
color: aliceblue;
}
.footer .copyright {
font-size: 12px;
}
<div class="header">
<div class="title">
<h2>Header</h2>
</div>
</div>
<div class="content">
<div class="main">
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
<div class="placeholder"></div>
</div>
</div>
<div class="footer">
<div class="copyright">
<span>Footer</span>
</div>
</div>