Multiple equal row height in CSS Grid Layout [duplicate] - html

This question already has answers here:
Align child elements of different blocks
(3 answers)
Closed 2 years ago.
How can I make all footers (with green background) same height, keeping content height also the same, too?
Current output:
Desired output:
CodePen: https://codepen.io/yasincad/pen/poNPgYv
Current HTML:
<div class="cards">
<div class="card">
<div>Long...<br><br><br>content</div>
<div class="card-footer">
<h3>Footer title</h3>
<div>Long...<br><br>footer text</div>
</div>
</div>
<div class="card">
<div>Shorter content</div>
<div class="card-footer">
<h3>Footer title</h3>
<div>Short footer text</div>
</div>
</div>
</div>
Current CSS:
.cards {
width: 600px;
column-gap: 30px;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}
.card {
background-color: lightgrey;
display: grid;
grid-template-rows: 1fr auto auto;
}
.card-footer {
background: lightgreen;
}

.cards {
width: 83vw;
column-gap: 3vw;
display: flex;
}
.card {
background-color: lightgrey;
width:40vw;
}
.card-footer {
background: lightgreen;
width:40vw;
}
<div class="cards">
<div class="card">
<div>Long...<br><br><br>content</div>
</div>
<div class="card">
<div>Shorter content</div>
</div>
</div>
<div class='cards'>
<div class="card-footer">
<h3>Footer title</h3>
<div>Long...<br><br>footer text</div>
</div>
<div class="card-footer">
<h3>Footer title</h3>
<div>Short footer text</div>
</div>
</div>

Related

Having problems with fitting content in div with css grid

I'm playing around with Css Grid and having problems with fitting overlaying content.
There is a top level container defined as css grid (class="container"), then content grid (class="content") which splits into 3 rows (header, label, rows).
Header is just a header, label contains labels for rows and rows is a content of "table".
Here is what it looks like:
When I resize window I got scroll bar on the right but it's for the whole page. Instead I would like to scroll only rows not the whole page.
Here is the the StackBlitz working example:
https://stackblitz.com/edit/angular-ivy-ayujp5
I guess it's simple but having problems with understanding how height is calculated and where and how overflow properties should be defined.
p {
font-family: Lato;
}
.container {
display: grid;
grid-template-columns: 30px 1fr 30px;
grid-template-rows: 30px 1fr 30px;
grid-template-areas: '. . .' '. content .' '. . .';
}
.content {
grid-area: content;
display: grid;
grid-template-rows: 50px 30px 1fr;
grid-template-areas: 'header' 'label' 'rows';
}
.header {
grid-area: header;
}
.label {
grid-area: label;
display: grid;
grid-template-rows: 1fr;
grid-template-columns: repeat(3, 4fr);
align-items: center;
}
.rows {
grid-area: rows;
height: 100%;
}
.row {
background-color: pink;
margin: 5px 0px;
border-width: 1px;
border-radius: 10px;
padding: 25px;
color: black;
}
<div class="container">
<div class="content">
<div class="header">Header</div>
<div class="label">
<div>Name</div>
<div>From</div>
<div>To</div>
</div>
<div class="rows">
<div class="row">
<div class="label">
<div>1</div>
<div>1999/01/01</div>
<div>1999/12/01</div>
</div>
</div>
<div class="row">
<div class="label">
<div>2</div>
<div>1999/01/01</div>
<div>1999/12/01</div>
</div>
</div>
<div class="row">
<div class="label">
<div>2</div>
<div>1999/01/01</div>
<div>1999/12/01</div>
</div>
</div>
<div class="row">
<div class="label">
<div>3</div>
<div>1999/01/01</div>
<div>1999/12/01</div>
</div>
</div>
<div class="row">
<div class="label">
<div>4</div>
<div>1999/01/01</div>
<div>1999/12/01</div>
</div>
</div>
</div>
I go with height calculation .pin-table { height: calc(100vh - 125px); overflow: auto; } but if anyone has better idea feel free to write.

complex grid layout which collapse into a single column on small screen

