84

I have a small issue I want to fix, but can't find any good answer :

When I use a scale on a div (which contains other divs), it leave white space around, from the "original" width and height of my div :

enter image description here

How can I remove the withe space around the div while scaled ?

I can use js if needed !

EDIT: Here is some code :

HTML

<div class="pull-right nextpack">

                    <div class="quarter scale-thumb">

                        <div class="up">
                            <div class="inner" style="background-image: url({{URL::base().'/galery/th293x711/'.$nextpack->src}})"></div>
                        </div>

                        <div class="face">
                            <div class="top" style="background-image: url({{URL::base().'/galery/th293x711/'.$nextpack->src}})"></div>
                            <div class="bot" style="background-image: url({{URL::base().'/galery/th293x711/'.$nextpack->src}})"></div>
                        </div>

                        <div class="cote-droit">
                            <div class="inner">
                                <div class="cote-droit-top" style="background-image: url({{URL::base().'/galery/th293x711/'.$nextpack->src}})"></div>
                                <div class="cote-droit-bot" style="background-image: url({{URL::base().'/galery/th293x711/'.$nextpack->src}})"></div>
                            </div>
                        </div>

                    </div>


                </div>

CSS (you really don't need to know how the pack is done, it's a lot of css3 for nothing, basically just skew, rotate, scale to make a 3D render from a flat template)

.quarter.scale-thumb
{
-webkit-transform: scale(0.2);
-moz-transform: scale(0.2);
-o-transform: scale(0.2);
transform: scale(0.2);
}

PS : The first pic is when I don't add the scale-thumb class

Pretty Good Pancake
  • 1,423
  • 3
  • 12
  • 28
  • Show some relevant code. Question is impossible to answer from a screenshot. – Dirk McQuickly May 05 '13 at 15:05
  • 1
    Is this more clear? The code is no big deal, it's really the scale and the white space around it that keeps me stuck :) – Pretty Good Pancake May 05 '13 at 15:11
  • You could put it all inside another div which has `overflow:hidden`, then resize that div. – Dave May 05 '13 at 15:12
  • When I add this : .nextpack { overflow: hidden; display: block; -webkit-transform: scale(0.2); -moz-transform: scale(0.2); -o-transform: scale(0.2); transform: scale(0.2); } I still have white space around... – Pretty Good Pancake May 05 '13 at 15:21
  • 1
    Adjust the `transform-origin` property, which centers a scaled box vertically and horizontally, by default. https://stackoverflow.com/q/43020800/3597276 – Michael Benjamin Jun 14 '17 at 17:04

13 Answers13

42

how transform works is:

  1. your element gets rendered
  2. your element gets transformed (moved, rotated, scaled)
  3. other elements stay where they got rendered - around the "original element"

so the white space is really just the way the element was rendered in the first place.

You should use width and height in CSS if you want to render the size of elements differently and have the surrounding elements respond to it.

Or you could use something like javascript to resize things.

Martin Turjak
  • 20,896
  • 5
  • 56
  • 76
  • 7
    Well, I can't do it with width and height because the elements I want to resize are not in percentage, and it's really complicated to make it so. How would you do it in js ? – Pretty Good Pancake May 05 '13 at 15:54
35

solution is to wrap the element inside a container, and resize it too while the scale() is done

Jsfiddle demo: http://jsfiddle.net/2KxSJ/

relevant code is:

#wrap
{
    background:yellow;
    height:66px;
    width:55px;
    padding:10px;
    float:left;
    -webkit-transition:0.5s all;
    -moz-transition:0.5s all;
    /* more transition here */
}

#wrap:hover
{
    height:300px;
    width:260px;
}

.quarter
{
    padding:20px;
    -webkit-transform: scale(0.2);
    -moz-transform: scale(0.2);
    -o-transform: scale(0.2);
    transform: scale(0.2);
    background:red;
    width:250px;
    -webkit-transform-origin:left top;
    -webkit-transition:0.5s all;
    -moz-transition:0.5s all;
    /* more transition here */
}


#wrap:hover .quarter
{
    -webkit-transform: scale(0.9);
    -moz-transform: scale(0.9);
    -o-transform: scale(0.9);
    transform: scale(0.9);
    -webkit-transform-origin:left top;
    -moz-transform-origin:left top;
    /* more transform-origin */
}
  • 2
    his fiddle has dead links, here's an updated fork: http://jsfiddle.net/2KxSJ/243/ – The Onin Jan 04 '18 at 00:55
  • This answer and fiddle are full of extra code. The key point is that the document flow will shift when animating the `height` and `width` of the wrapping element. – koktavy Nov 10 '21 at 20:56
  • 1
    For future readers - the container is specifying the exact width/height for both states. There's nothing special going on here. – bendytree Dec 29 '22 at 15:01
5

I encountered this problem and I solved it in this way, I used SCSS in order to don't repeat the same numbers along the code. The below code just moves the element right as the zoom decreases, in order to re-align it.

$originalWidth: 100px;
$rate: 0.5;

parent {
  width: $originalWidth;
}

parent > div {
  transform: scale(1);
}

parent:hover {
  width: $originalWidth*$rate;
}

