I'm working on a responsive CSS grid with 1 to 4 columns depending on viewport size and any number of rows. The content of each grid box (a Material-style card) expands on-click to show more data. Everything works perfectly when there is only 1 column (phone sized screens) but as soon as it expands to multiple columns I'm starting to see an issue that I don't quite understand yet.
When I click one card to expand the data, every other card in the same row expands to fill the entire row height. That just looks bad and isn't the intended card behavior. What I'd rather have is for the cards NOT being clicked to remain their original size while only the clicked card gets expanded.
I first tried implementing this with display: flex
but I couldn't get the behavior I wanted. I am open to a flex solution if there is one.
Below is the relevant HTML, CSS and jQuery. The full example can also be found on CodePen: https://codepen.io/davewiard/pen/eydPoj.
var $cell = $(".card");
//open and close card when clicked on card
$cell.find(".js-expander").click(function() {
var $thisCell = $(this).closest(".card");
if ($thisCell.hasClass("is-collapsed")) {
$cell
.not($thisCell)
.removeClass("is-expanded")
.addClass("is-collapsed")
.addClass("is-inactive");
$thisCell.removeClass("is-collapsed").addClass("is-expanded");
if ($cell.not($thisCell).hasClass("is-inactive")) {
//do nothing
} else {
$cell.not($thisCell).addClass("is-inactive");
}
} else {
$thisCell.removeClass("is-expanded").addClass("is-collapsed");
$cell.not($thisCell).removeClass("is-inactive");
}
});
//close card when click on cross
$cell.find(".js-collapser").click(function() {
var $thisCell = $(this).closest(".card");
$thisCell.removeClass("is-expanded").addClass("is-collapsed");
$cell.not($thisCell).removeClass("is-inactive");
});
/*
* site-wide styling
*/
* {
box-sizing: border-box;
}
/*
* header styling
*/
#title {
font-family: "Expletus Sans", "Roboto", sans-serif;
text-transform: uppercase;
}
/*
* content styling
*/
hr {
border: 0.5px solid green;
margin: 10px 0;
}
/*
* upper card styling
*/
.container {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: fit-content;
}
@media screen and (min-width: 700px) {
.container {
grid-template-columns: repeat(2, 1fr);
}
}
@media screen and (min-width: 1050px) {
.container {
grid-template-columns: repeat(3, 1fr);
}
}
@media screen and (min-width: 1400px) {
.container {
grid-template-columns: repeat(4, 1fr);
}
}
.card {
background-color: #e0e0e0;
max-width: 100%;
min-width: 300px;
margin: 10px;
padding: 16px;
border-radius: 5px;
color: #212121;
}
/*
* lower/expanding card styling
*/
.card.is-collapsed .card--expander {
max-height: 0;
min-height: 0;
overflow: hidden;
margin-top: 0;
opacity: 0;
}
.name {
grid-column: 1 / span 2;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="card [ is-collapsed ]">
<div class="card--upper [ js-expander ]"><div class="symbol">Title</div></div>
<div class="card--expander [ js-collapser ]">
<hr />
<div class="card--expander--info--container"><span class="name">Name</span></div>
</div>
</div>
<div class="card [ is-collapsed ]">
<div class="card--upper [ js-expander ]"><div class="symbol">Title</div></div>
<div class="card--expander [ js-collapser ]">
<hr />
<div class="card--expander--info--container"><span class="name">Name</span></div>
</div>
</div>
<div class="card [ is-collapsed ]">
<div class="card--upper [ js-expander ]"><div class="symbol">Title</div></div>
<div class="card--expander [ js-collapser ]">
<hr />
<div class="card--expander--info--container"><span class="name">Name</span></div>
</div>
</div>
<div class="card [ is-collapsed ]">
<div class="card--upper [ js-expander ]"><div class="symbol">Title</div></div>
<div class="card--expander [ js-collapser ]">
<hr />
<div class="card--expander--info--container"><span class="name">Name</span></div>
</div>
</div>
<div class="card [ is-collapsed ]">
<div class="card--upper [ js-expander ]"><div class="symbol">Title</div></div>
<div class="card--expander [ js-collapser ]">
<hr />
<div class="card--expander--info--container"><span class="name">Name</span></div>
</div>
</div>
</div>