snu snu - 7 months ago 28
HTML Question

placing div in the middle of div with transform scale

I'm trying to place a div in the middle of another div (both horizontally and vertically) and scale it to a max while maintaining an aspect ratio.

It's working well if I do the scaling but keep it in top/left side but as soon as I'm trying to center it it all breaks.

#area is an external div, #cont is the main content div to be scaled. IRL it has a complex structure inside and not just one image like in the example below.

There are jsfiddle examples showing my attempts. To see what I mean please resize the result iframe.

Here is the scaling while keeping the div on left / top:
https://jsfiddle.net/regc/3t4n3xud/1/

CSS

#area {
top: 40px;
bottom: 40px;
left: 10px;
right: 10px;
display: block;
position: absolute;
border: 4px solid #73AD21;
}
#cont {
width: 500px;
height: 200px;
position: absolute;
border: 4px solid #aa2221;
}


JS:

cont_el.style['transform'] = 'scale(' + scale + ')';

cont_el.style['transform-origin'] = 'left top';

cont_el.style.width = i.width * scale;
cont_el.style.height = i.height * scale;


Here are my attempts to center it but it breaks:
https://jsfiddle.net/regc/4gcxcn7j/11/

CSS

#area {
top: 40px;
bottom: 40px;
left: 10px;
right: 10px;
display: block;
position: absolute;
border: 4px solid #73AD21;
}
#cont {
width: 500px;
height: 200px;
position: absolute;
border: 4px solid #aa2221;
margin: 0 auto;
top: 50%;
transform: translateY(-50%);
}


JS

cont_el.style['transform'] = 'scale(' + scale + ') translateY(-50%)';

cont_el.style['transform-origin'] = 'center center';

cont_el.style.width = i.width * scale;
cont_el.style.height = i.height * scale;

cont_el.style.margin = '0 auto';

cont_el.style.top = '50%';

Answer

I hope this is what you want !! use transform-origin:top left;

FIDDLE

scale_cont()
window.addEventListener('resize', scale_cont)

function scale_cont() {
  const o = getComputedStyle(document.getElementById('area'))
  const i = getComputedStyle(document.getElementById('cont'))

  const cont_el = document.getElementById('cont')

  const scale = Math.min(
    parseFloat(o.width) / parseFloat(i.width),
    parseFloat(o.height) / parseFloat(i.height));
  console.log('scale ', scale)

  /*
  	cont_el.style['-webkit-transform'] = 'scale(' + scale + ')';
  	cont_el.style['-moz-transform'] = 'scale(' + scale + ')';
  	cont_el.style['-o-transform'] = 'scale(' + scale + ')';
  	cont_el.style.transform = 'scale(' + scale + ')';
  */

  cont_el.style.transform = 'scale(' + scale + ') translate(-50%, -50%)';
  cont_el.style['-o-transform'] = 'scale(' + scale + ') translate(-50%, -50%)';
  cont_el.style['-webkit-transform'] = 'scale(' + scale + ') translate(-50%, -50%)';
  cont_el.style['-moz-transform'] = 'scale(' + scale + ') translateY(-50%, -50%)';


  cont_el.style['-webkit-transform-origin'] = 'top left';
  cont_el.style['-moz-transform-origin'] = 'top left';
  cont_el.style['-o-transform-origin'] = 'top left';
  cont_el.style['transform-origin'] = 'top left';

  cont_el.style.width = i.width * scale;
  cont_el.style.height = i.height * scale;



  cont_el.style.margin = '0 auto';

  cont_el.style.top = '50%';

  // cont_el.style.transform = 'translateY(-50%)';

}
#area {
  top: 40px;
  bottom: 40px;
  left: 10px;
  right: 10px;
  display: block;
  position: absolute;
  border: 4px solid #73AD21;
}
#cont {
  width: 500px;
  height: 200px;
  position: absolute;
  border: 4px solid #aa2221;
  margin: 0 auto;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  transform-origin: top left;
}
#cont img {
  width: 100%;
  height: 100%;
  max-width: 100%:
}
#all,
#main {
  height: 100%;
  width: 100%;
  margin: 0;
  padding: 0;
  top: 0;
  left: 0;
  position: absolute;
  display: block;
  overflow: none;
  box-sizing: inherit;
}
#header {
  width: 100%;
  height: 30px;
  position: relative;
  top: 0;
  left: 0;
  background: #a4f4f4;
}
#footer {
  width: 100%;
  height: 30px;
  position: fixed;
  bottom: 0;
  left: 0;
  background: #34f4f4;
}
<div id='all'>
  <div id='main'>
    <div id='header'>
      Header
    </div>
    <div id='area'>
      <div id='cont'>
        <img src='https://www.google.com.au/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png' />
      </div>
    </div>
    <div id='footer'>
      Footer
    </div>
  </div>
</div>