Reputation: 829
I'm trying to scale down a div (divB) that's inside of another div (divA). The problem is that divA's height is specified by its contents. When divB gets scaled down, the height of divA doesn't change... This happens when a transform is applied because it doesn't actually change the pixel count, it changes the size of the pixels themselves (at least I'm pretty sure that's what's happening). So the easy fix is to manually set the height of divA to be the size of divB multiplied by the scale factor.
However, if I do this, I need to reset the height manually every time the contents of divA change. In my case, this is very cumbersome as there will be a ton of changes to divA's contents. So, I'm wondering if there is a simpler way to do this, preferably using CSS.
Here is a simple JSFiddle to demonstrate the problem: http://jsfiddle.net/turtlewaxer1100/82cux/8/
Just add some elements, scale down, and you'll see what I mean about the height not adjusting. If you click "Fix Height" then it'll adjust the height properly, but then if you add more elements the height doesn't adjust unless you fix it again...
html
<div>
<div class="wrapper">
<div id="scalar"></div>
</div>
<div class="buttons">
<div id="button">
<input type="button" value="Add" />
</div>
<div id="scaleDown">
<input type="button" value="Scale Down" />
</div>
<div id="scaleUp">
<input type="button" value="Scale Up" />
</div>
<div id="fixHeight">
<input type="button" value="Fix Height" />
</div>
</div>
</div>
css
.wrapper {
float:right;
width: 200px;
background-color: black;
}
.section {
margin-left:75px;
height: 50px;
width: 50px;
background-color: red;
}
.buttons {
float:left;
}
.scaleDown {
-webkit-transform: scale(0.75);
-moz-transform: scale(0.75);
-ms-transform: scale(0.75);
transform: scale(0.75);
-webkit-transform-origin: 50% 0 0;
-moz-transform-origin: 50% 0 0;
-ms-transform-origin: 50% 0 0;
transform-origin: 50% 0 0;
}
jquery
var section = $("<div class='section'></div>")
$(document).ready(function () {
$("#button").children().click(function () {
$("#scalar").append(section.clone(false));
});
$("#scaleDown").children().click(function () {
$("#scalar").addClass("scaleDown");
});
$("#scaleUp").children().click(function () {
$("#scalar").removeClass("scaleDown");
});
$("#fixHeight").children().click(function () {
$(".wrapper").height($("#scalar").height()*.75)
});
});
Upvotes: 0
Views: 6822
Reputation: 829
So I couldn't find an answer using just CSS, but I did find a fairly simple javascript solution. There is a DOM event called "DOMSubtreeModified", which will fire every time any element within the current element's hierarchy is changed. So, what I did is test whether the height of the element is different from the previous height each time this event is fired. If it is different, then set it accordingly. This way you can catch all dynamic height changes without any regard to what specifically changed the height.
Here is a fiddle to demonstrate the idea: http://jsfiddle.net/turtlewaxer1100/E6D2H/5/
HTML
<div class="wrapper">
<div id="scalar"></div>
</div>
<div class="buttons">
<div id="button">
<input type="button" value="Add" />
</div>
</div>
CSS
.wrapper {
float:right;
width: 200px;
background-color: black;
}
.section {
margin-left:75px;
height: 50px;
width: 50px;
background-color: red;
}
.buttons {
float:left;
}
#scalar
{
-webkit-transform: scale(0.75);
-moz-transform: scale(0.75);
-ms-transform: scale(0.75);
transform: scale(0.75);
-webkit-transform-origin: 50% 0 0;
-moz-transform-origin: 50% 0 0;
-ms-transform-origin: 50% 0 0;
transform-origin: 50% 0 0;
}
JS
var section = $("<div class='section'></div>")
var scaleFactor = 0.75;
var originalHeight = 0;
$(document).ready(function () {
$("#button").children().click(function () {
$("#scalar").append(section.clone(false));
});
$(".wrapper").bind('DOMSubtreeModified', function() {
var height, heightOffset;
height = $("#scalar").height();
if (height && originalHeight !== height) {
heightOffset = height * scaleFactor;
$(this).height(heightOffset);
return originalHeight = height;
}
});
});
Upvotes: 2