Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fixed svg in the bottom of a nested svg

Tags:

svg

d3.js

I have nested SVG in this form where the parent SVG can change its width and height:

<svg id="parent">
    <svg id="noPreserveRatio"></svg>
    <svg id="fixed"></svg>
</svg>

I would like the SVG with id="fixed" to always have the same height (say 100px) and width=100% relative to the parent SVG. And I would like the SVG with id="noPreserveRatio" to completely fill the parent container. I've tried different ways using the viewbox and preserve aspect ratio but could not achieve desired results. It would be really nice if my nested and parent SVGs had the same coordinate system so I could easily calculate the location of children SVGs.

like image 253
katya Avatar asked Sep 20 '25 21:09

katya


1 Answers

Not all of your requirements can be fullfilled at the same time. For the parent and the children to have the same coordinate system, the parent needs to set a viewBox that fits that of its children. But then the "fixed" child is positioned in that coordinate system and its height will be scaled when the parent changes its height (I'll assume width and height of the parent is set in a stylesheet):

<svg id="parent" viewBox="0 0 500 400" preserveAspectRatio="none">
    <svg id="noPreserveRatio" width="100%" height="100%"
         viewBox="0 0 500 400" preserveAspectRatio="none">
         ...
    </svg>
    <!-- always at the bottom, but no fixed height -->
    <svg id="fixed" x="0" y="300" width="100%" height="100"
         viewBox="..." preserveAspectRatio="...">
         ...
    </svg>
</svg>

To achieve a fixed height, you need to leave out the parent viewBox, but then you can only use relative units for x and y to describe the positioning of children. A transform attribute, on the other hand, could use absolute units (screen pixels, basically):

<svg id="parent">
    <svg id="noPreserveRatio" width="100%" height="100%"
         viewBox="0 0 500 400" preserveAspectRatio="none">
         ...
    </svg>
    <!-- always the same height, but not guaranteed to end at the bottom -->
    <svg id="fixed" x="0%" y="75%" width="100%" height="100"
         viewBox="..." preserveAspectRatio="...">
         ...
    </svg>
    <!-- ...but a small trickery can solve that: -->
    <svg id="fixed" x="0%" y="100%" width="100%" height="100px"
         transform="translate(0, -100)"
         viewBox="..." preserveAspectRatio="...">
         ...
    </svg>
</svg>
like image 90
ccprog Avatar answered Sep 23 '25 11:09

ccprog