I'm using css3 scale transform to scale a div that contains other divs inside.
The problem I have is that some of the inner divs I need to keep as they were, basically as if they were not scaled, their size should not change, however I do need to scale the parent div with everything else inside.
How can you reverse the scaling in some of the divs?
I am trying to apply an inverse scaling.
If the overall div had applied a value of 1.5 , I'm trying to find what value I should now scale the other divs to revert them visually to how they looked before.
If the parent div has been scaled by a factor of 1.5
, then you need to scale the children by a factor of 1/1.5 = 0.(6)
to keep their size constant.
example
In general, in order to cancel for a child element a scale transform that has been applied on the parent and has a scale factor of a
, you need to apply another scale transform of factor 1/a
on the child itself.
You either need to:
- compute manually the scale factor before you do anything else and then use it as it is in your code (example linked above)
- use a preprocessor to handle this for you (SASS example)
- use JavaScript to compute the scale factor needed for the child and
to set the scale
transform
on the child
The inverse of any scale operation is 1 / <scale>
so by scaling the container by 1.5
you would need to scale the children by 1 / 1.5 = 0.6
Unfortunately, according to the specification you cannot just use CSS like:
transform: scale(1/1.5);
since scale is defined as scale(<number>[, <number>])
where <number>
is
either an or zero or more decimal digits followed by a dot (.) followed by one or more decimal digits
So you'll have to do the calculation yourself or could use a dynamic stylesheet language like LESS which supports these sort of operations.
Demo (webkit only)
If you, as suggested, use the inverted the scale factor, then note that the child does not necessarily keep its original size during the scale transformation -- this matters of course only if you let the scale transforms have a duration (e.g. by using transition: transform;
).
You could use a CSS variable to store your scale factor, and then use calc()
to calculate the inverse scale for the child elements that have a certain class:
.wrapper {
transform: scale(var(--scale));
background: #ddd;
}
.wrapper > * {
text-align: center;
}
.wrapper > .revertscale {
transform: scale(calc(1/var(--scale)));
}
<div class="wrapper" style="--scale: 0.8">
<h2>scaled title</h2>
<p>scaled description</p>
</div>
<div class="wrapper" style="--scale: 0.8">
<h2 class="revertscale">not scaled title</h2>
<p class="revertscale">not scaled description</p>
</div>
⋅
⋅
⋅
In case you don't want any of the child elements to scale, another way of doing it would be to style your wrapper as a pseudo element :
.wrapper {
position: relative;
}
.wrapper > * {
text-align: center;
}
.wrapper::before {
content: "";
z-index: -1;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
transform: scale(var(--scale));
background: #ddd;
}
<div class="wrapper" style="--scale: 1">
<h2>title</h2>
<p>description</p>
</div>
<div class="wrapper" style="--scale: 1.2">
<h2>title</h2>
<p>description</p>
</div>
<div class="wrapper" style="--scale: 0.8">
<h2>title</h2>
<p>description</p>
</div>