Search code examples
csssvgresponsive

Can responsive SVG reposition element without scaling them?


Giving this simple SVG :

svg {
  background-color: lightblue;
}
<p>Normal size :</p>
<svg viewBox="0 0 60 40" width="60" height="40" xmlns="http://www.w3.org/2000/svg">
  <circle cx="10" cy="10" r="5"/>
  <circle cx="30" cy="10" r="5"/>
  <circle cx="50" cy="10" r="5"/>
  <circle cx="10" cy="30" r="5"/>
  <circle cx="30" cy="30" r="5"/>
  <circle cx="50" cy="30" r="5"/>
</svg>

What I want to do, and I'm not sure SVG can do it, is that if with css I make my svg 3 times larger (60px => 180px), it will take the whole space BUT not doing a simple scale/zoom like effet tha happens when preserving aspect ratio. I need to keep my circles with 5px radius, and just increasing the space between them.

To go from this enter image description here to this enter image description here


Solution

  • As commented by @ccprog: the primitives <rect>, <circle>, <ellipse> and <line> support percentage values.

    Apply padding to the parent svg to set fixed x an y offsets (eg. 10px/svg user units).

    * {
      box-sizing: border-box;
    }
    
    .resize {
      resize: both;
      overflow: auto;
      padding: 1em;
      border: 1px solid #ccc;
    }
    
    svg {
      background-color: lightblue;
      padding: 0 10px;
      overflow: visible;
    }
    
    .svg2 {
      padding: 10px;
    }
    <p>resize me :</p>
    <div class="resize">
      <svg id="svg" width="100%" height="40" xmlns="http://www.w3.org/2000/svg">
        <circle cx="0" cy="10" r="5" />
        <circle cx="0" cy="30" r="5" />
    
        <circle cx="50%" cy="10" r="5" />
        <circle cx="50%" cy="30" r="5" />
    
        <circle cx="100%" cy="10" r="5" />
        <circle cx="100%" cy="30" r="5" />
      </svg>
    
    </div>
    
    <div class="resize">
      <svg class="svg2" width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
        <!-- align path center to x/y =0 by adding viewBox offset width/2 height/2 -->
        <symbol class="icon icon-home" id="iconHome" viewBox="20 20 40 40" overflow="visible">
            <path d="M36.4 22.2l-5.2 0l0 13l-3.4 0l0-16.7l-7.7-8.7l-7.7 8.7l0 16.7l-3.4 0l0-13l-5.2 0l16.4-17.4z"></path>
         </symbol>
    
        <use x="0" y="0%"  href="#iconHome" width="20" height="20" />
        <use x="0" y="100%" href="#iconHome" width="20" height="20" />
        
        <use x="50%" y="0%"  href="#iconHome" width="20" height="20" />
        <use x="50%" y="100%" href="#iconHome" width="20" height="20" />
        
        <use x="100%" y="0%"  href="#iconHome" width="20" height="20" />
        <use x="100%" y="100%" href="#iconHome" width="20" height="20" />
      </svg>
    </div>

    You can also apply percentage values for <path> elements by wrapping paths in a <symbol> element (2nd example).