In the code below, I am trying to implement a grid made of 2 rows of 3 images in the bottom right corner only. The grid should not be bigger than the other quarters. In other words, I would like each quarter to be of the same size, but the bottom right one should have these 2 rows of 3 images.
My key objective is to have a method which collapses into a single column on small screens, with the images on top of each other. So on small screens, there shouldn't be any more grids, but just a column of images below the 3 quarters:
On normal screen:
| Hello World | 2 |
| | |
| 3 | img img img |
| | img img img |
On small screens:
Hello World
2
3
img
img
img
img
img
img
Here is my code, which does not work...
<!DOCTYPE html>
<html>
<head>
<style>
.box.md {
grid-column: span 2;
grid-row: span 2;
}
.box.lg {
grid-column: span 2;
grid-row: span 2;
}
.container {
padding: 20px;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
grid-auto-rows: 240px;
grid-auto-flow: dense;
grid-gap: 8px;
}
.box {
background: yellow;
display: flex;
justify-content: center;
align-items: center;
font-size: 48px;
font-weight: bold;
}
.grid-container {
display: grid;
grid-template-columns: auto auto auto;
}
.item1 {
grid-row-start: 1;
grid-row-end: 3;
}
</style>
</head>
<body>
<h1>Test:</h1>
<div class="container">
<div class="box md">
<p> Hello World </p>
</div>
<div class="box md">2</div>
</div>
<div class="container">
<div class="box md">3</div>
<div class="container">
<div class="row" >
<div class="grid-container">
<div class="item1">
<a><img src="AI.jpg"></a>
</div>
<div class="item2">
<a><img src="AI.jpg"></a>
</div>
<div class="item3">
<a><img src="AI.jpg"></a>
</div>
<div class="item4">
<a><img src="AI.jpg"></a>
</div>
<div class="item5">
<a><img src="AI.jpg"></a>
</div>
<div class="item6">
<a><img src="AI.jpg"></a>
</div>
</div>
</div>
</div>
</div>
.box.md {
grid-column: span 2;
grid-row: span 2;
}
.box.lg {
grid-column: span 2;
grid-row: span 2;
}
.container {
padding: 20px;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
grid-auto-rows: 240px;
grid-auto-flow: dense;
grid-gap: 8px;
}
.box {
background: yellow;
display: flex;
justify-content: center;
align-items: center;
font-size: 48px;
font-weight: bold;
}
.grid-container {
display: grid;
grid-template-columns: auto auto auto;
}
.item1 {
grid-row-start: 1;
grid-row-end: 3;
}
<h1>Test:</h1>
<div class="container">
<div class="box md">
<p> Hello World </p>
</div>
<div class="box md">2</div>
</div>
<div class="container">
<div class="box md">3</div>
<div class="container">
<div class="row">
<div class="grid-container">
<div class="item1">
<a><img src="AI.jpg"></a>
</div>
<div class="item2">
<a><img src="AI.jpg"></a>
</div>
<div class="item3">
<a><img src="AI.jpg"></a>
</div>
<div class="item4">
<a><img src="AI.jpg"></a>
</div>
<div class="item5">
<a><img src="AI.jpg"></a>
</div>
<div class="item6">
<a><img src="AI.jpg"></a>
</div>
</div>
</div>
</div>
</div>
Could anyone help me solve this problem?
Kind regards,
-Pierre.
Using flex with wrap to layout your main "grid". Using grid with auto-fit columns to layout the pictures.
I did that because I suppose you are after a fluid layout. It would be much easier to adapt to any screen using media queries...
You should try the snippet in full-screen and test with various windows sizes. Pictures layout can be suited to your requirements by changing the pixel size in minmax(240px, 1fr) for .grid-container.
.container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.container > * {
flex: 1;
min-width: 300px;
min-height: 250px;
}
.box {
background: yellow;
display: flex;
justify-content: center;
align-items: center;
font-size: 48px;
font-weight: bold;
}
.grid-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
grid-auto-rows: minmax(120px, max-content);
gap: .5rem;
padding: .5rem;
}
.grid-container a {
display: flex;
align-items: center;
justify-content: center;
max-height: 100%;
max-width: 100%;
}
.grid-container img {
display: block;
max-width: 100%;
max-height: 100%;
}
<h1>Test:</h1>
<div class="container">
<div class="box md">
<p> Hello World </p>
</div>
<div class="box md">2</div>
</div>
<div class="container">
<div class="box md">3</div>
<div class="container">
<div class="row">
<div class="grid-container">
<div class="item1">
<a><img src="https://picsum.photos/seed/pic1/300/200"></a>
</div>
<div class="item2">
<a><img src="https://picsum.photos/seed/pic2/300/200"></a>
</div>
<div class="item3">
<a><img src="https://picsum.photos/seed/pic3/300/200"></a>
</div>
<div class="item4">
<a><img src="https://picsum.photos/seed/pic4/300/200"></a>
</div>
<div class="item5">
<a><img src="https://picsum.photos/seed/pic5/300/200"></a>
</div>
<div class="item6">
<a><img src="https://picsum.photos/seed/pic6/300/200"></a>
</div>
</div>
</div>
</div>
</div>
You coumd try something with calc() and clamp() to give a minmax() value to your columns dependind on a set px value to init calc(clamp()) ; and the unknown value that is 100vw. Playing around with those, it allows you to set a min and max-width while the calc() function updates with the viewport's width. It can give a failing value (if calculation turns out to be less than 0).
Once you understood how it worked, you can use your own values to reset your breakpoints without a mediaquerie but auto-fit.
Example setting every items as direct child of the container and using nested grid with different calc(clamp()) setting :
* {box-sizing:border-box;}
.container {
display:grid;
grid-template-columns: repeat(auto-fit,minmax(clamp(calc(((200px + 50vw ) * 2 ) - 100vw ), 40vw, 100% ) ,1fr));
gap:1em;
width:100%;
}
.box.md {
max-width:100%;
border:solid;
color:red;
justify-content:space-around;
}
.box.md.img {
width: 100%;
grid-template-columns: repeat(auto-fit,minmax(calc(((140px + 25vw) * 2) - 50vw) ,1fr));
}
.box.md.img img {
width:100%;
}
<h1>Test: grid layout</h1>
<div class="container">
<div class="box md">
<p> Hello World </p>
</div>
<div class="box md">2</div>
<div class="box md">3</div>
<div class="box md img container">
<div class="item1 box img ">
<a><img src="https://dummyimage.com/200x100/&text=AI.jpg"></a>
</div>
<div class="item2 box img">
<a><img src="https://dummyimage.com/200x100/&text=AI.jpg"></a>
</div>
<div class="item3 box img">
<a><img src="https://dummyimage.com/200x100/&text=AI.jpg"></a>
</div>
<div class="item4 box img">
<a><img src="https://dummyimage.com/200x100/&text=AI.jpg"></a>
</div>
<div class="item5 box img">
<a><img src="https://dummyimage.com/200x100/&text=AI.jpg"></a>
</div>
<div class="item6 box img">
<a><img src="https://dummyimage.com/200x100/&text=AI.jpg"></a>
</div>
</div>
</div>
Pen to play with : https://codepen.io/gc-nomade/pen/PopPNoJ
See if this helps with the images grid
.container {
display: grid;
grid: auto auto/ 1fr 1fr 1fr;
}
#media (max-width: 450px) {
.container {
grid: auto / auto;
grid-auto-flow: row;
}
}
<div class="container">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
</div>
}

