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/
Related
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>
This question already has answers here:
How to make an element width: 100% minus padding?
(15 answers)
How wide is the default `<body>` margin?
(4 answers)
Closed 8 months ago.
I want to divide body into 2 parts without any padding or gap.
But when I divide body by grid.
It shows me some gap even if I set grid-gap as 0.
It should show left as whole blue and right as whole white.
How to remove those gaps?
body {
width: 100%;
height: 100vh;
background-color: #5FAAD9;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-column-gap: 0;
gap: 0;
}
#Record {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
padding: 20px;
}
#List {
width: 100%;
height: 100vh;
background-color: white;
}
You have 20px padding on the left item but not on the right item.
The padding is not being counted in the height of the left item because the default setting for box-sizing will be being used.
You can make that padding be included in the dimensions of the item by setting box-sizing: border-box;
This snippet also sets the margins of all elements to 0 initially so as to remove the small (normally 8px) margins around the body.
* {
margin: 0;
}
body {
width: 100%;
height: 100vh;
background-color: #5FAAD9;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-column-gap: 0;
gap: 0;
}
#Record {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
padding: 20px;
box-sizing: border-box;
}
#List {
width: 100%;
height: 100vh;
background-color: white;
}
<body>
<div id="Record"></div>
<div id="List"></div>
</body>
I have a column of a defined size (let's say 50px), then an undetermined number of columns that should divide the available space among themselves, and finally another 50px column.
I know this could be achieved if I knew the total number of columns beforehand:
body > div {
grid-template-columns: 50px repeat(3, 1fr) 50px;
display: grid; grid-gap: 1rem; background: beige; width: 80%; padding: 1rem;
}
div div { background: IndianRed; min-height: 5rem;}
<div><div></div><div></div><div></div><div></div><div></div></div>
I also know I can do a fixed sized column + n columns this way:
body > div {
grid-template-columns: 50px repeat(auto-fit, minmax(1px, 1fr));
display: grid; grid-gap: 1rem; background: beige; width: 80%; padding: 1rem;
}
div div { background: IndianRed; min-height: 5rem;}
<div><div></div><div></div><div></div><div></div><div></div></div>
But the specific case doesn't work as it could this way. Instead, I'm left with an empty column at the end:
body > div {
grid-template-columns: 50px repeat(auto-fit, minmax(1px, 1fr)) 50px;
display: grid; grid-gap: 1rem; background: beige; width: 80%; padding: 1rem;
}
div div { background: IndianRed; min-height: 5rem;}
<div><div></div><div></div><div></div><div></div><div></div></div>
Is the thing I'm trying to do achievable with grid?
Remove the last column from the grid template. The column template would now look like this:
grid-template-columns: 50px repeat(auto-fit, minmax(1px, 1fr));
Then add this:
div div:last-child {
grid-column: -1;
width: 50px;
}
That should work!
<div class="container">
<div class="wrapper">
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
</div>
</div>
.circle {
width: 100px;
height: 100px;
border-radius: 50%;
background: red;
}
.wrapper {
display: grid;
grid-template-columns: 1fr;
justify-items: center;
align-items: space-around;
min-width: 300px;
height: 70vh;
background: whitesmoke;
}
#media screen and (min-width: 1100px) {
.container {
height: auto;
display: grid;
grid-template-columns: 1fr repeat(2, minmax(auto, 30rem)) 1fr;
background: pink;
}
.wrapper {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-column: 2/4;
justify-content: center;
background: cyan;
}
}
I've created a column that contains three circles in it, each stacked on top of the other in a column, which all looks fine when the screen is narrow. But when the browser is widened and I add a media query for when the screen gets wider than 1100px, I want the column of circles to flip to become a single row of circles.
But when I do this using CSS Grid, it doesn't work, and two circles appear on one row, and the third circle appears below the first circle on a second row. You can see it at https://codepen.io/HorrieGrump/pen/ZEKxJgv
I can get it to work if I use flexbox instead (as shown below) by swapping out the current .wrapper block in CSS and using this new one with flexbox, but I'd like to know if it's possible to use CSS Grid instead of flexbox to do this.
Can someone please let me know how to get the media query to flip the column into a single row using CSS Grid – and not have to resort to flexbox?
.wrapper {
display: flex;
flex-direction: row;
grid-template-columns: repeat(2,1fr);
justify-content: space-around;
align-items: center;
grid-column: 2/4;
background: cyan;
}
Edit your media query for .wrapper
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
align-items: center;
grid-column: 2/4;
background: cyan;
}
At first this looks like a standard 3-column layout, but the way the auxiliary columns wrap isn't common and doesn't seem to fit flexbox's wrapping model, either in forward or reverse mode. Perhaps grid is a better solution than flexbox? I'd like to avoid media queries if possible, but of course a working solution is better than none.
Design constraints
When there is enough space (1200px), all columns display adjacent with fixed widths.
When there is only enough room for MAIN and AUX1 (1000px), AUX2 wraps beneath and fills the width.
When there is only enough room for MAIN (800px), both auxiliary columns wrap beneath and sit adjacent to each other at 50% width.
As the screen continues to shrink, the layout remains the same as per 800px, but all columns shrink proportionally without overflowing the screen bounds.
None of the three content areas can overlap or intersect.
Here I created this just for you :).
EDIT: Here is a new way of doing it with a grid which will form to the content added to the divs. Please let me know if this works.
.contain {
width: 100%;
height: 100%;
text-align: center;
}
.wrap{
display: inline-flex;
}
.aux2{
background-color: orange;
width: 200px;
display: inline-flex;
}
.main{
background-color: blue;
width: 800px;
display: inline-flex;
}
.aux1{
background-color: green;
width: 200px;
display: inline-flex;
}
#media (max-width: 1200px){
.wrap{
display: grid;
justify-items: center;
grid-template-areas: auto auto;
grid-template-rows: auto auto;
}
.aux2{
background-color: orange;
width: 100%;
display: inline-flex;
grid-row: 2;
grid-column: 1 / span 2;
}
.main{
background-color: blue;
width: 800px;
display: inline-flex;
grid-row: 1;
}
.aux1{
background-color: green;
width: 200px;
display: inline-flex;
grid-row: 1;
}
}
#media (max-width: 1000px){
.wrap{
display: grid;
grid-template-areas: auto auto;
grid-template-rows: auto auto;
}
.aux2{
background-color: orange;
width: 100%;
display: inline-flex;
grid-row: 2;
grid-column: 1;
}
.main{
background-color: blue;
width: 100%;
display: inline-flex;
grid-row: 1;
grid-column: 1 /span 2;
}
.aux1{
background-color: green;
width: 100%;
display: inline-flex;
grid-row: 2;
grid-column: 2;
}
}
<div class="contain">
<div class="wrap">
<div class="aux2">aux2</div>
<div class="main">main</div>
<div class="aux1">aux1</div>
</div>
</div>