make the css grid cell take up all the remaining space - css

I have a 3 cells grid.
I want cells 1 and 3 to be the same size and cell 2 to fill all the remaining space.
like this:
| abcdefghi | ...........abcdefghijklmnopqrstuvwxyz........... | ......abc |
I tried grid-template-columns: 1fr auto 1fr Unfortunately, auto uses as little space as possible and I get something like this:
| abcdefghi........... | abcdefghijklmnopqrstuvwxyz | .................abc |
Is there a way to do this with css-grid?
.foo {
height: 100px;
display: grid;
grid-template-columns: 1fr auto 1fr;
resize: horizontal;
overflow: hidden;
text-align: center;
}
.foo div {
border: 1px solid blue;
}
.foo div:first-child {
text-align: left;
}
.foo div:last-child {
text-align: right;
}
<div class='foo'>
<div>abcdefghi</div>
<div>abcdefghijklmnopqrstuvwxyz</div>
<div>abc</div>
</div>

Related

CSS Grid layout with dynamic height

I need to create layout 2x2 blocks with min-width 500px and min-height 300px. (first img).
I can collapse blue block (by click on it) to height 100px and the block which is below must fill the gap and become bigger. The same behaviour if lower block collapsed, the upper will stretch. (second img)
if screen width > 1200, turn it into 4 columns with width:300px, height:600px (third img) enter image description here
I tried to do add for parent
width: 100%;
height: 100%;
display: grid;
grid-template-rows: minmax(300px, 1fr) minmax(300px, 1fr);
grid-template-columns: minmax(500px, 1fr) minmax(500px, 1fr);
grid-column-gap: 25px;
grid-row-gap: 25px;
}
and also added
#media (min-width: 1200px) {
.parent {
grid-template-rows: minmax(600px, 1fr);
grid-template-columns: repeat(4, minmax(300px, 1fr));
}
}
but I don't know how to implement collapsing
Try this. I use the columns property on the parent to make a 2 column layout with the children to be flex containers. This means that when the flex children are clicked, we can use flex-grow, flex-shrink and flex-basis to make the clicked one smaller and the unclicked one automatically grow.
For screen sizes greater than 1200px, I've used a media query to flip the flex container to flex-direction: row which makes your four columns. The only bit that's annoying is that the column layout, the middle section is wider than the other parts. You might be able to fix this with a bit of tweaking
window.onload = () => {
document.querySelector('.container').addEventListener('click', (e) => {
e.target.classList.toggle('shrink');
});
}
.container {
columns: 2;
padding: 0.5rem;
border: 3px solid black;
height: 600px;
}
.column {
display: flex;
flex-direction: column;
height: 100%;
}
[id^="b"] {
background-color: #00A8F3;
border: 3px solid black;
margin-bottom: 0.5rem;
display: grid;
place-items: center;
padding: 1rem;
flex-grow: 1;
flex-shrink: 1;
}
.shrink {
flex-basis: 100px;
flex-grow: 0;
}
#media screen and (min-width: 1200px) {
.column {
flex: 1;
flex-direction: row;
justify-content: space-evenly;
}
.container {
display: flex;
}
[id^="b"] {
flex-basis: 300px;
flex-grow: 0;
flex-shrink: 0;
}
}
<div class='container'>
<div class='column'>
<div id='b1'>1</div>
<div id='b2'>2</div>
</div>
<div class='column'>
<div id='b3'>3</div>
<div id='b4'>4</div>
</div>
</div>
You can try like below. I added a checkbox to simulate the switch between (1) and (2)
.container {
display: grid;
grid-template-columns: 1fr 1fr; /* 2 columns */
grid-auto-flow: dense;
gap: 20px;
border:1px solid;
height: 300px;
}
.container > div {
display: flex;
flex-direction: column;
gap: 20px;
}
.container > div > div {
flex-grow: 1; /* fill remaining height */
height: 100%; /* we start with equal div */
background: lightblue;
font-size: 20px;
}
#media (max-width: 1200px) {
/* update the height on toggle */
input:checked ~ .container > div:first-child > div:last-child,
input:checked ~ .container > div:last-child > div:first-child {
height: 80px;
}
}
#media (min-width: 1200px) {
.container {
grid-template-columns: 1fr 1fr 1fr 1fr; /* 4 columns */
}
.container > div {
display: contents; /* remove inner divs */
}
/* rectify the order */
.container > div:first-child > div:last-child {
grid-column: 3;
}
}
<input type="checkbox">
<div class="container">
<div>
<div> 1 </div>
<div> 3 </div>
</div>
<div>
<div> 2 </div>
<div> 4 </div>
</div>
</div>

