Search code examples
csshtmlsvgviewbox

How to postion a Div in the flow after a scaled Svg (without JS)?


I want to position a DIV just after a dynamically scaled SVG. Unfortunately the DIV position doesn't change.

<svg style="transform:scale(x); transform-origin:0 0"></svg>
<div>Sould be just under the SVG whatever scale</div>

I've tried different techniques (position:relative, flex-direction:column, fit-content, ...) without success. I have to recalculate the DIV position after every scaling.

Is it possible to achieve this in CSS, whith no Javascript ?

Transform.onclick = function () {  
  scale = function ( ratio ) {
    S1.style.transform = 'scale(' + ratio + ')'
  
    //the calculation part I'd like to avoid
    var ty =  S1.height.baseVal.value * ( ratio - 1 ) 
    DivIn.style.transform = 'translateY(' + ty + 'px)'
  }
  
  toggle( this )
}

Dims.onclick = function () {  
  var H = S1.height.baseVal.value
  var W = S1.width.baseVal.value

  scale = function ( ratio ) {
    S1.setAttribute( "height", H * ratio )
    S1.setAttribute( "width", W * ratio )
  }
  
  toggle( this )
}

Symb.onclick = function () {     
  scale = function ( ratio ) {
    S1.style.fontSize = ratio + "em"
  }
  
  toggle( this )
}

Transform.click()

function toggle ( button ) {
  Array.from( document.querySelectorAll( 'button' ) )
  .forEach( b => b.style.fontWeight = button==b ? 700:500 )
} 
svg {
  transform-origin: 0 0;
}
div#DivOut {
  position: relative;
}
div#Container {
  position: flex;
  flex-direction: column;
  height: fit-content;
  border: 1px solid blue;
}
<input type=number value=1 oninput="scale(this.value)">
<button id=Transform>1: Transform</button> 
<button id=Dims>2: Relative Height</button> 
<button id=Symb>3: Symbol</button> 

<div id=Container>
  <svg width=50 height=50 id=S1>
    <use xlink:href="#SY"></use>
    <symbol id=SY>
      <rect x=0 y=0 width=100% height=100% fill=red />
    </symbol>
  </svg>
  <div id=DivIn>Next line test 1</div>
</div>
<div id=DivOut>Next line test 2</div>


Solution

  • The best solution I found is to set a viewBox attribute to the <svg> element.

    Then you can resize it by just changing the width and height via CSS style.

    function resize()
    {
        SVG1.classList.toggle( 'double' )
    }
    .double {
       width: 200px ;
       height: 200px ;
    }
    <svg id=SVG1 viewBox="0 0 100 100"  width=100 height=100>  
       <rect x=0 y=0 width=100 height=100 fill=red />
    </svg>
    <div>
      <button onclick="resize()">Resize</button>
    </div>