How to display container inside two columns?

I would like to display the content of these two columns only inside the container and the columns take the full width of the page like this image down bellow.
Is this possible by using css grid?
Thank you for your help and your support.
<div class="columns">
<div class="columns--container">
<div class="column">
<!-- Content -->
</div>
<div class="column">
<!-- Content -->
</div>
</div>
</div>
Ok, I'm new to grids, but this should work:
.columns {
height: 400px;
background: whitesmoke;
display: grid;
grid-template-columns: auto auto auto auto;
grid-gap: 10px;
}
.columns-container {
grid-column-start: 2;
grid-column-end: 4;
display: inherit;
grid-template-columns: auto auto;
flex-direction: row;
}
.column {
background: green;
}
<div class="columns">
<div class="columns-container">
<div class="column">
<!-- Content -->
</div>
<div class="column">
<!-- Content -->
</div>
</div>
</div>

Is it possible to put buttons under each element in a grid?

I'm trying to make a grid with items/pizza toppings to order, and I would like an "Add to cart" button under each item in the grid. How would I go about doing that?
So far I've tried simply putting a button with a line break under an element but as assumed, that didn't work.
Here is the relevant code I have in the body:
.wrapper {
width: 90%;
margin: 0 auto;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-auto-rows: 200px;
grid-row-gap: 30px;
grid-column-gap: 10px;
}
.item {
background: firebrick;
color: white;
padding: 10px;
}
.item:nth-child(even) {
background: rgb(139, 19, 19);
}
.add {
margin-bottom: 100px;
}
button {
margin-bottom: 100px;
}
#container {
background-color: maroon;
width: 1500px;
height: 1200px;
margin-left: auto;
margin-right: auto;
border-color: black;
border-width: 10px;
border-style: double;
}
<div id="container">
<div id="header">
<h1> Pizza Planet </h1>
<script src="index.js"></script>
</div>
<div id="content">
<h2>Select your items:</h2>
<div class="wrapper">
<div class="item">1</div>
<div class="add"><button>Add To Cart</button></div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
</div>
</div>
All that does is make a huge gap for another cell on the grid with a tiny add to cart button on there. Any help would be appreciated, thank you.
One approach might be to use CSS grid to achieve what you require. A simple grid layout for what you describe above could be done like this:
.item img {
width:100%;
/* Causes the button to sit below the img */
display:block;
}
.item button {
width:100%;
}
.grid {
/* Specifies css grid to be used */
display:grid;
/* Specifies the number of columns and sizes in the grid */
grid-template-columns: 1fr 1fr;
/* Specifies spacing between grid cells */
grid-gap:1rem;
}
<div class="grid">
<div class="item">
<img src="http://wallpapersdsc.net/wp-content/uploads/2015/11/Pizza_Images12.jpg" />
<button>Order</button>
</div>
<div class="item">
<img src="http://wallpapersdsc.net/wp-content/uploads/2015/11/Pizza_Images12.jpg" />
<button>Order</button>
</div>
<div class="item">
<img src="http://wallpapersdsc.net/wp-content/uploads/2015/11/Pizza_Images12.jpg" />
<button>Order</button>
</div>
<div class="item">
<img src="http://wallpapersdsc.net/wp-content/uploads/2015/11/Pizza_Images12.jpg" />
<button>Order</button>
</div>
</div>