How to expand a sibling element of a grid?

I have a list of cards that are displayed in a grid layout.
When I click in one of these cards, a div will appear, displaying the details.
This detail element should have a minimum of 300px and occupy all space but my cards should be displayed as much as possible occupying more than 1 per row if possible.
https://jsfiddle.net/3h1kx9Lz/
.parent {
width: 100%;
gap: 10px;
display:flex;
}
.container {
grid-template-columns: repeat(auto-fit, minmax(100px, 200px));
grid-auto-rows: min-content;
gap: 10px;
display: grid;
flex-grow: 1;
align-items: flex-start;
}
.card {
height: 30px;
background: red;
}
.detail {
min-width:300px;
flex-grow:1;
background: blue;
height: 200px;
}
Here it is
.parent {
width: 100%;
display:flex;
}
and removed the flex-grow from the ,card
https://jsfiddle.net/xbc2vdg9/

How to create a CSS grid with 3 images (2 on row 1, 1 on row 2) where the third image is centered [duplicate]

This question already has answers here:
How to center elements on the last row in CSS Grid?
(8 answers)
Closed 2 years ago.
I am trying to create a responsive grid. Desktop should be one row with three images all centered. On smaller screens (<720px) I need two images, and the third image to wrap down onto the next line. I've achieved that - but it wraps onto the next line on the left - I need it CENTERED. I assume this is because the way I achieve the 'wrap' was by telling it to create two columns (so it's 'reserved' space for row 2/column 2).
At the moment it looks like this:
I want it to look like this:
#media (min-width: 900px) {
#grid-container-clients {
padding-top: 30px;
margin: auto;
display: grid;
width: 900px;
height: 200px;
grid-gap: 1rem;
grid-template-columns: 1fr 1fr 1fr;
background-color: white;
text-align: center;
}
.grid-item-clients {
/*grid-rows:*/
position: relative;
text-align: center;
border: solid black 1px;
border-radius: 2px;
}
}
#media (max-width: 899px) {
#grid-container-clients {
padding-top: 30px;
margin: auto;
display: grid;
width: 400px;
height: 400px;
grid-gap: 1rem;
grid-template-columns: 1fr 1fr;
background-color: white;
text-align: center;
}
.grid-item-clients {
position: relative;
text-align: center;
border: solid black 1px;
border-radius: 2px;
}
}
<div id="grid-container-clients">
<div class="grid-item-clients"><img src="images/client.png" style="width:100%;"></div>
<div class="grid-item-clients"><img src="images/client.png" style="width:100%"></div>
<div class="grid-item-clients"><img src="images/client.png" style="width:100%"></div>
</div>
<!-- End "container-clients" -->
Here is a simplified answer using #Paulie_D's idea of a 6-column grid. Using grid-template-areas, we can explicitly place the grid items to occupy exactly as much space as we want in the grid. The dots represent empty slots in the grid. Because item3occupies columns 3 and 4 in the 6 column grid, it appears centered.
.container {
justify-content: center;
display: grid;
grid-gap: 1rem;
grid-template-areas: "item item1 item2 item2 item3 item3";
}
.item {
width: 200px;
height: 200px;
background-color: #ccc;
}
.item1 {
grid-area: item1;
}
.item2 {
grid-area: item2;
}
.item3 {
grid-area: item3;
}
#media screen and (max-width: 720px) {
.container {
grid-template-areas: ". item1 item1 item2 item2 ."
". . item3 item3 . .";
}
}
<div class="container">
<div class="item1 item"></div>
<div class="item2 item"></div>
<div class="item3 item"></div>
</div>
jsFiddle