parent:hover > div {
  transform: translateX(($originalWidth * ($rate - 1))/2) scale($rate); /* the order matters*/
}

You can get rid of SCSS just using CSS variables and calc(), if you prefer.

5

I resolved my problem like yours that way.

I have a main container and I want decrease it

my css: .grid-container.full { transform: scale(0.6); transform-origin: top center; }

but my container had the bigger margin bottom. then I do it:

$mainGrid = $('.grid-container.full') $mainGrid.css('height', $mainGrid.height() * .6);

Pablo Papalardo
  • 1,224
  • 11
  • 9
  • 1
    the `transform-origin: top center` option was the thing I was missing - my parent container was huge, and it decided to transform from the bottom up - so it created a ton of "white space". – Brian Powell Jul 03 '19 at 20:03
4

Solved the issue with margin-bottom (it will be negative in case of scaling down):

#container {
  display: inline-block;
  border: 3px solid blue;
}

#content {
  --scale: 0.5;

  width: 200px;
  height: 200px;
  background: lightgreen;
  transform: scale(var(--scale));
  transform-origin: top left;
  margin-bottom: calc((var(--scale) - 1) * 100%);
}
<div id="container">
  <div id="content"></div>
</div>
Vitaliy Ulantikov
  • 10,157
  • 3
  • 61
  • 54
2

Another idea for white spaces when you transform objects

<div class="outer">
    <div class="inner">
        transformme
    </div>
</div>

css

.outer { overflow:hidden }
.inner {
    transform-origin:left top;
}

js

var rate = 0.5;
var outerheight = $('.inner').outerHeight()*rate;
$('.inner').css({ transform: "scale("+rate+")" });
$('.outer').css({ height: outerheight });

Also you can add other browser tags; -webkit-transform, -moz-transform, -o-transform

Alper AKPINAR
  • 71
  • 3
  • 10
2

it's simple you have to calculate with height, If for some reason you turn it upside down! like here your current width: 500px; and height: 220px; you want to reverse it like width: 220px; height: 500px; then again you have to use margin-bottom: calc((0.6 - 1) * 500px); that's it.

#parent {
  display: inline-block;
  outline: 5px solid black;
}

#child {
  width: 500px;
  height: 220px;
  background: #555; 
  transform: scale(0.6);
  transform-origin: top center;
  margin-bottom: calc((0.6 - 1) * 220px);
}
<div id="parent">
  <div id="child"> </div>
</div>
kyun
  • 9,710
  • 9
  • 31
  • 66
Sagar Roy
  • 316
  • 1
  • 6
1

I have a simple solution: You could put it all inside another div which has height:0px;.

Biet Khong
  • 21
  • 4
0

try multiplying both width and height of image using decimal numbers. Like this -> (I used SCSS)

img{
 width : 100px * 0.5;  // width reduced to half
 height : 100px * 0.5; // height reduced to half
}

I hope this helps in 2021 !

JoyShaheb
  • 129
  • 1
  • 7
  • This will only cause an error in the CSS for the element it won't without using the `calc` function – a.mola Mar 16 '21 at 02:10
0

I had the task to place drop-down into the site menu scaled to 0.5 top right with width: 500px. I resolved it: wrap drop-down into tag div, then apply next CSS code the wrapper:

div.scale_wrapper{
    position: relative;
    top: 34px;
    margin-right: calc(500px * -0.5);
}

Play with 34px for your current purposes. -0.5 is scale

Demo link with drop-down in the top site menu: https://demo.currency-switcher.com/

realmag777
  • 2,050
  • 1
  • 24
  • 22
0

If you do not need Firefox compatibility you could use {zoom:0.2} instead of {transform: scale(0.2);}

ESP32
  • 8,089
  • 2
  • 40
  • 61
0

I have solved the problem by positioning my elements in position absolute.Like this, you have full control of the space by playing with the margins and place your elements where you want them.

#element {position: absolute; scale: 0.7;}

Hutch
  • 21
  • 3
-2

I solved this with by adding an 'outline: 1px solid transparent' to the element where the scale is applied on.

#wrap:hover .quarter
{
   -webkit-transform: scale(0.9);
   -moz-transform: scale(0.9);
   -o-transform: scale(0.9);
   transform: scale(0.9);
   -webkit-transform-origin:left top;
   -moz-transform-origin:left top;

   outline: 1px solid transparent;
}
Ubby
  • 119
  • 2
  • I have no idea why, but this actually works amazingly in all browsers! How did you get to this? – italo.nascimento Sep 26 '17 at 14:17
  • Doesn't work, and if it did, it would be nice to know why. – The Onin Jan 04 '18 at 00:53
  • I removed the outline:1px solid transparent and it still works for me. All I needed was the origin statements. Beforehand the -transform was scaling all the whitespace and centering the shrunken image so this answer helped me – weekapaug Apr 29 '18 at 18:07
  • This works, just tested and works in JavaScript also - just set the element style: `.transformOrigin='left top';` .. after this just re-size the element's parent/wrapper by using `.getBoundingClientRect().width` .. (or height) respectively. –  Oct 17 '18 at 14:05