css - using grid-auto-column to create dynamic widths

I'm trying to get my css grid to either be 2 blocks per row (if there are enough items) or a single block that spans the entire width. However, I can't seem to get it to work using grid-auto-column.
The top block is what I want it to look like, and the bottom block is what my current css is creating.
.flex1 {
display: flex;
flex-direction: row;
flex: 1;
}
.grid1 {
display: grid;
grid-auto-columns: minmax(50%, 100%);
}
div.height {
height: 50px;
width: 100%;
}
.red {
background-color: red;
}
.blue {
background-color: blue;
}
.green {
background-color: green;
}
<div class="flex1">
<div class="red height">
</div>
<div class="blue height">
</div>
</div>
<div>
<div class="green height">
</div>
</div>
<br><br>
<div class="grid">
<div class="red height">
</div>
<div class="blue height">
</div>
<div class="green height">
</div>
</div>
Unfortunately, as far as I know, this isn't possible with the Grid, but it's a perfect and easy job for Flexbox, since you only need to handle one or single dimensional layout, in your case rows.
Below I'm giving you the shorter version of the desired result / behavior of flex-items, with less markup and styling:
.flex {
display: flex;
flex-wrap: wrap; /* enables wrapping of flex-items */
}
.flex > div {
flex: 1 0 50%; /* grows full width if alone in a row / doesn't shrink / initial width set to 50%, i.e. can't be less than 50% of the parent's width */
height: 50px;
}
.red {background: red}
.blue {background: blue}
.green {background: green}
.yellow {background: yellow}
<div class="flex">
<div class="red"></div>
</div>
<br>
<div class="flex">
<div class="red"></div>
<div class="blue"></div>
</div>
<br>
<div class="flex">
<div class="red"></div>
<div class="blue"></div>
<div class="green"></div>
</div>
<br>
<div class="flex">
<div class="red"></div>
<div class="blue"></div>
<div class="green"></div>
<div class="yellow"></div>
</div>
Use grid-template-areas: "a b" "c c";(change .grid1 to .grid as in html)
Also set grid-area:; to each div inside .grid
.flex1 {
display: flex;
flex-direction: row;
flex: 1;
}
.grid {
display: grid;
grid-auto-columns: minmax(50%, 100%);
grid-template-areas: "a b" "c c";
}
div.height {
height: 50px;
width: 100%;
}
.red {
background-color: red;
}
.blue {
background-color: blue;
}
.green {
background-color: green;
}
<div class="flex1">
<div class="red height">
</div>
<div class="blue height">
</div>
</div>
<div>
<div class="green height">
</div>
</div>
<br><br>
<div class="grid">
<div class="red height" style="grid-area: a;">
</div>
<div class="blue height" style="grid-area: b;">
</div>
<div class="green height" style="grid-area: c;">
</div>
</div>