CSS Grid - unexpected behavior of fr with grid gap

I'm trying to create a layout with CSS grid that looks like this (ie: a section on the left that has a fixed width and height, a section at the top which takes up the minimum height possible, and a section underneath that which takes up all the remaining space):
However, what I'm getting is this (where the space at the bottom of the orange section is equal to the grid-row-gap):
I'm wondering why the fr is being calculated like this instead of compensating for the grid gap?
(In my project I can fix this issue by adding a margin to the bottom right element instead of using grid-row-gap, but I'd like to know if there's something I'm misunderstanding about CSS grid)
span {
display: inline-block;
}
.grid {
border: 1px solid black;
display: inline-grid;
grid-template-columns: repeat(2, auto);
grid-template-rows: auto 1fr;
grid-row-gap: 1rem;
}
.left {
background: orange;
height: 120px;
width: 120px;
grid-row: 1/span 2;
}
.right-top {
background: yellow;
height: 20px;
width: 300px;
}
.right-bottom {
background: blue;
}
<div class="grid">
<span class="left"></span>
<span class="right-top"></span>
<span class="right-bottom"></span>
</div>

Overlapping grid items using grid-template-areas / named areas

I'm experimenting with CSS Grids, and this is the layout I'm building:
.grid {
display: grid;
align-items: center;
grid-template-columns: 1fr 4rem 1fr;
grid-template-rows: 1rem 1fr 1rem;
max-width: 900px;
margin: 0 auto;
}
.text {
/*
// Ideally, this should be
grid-area: text
*/
grid-column: 1 / 3;
grid-row: 2 / 3;
/* Fix z-index */
position: relative;
padding: 4rem;
background-color: #fff;
}
.image {
/*
// Ideally, this should be
grid-area: image;
*/
grid-column: 2 / 4;
grid-row: 1 / -1;
background-color: lightgray;
padding: 1rem;
/* Center das image */
display: flex;
justify-content: center;
}
/* Basic body */
body {
background-color: #fafafa;
font-family: sans-serif;
padding: 2rem;
}
img {
max-width: 100%;
height: auto;
}
<div class="grid">
<div class="text">One morning, when bobby woke from troubled dreams, he found himself transformed in his bed into a horrible vermin. He lay on his leg like back, and if he lifted his head a little he could see his brown belly, slightly domed and divided by arches into
stiff sections.
</div>
<div class="image">
<img src="http://unsplash.it/400/400" />
</div>
</div>
(best to preview in full page...)
What I'd like to avoid:
.text and .image both currently are using grid-column: * / *; syntax, instead I'd like to use grid-area: text and grid-area: image;.
Is it possible to define grid-template-{columns|rows} as overlapping areas? I tried using second way of defining grid areas
, but that didn't seem to work.
Looks like you can't do [a-start] [b-start] [a-end] [b-end] in that syntax, or at least I didn't manage to.
So - Is there any way to create an overlapping grid using named areas?
I'm trying to use the named areas for convenience purely - so that it's easier to reason about the responsive layout code, instead of repeating myself multiple times in media queries.
Edit
Found the answer because of #vals answer below.
This seemed to work just fine, I probably made a syntax error in my previous attempt somewhere:
grid-template-columns: [text-start] 1fr [image-start] 4rem [text-end] 1fr [image-end];
grid-template-rows: [image-start] 1rem [text-start] 1fr [text-end] 1rem [image-end];
At least in a more basic layout, it seems to work for me:
.container {
border: solid 1px green;
height: 180px;
width: 300px;
display: grid;
grid-template-columns: [left-start] 100px [right-start] 100px [left-end] 100px [right-end];
grid-template-rows: [left-start] 60px [right-start] 60px [left-end] 60px [right-end];
}
.left {
grid-area: left;
background-color: red;
}
.right {
grid-area: right;
background-color: lightgray;
opacity: 0.5;
}
<div class="container">
<div class="left">
</div>
<div class="right">
</div>
</div>

Resources