That's pretty funky.
A Theory:
When .cards-card-detail
elements have display:none
, their widths are undefined. The .data-set-label
elements have width:50%
but, with their parents' widths undefined, their widths get calculated in a strange way which causes inner text to wrap and heights to get thrown off.
Some Tests:
In the test below, the width of .data-set-label
is computed as "50 pixels", even though it's defined as "50%". But when .cards-card-detail
is display:block
, a more accurate width is returned.
$(function() {
console.log("display:none - " + $('.data-set-label').width());
$('.cards-card-detail').show()
console.log("display:block - " + $('.data-set-label').width());
});
* {
box-sizing: border-box;
}
.cards {
font-size: 0;
}
.cards-card {
font-size: 12pt;
display: inline-block;
width: 33%;
vertical-align: top;
border: 1px solid red;
}
.cards-card:nth-child(2n) {
width: 34%;
border: 1px solid green;
}
.cards-card-header {
height: 100px;
}
.cards-card-detail {
padding: 10px;
border-top: 1px solid red;
display: none;
}
.data-set-wrapper {
font-size: 0;
}
.data-set-label {
font-size: 12px;
border: 1px solid red;
width: 50%;
display: inline-block;
}
.data-set-data {
font-size: 12px;
border: 1px solid red;
width: 50%;
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div class="cards">
<div class="cards-card">
<div class="cards-card-header">
Here is some header information
</div>
<div class="cards-card-detail">
<div class="data-set-wrapper">
<label class="data-set-label">Label</label>
<div class="data-set-data">
some data
</div>
</div>
</div>
</div>
</div>
Setting the width of .data-set-label
explicitly to "50px" makes the text wrap and increases the height of .cards-card-detail
, seemingly to the same "wrong" height as in your example (coincidence?).
* {
box-sizing: border-box;
}
.cards {
font-size: 0;
}
.cards-card {
font-size: 12pt;
display: inline-block;
width: 33%;
vertical-align: top;
border: 1px solid red;
}
.cards-card:nth-child(2n) {
width: 34%;
border: 1px solid green;
}
.cards-card-header {
height: 100px;
}
.cards-card-detail {
padding: 10px;
border-top: 1px solid red;
}
.data-set-wrapper {
font-size: 0;
}
.data-set-label {
font-size: 12px;
border: 1px solid red;
width: 50px;
display: inline-block;
}
.data-set-data {
font-size: 12px;
border: 1px solid red;
width: 50px;
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div class="cards">
<div class="cards-card">
<div class="cards-card-header">
Here is some header information
</div>
<div class="cards-card-detail">
<div class="data-set-wrapper">
<label class="data-set-label">Label</label>
<div class="data-set-data">
some data
</div>
</div>
<div class="data-set-wrapper">
<label class="data-set-label">Label</label>
<div class="data-set-data">
some data
</div>
</div>
<div class="data-set-wrapper">
<label class="data-set-label">Label</label>
<div class="data-set-data">
some data
</div>
</div>
</div>
</div>
</div>
A Solution:
I had some success by defining the width of .cards-card-detail
at "100%" in the hopes that the childrens' "50%" width would then be set correctly.
$(function() {
$("#ShowDetailsCheckBox").change(function() {
if ($(this).is(":checked")) {
setContentDataHeights();
$(".cards-card-detail").slideDown();
} else {
$(".cards-card-detail").slideUp();
}
});
});
function setContentDataHeights() {
var maxContentDataHeight = 0;
$(".cards-card-detail").each(function() {
if ($(this).height() > maxContentDataHeight)
maxContentDataHeight = $(this).height();
});
if (maxContentDataHeight > 0) {
$(".cards-card-detail").height(maxContentDataHeight);
}
}
* {
box-sizing: border-box;
}
.cards {
font-size: 0;
}
.cards-card {
font-size: 12pt;
display: inline-block;
width: 33%;
vertical-align: top;
border: 1px solid red;
}
.cards-card:nth-child(2n) {
width: 34%;
border: 1px solid green;
}
.cards-card-header {
height: 100px;
}
.cards-card-detail {
padding: 10px;
border-top: 1px solid red;
display: none;
width: 100%;
}
.data-set-wrapper {
font-size: 0;
}
.data-set-label {
font-size: 12px;
border: 1px solid red;
width: 50%;
display: inline-block;
}
.data-set-data {
font-size: 12px;
border: 1px solid red;
width: 50%;
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<input type="checkbox" id="ShowDetailsCheckBox" />Show details
<div class="cards">
<div class="cards-card">
<div class="cards-card-header">
Here is some header information
</div>
<div class="cards-card-detail">
<div class="data-set-wrapper">
<label class="data-set-label">Label</label>
<div class="data-set-data">
some data
</div>
</div>
</div>
</div>
<div class="cards-card">
<div class="cards-card-header">
Here is some header information
</div>
<div class="cards-card-detail">
<div class="data-set-wrapper">
<label class="data-set-label">Label</label>
<div class="data-set-data">
some data
</div>
</div>
<div class="data-set-wrapper">
<label class="data-set-label">Label</label>
<div class="data-set-data">
some data
</div>
</div>
</div>
</div>
<div class="cards-card">
<div class="cards-card-header">
Here is some header information
</div>
<div class="cards-card-detail">
<div class="data-set-wrapper">
<label class="data-set-label">Label</label>
<div class="data-set-data">
some data
</div>
</div>
<div class="data-set-wrapper">
<label class="data-set-label">Label</label>
<div class="data-set-data">
some data
</div>
</div>
<div class="data-set-wrapper">
<label class="data-set-label">Label</label>
<div class="data-set-data">
some data
</div>
</div>
</div>
</div>
</div>
I'm curious about other explanations.
EDIT:
I see what you mean: the solution above doesn't work consistently.
Here's a alternative technique:
Set .cards
to opacity:0
until the heights of .card-card-detail
are set. Then reveal the cards.
$(document).ready(function() {
setContentDataHeights();
$('.cards-card-detail').hide();
$('.cards').addClass('show');
$("#ShowDetailsCheckBox").change(function() {
if ($(this).is(":checked")) {
$(".cards-card-detail").slideDown();
} else {
$(".cards-card-detail").slideUp();
}
});
});
function setContentDataHeights() {
var maxContentDataHeight = 0;
$(".cards-card-detail").each(function() {
if ($(this).height() > maxContentDataHeight)
maxContentDataHeight = $(this).height();
});
if (maxContentDataHeight > 0) {
$(".cards-card-detail").height(maxContentDataHeight);
}
}
* {
box-sizing: border-box;
}
.cards {
font-size: 0;
opacity: 0;
transition: opacity .25s;
}
.cards.show {
opacity: 1;
}
.cards-card {
font-size: 12pt;
display: inline-block;
width: 33%;
vertical-align: top;
border: 1px solid red;
}
.cards-card:nth-child(2n) {
width: 34%;
border: 1px solid green;
}
.cards-card-header {
height: 100px;
}
.cards-card-detail {
padding: 10px;
border-top: 1px solid red;
}
.data-set-wrapper {
font-size: 0;
}
.data-set-label {
font-size: 12px;
border: 1px solid red;
width: 50%;
display: inline-block;
vertical-align: top;
}
.data-set-data {
font-size: 12px;
border: 1px solid red;
width: 50%;
display: inline-block;
vertical-align: top;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="checkbox" id="ShowDetailsCheckBox" />Show details
<div class="cards">
<div class="cards-card">
<div class="cards-card-header">
Here is some header information
</div>
<div class="cards-card-detail">
<div class="data-set-wrapper">
<label class="data-set-label">label label label label label label </label>
<div class="data-set-data">
some data
</div>
</div>
<div class="data-set-wrapper">
<label class="data-set-label">Label</label>
<div class="data-set-data">
some data
</div>
</div>
<div class="data-set-wrapper">
<label class="data-set-label">Label</label>
<div class="data-set-data">
some data
</div>
</div>
</div>
</div>
<div class="cards-card">
<div class="cards-card-header">
Here is some header information
</div>
<div class="cards-card-detail">
<div class="data-set-wrapper">
<label class="data-set-label">label label label label label label label label label label </label>
<div class="data-set-data">
some data
</div>
</div>
<div class="data-set-wrapper">
<label class="data-set-label">Label</label>
<div class="data-set-data">
some data
</div>
</div>
</div>
</div>
<div class="cards-card">
<div class="cards-card-header">
Here is some header information
</div>
<div class="cards-card-detail">
<div class="data-set-wrapper">
<label class="data-set-label">Label</label>
<div class="data-set-data">
some data
</div>
</div>
</div>
</div>
</div>