Search code examples
htmlsvgposition

Position of <use> svg path


I need to position an icon path that I got from somewhere on the internet (soon to be replaced with my own). My first attempt using <symbol> in conjunction with <use> doesn't give me what I want despite significant tinkering (the icon won't get inside the square in the example below). Then I found that using <g> instead of <symbol> will do the trick, but at the cost of manually scaling the path myself. Since automatic scaling is nicer, there should be a way to position accurately with <symbol>.

The W3 specs mention the different behaviors of <use> depending on whether the reference is <symbol>, <svg>, or otherwise, but that flies right over my head.

<!DOCTYPE html>
<title>Icon won't get in box</title>

<body>
<svg>
<defs>
<symbol id="backward" viewBox="0 0 477.175 477.175"><path d="M145.188,238.575l215.5-215.5c5.3-5.3,5.3-13.8,0-19.1s-13.8-5.3-19.1,0l-225.1,225.1c-5.3,5.3-5.3,13.8,0,19.1l225.1,225 c2.6,2.6,6.1,4,9.5,4s6.9-1.3,9.5-4c5.3-5.3,5.3-13.8,0-19.1L145.188,238.575z"></path></symbol>
<g id='back2' transform='scale(.062)'>
<path d="M145.188,238.575l215.5-215.5c5.3-5.3,5.3-13.8,0-19.1s-13.8-5.3-19.1,0l-225.1,225.1c-5.3,5.3-5.3,13.8,0,19.1l225.1,225 c2.6,2.6,6.1,4,9.5,4s6.9-1.3,9.5-4c5.3-5.3,5.3-13.8,0-19.1L145.188,238.575z"></path>
</g>
</defs>

<g transform='translate(50,50)'>
<rect height='30' width='30' fill='#DDD' />
<use xlink:href='#backward' height='30' x='0' y='0' />
</g>

<g transform='translate(50, 100)'>
<rect height='30' width='30' fill='#DDD' />
<use xlink:href='#back2' x='0' y='0' />
</g>
</svg>
</body>


Solution

  • You just need to add width="30" to your <use> reference.

    <svg>
    <defs>
    <symbol id="backward" viewBox="0 0 477.175 477.175"><path d="M145.188,238.575l215.5-215.5c5.3-5.3,5.3-13.8,0-19.1s-13.8-5.3-19.1,0l-225.1,225.1c-5.3,5.3-5.3,13.8,0,19.1l225.1,225 c2.6,2.6,6.1,4,9.5,4s6.9-1.3,9.5-4c5.3-5.3,5.3-13.8,0-19.1L145.188,238.575z"></path></symbol>
    <g id='back2' transform='scale(.062)'>
    <path d="M145.188,238.575l215.5-215.5c5.3-5.3,5.3-13.8,0-19.1s-13.8-5.3-19.1,0l-225.1,225.1c-5.3,5.3-5.3,13.8,0,19.1l225.1,225 c2.6,2.6,6.1,4,9.5,4s6.9-1.3,9.5-4c5.3-5.3,5.3-13.8,0-19.1L145.188,238.575z"></path>
    </g>
    </defs>
    
    <g transform='translate(50,50)'>
    <rect height='30' width='30' fill='#DDD' />
    <use xlink:href='#backward' width="30" height='30' x='0' y='0' />
    </g>
    
    <g transform='translate(50, 100)'>
    <rect height='30' width='30' fill='#DDD' />
    <use xlink:href='#back2' x='0' y='0' />
    </g>
    </svg>

    When the width is not set, it defaults to 100% and the symbol is being centred in that 100% x 30px viewport. You can see that if we add an outline representing that box.

    Here "100%" means 100% of the SVG width. That value is 300px, which is the default width that browsers give to elements of indeterminate width.

    <svg overflow="visible">
    <defs>
    <symbol id="backward" viewBox="0 0 477.175 477.175"><path d="M145.188,238.575l215.5-215.5c5.3-5.3,5.3-13.8,0-19.1s-13.8-5.3-19.1,0l-225.1,225.1c-5.3,5.3-5.3,13.8,0,19.1l225.1,225 c2.6,2.6,6.1,4,9.5,4s6.9-1.3,9.5-4c5.3-5.3,5.3-13.8,0-19.1L145.188,238.575z"></path></symbol>
    </defs>
    
    <g transform='translate(50,50)'>
    <rect height='30' width='30' fill='#DDD' />
    <use xlink:href='#backward' height='30' x='0' y='0' />
    <rect width="100%" height="30" fill="none" stroke="red" />
    </g>
    
    </svg>