Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scale inline SVG symbol referenced with <use>

Tags:

css

svg

I have an SVG logo defined as a symbol like so:

<svg class="SpriteSheet">
    <symbol id="icon-logo" viewBox="-12 -79.61 407.19 108.36">
        <path id="logo-upperLeft" d="M0-67.61l83.66 0 0-10 -93.66 0 0 30.92 10 0Z" transform="translate(-2 -2)"></path>
        <path id="logo-upperRight" d="M383.19-67.61l-83.66 0 0-10 93.66 0 0 30.92 -10 0Z" transform="translate(2 -2)"></path>
        <path id="logo-lowerLeft" d="M0 16.75l83.66 0 0 10 -93.66 0 0-30.92 10 0Z" transform="translate(-2 2)"></path>
        <path id="logo-lowerRight" d="M383.19 16.75l-83.66 0 0 10 93.66 0 0-30.92 -10 0Z" transform="translate(2 2)"></path>
    </symbol>
</svg>

This definition is included at the top of the body and styled with display:none.

Later in the document, I use the logo in this way:

<header class="Header">
    <h1 class="Header-headline">
        <a href="/">
            <svg class="Header-logo">
                <use xlink:href="#icon-logo"></use>
            </svg>
        </a>
    </h1>
</header>

I want to make the logo a certain height, with an automatic width:

.Header-logo {
    height: 5rem;
}

This results in this: svg width not scaling

Although the height is correct (here, 1rem is 24px), the width remains the default 300px. Adding width:auto causes no changes. In researching this problem, I came across several possible solutions here and here. However, none have worked with my application: reapplying the viewBox at the point of usage cuts off a large part of the image and using an <img> tag is not possible because I need to retain access to the SVG's DOM for styling purposes.

I could add a hard-coded width based on the known aspect ratio of the image, but this seems to be a non-optimal solution: what if the aspect ratio of the logo changes in the future? Another option is to define width:100%, which does work, however, this makes the 'clickable' area of the <a> extend across the entire width of the header, which I would like to avoid.

Is it possible to have an automatically-sized width with a defined height when the viewBox is described in the <symbol> definition? Must I be relegated to using an <img> tag or an absolute width for the SVG element?

like image 328
Scott Colby Avatar asked Jun 25 '15 14:06

Scott Colby


People also ask

Can SVG images be scaled?

Once you add a viewBox to your <svg> (and editors like Inkscape and Illustrator will add it by default), you can use that SVG file as an image, or as inline SVG code, and it will scale perfectly to fit within whatever size you give it. However, it still won't scale quite like any other image.

How do I scale SVG viewBox?

We use viewBox to make the SVG image scalable. viewBox = “0 0 100 100”: defines a coordinate system having x=0, y=0, width=100 units and height=100 units. Thus, the SVG containing a rectangle having width=50px and height=50px will fill up the height and width of the SVG image, and all the dimensions get scaled equally.

How do I use an SVG symbol?

The SVG <symbol> element is used to define graphical template objects which can be instantiated by the <use> element. The use of symbol elements for graphics that are used multiple times in the same document adds structure and semantics.

How do I change the size of an SVG icon in CSS?

Approach: You can simply customize the class of SVG by changing the height and width of the icons or by changing the values of viewBox attributes of SVG. Note: The viewBox attribute defines the position and dimension of an SVG viewport.


1 Answers

Unfortunately it is the dimensions of the <svg> element that appears in your <header> that is important. There is no way to inherit a viewBox from a child symbol reference.

You would need to copy the viewBox (width and height) from the symbol.

.Header-logo {
    height: 5rem;
}

.Header-logo2 {
    height: 8rem;
}
<svg class="SpriteSheet" width="0" height="0">
    <symbol id="icon-logo" viewBox="-12 -79.61 407.19 108.36">
        <path id="logo-upperLeft" d="M0-67.61l83.66 0 0-10 -93.66 0 0 30.92 10 0Z" transform="translate(-2 -2)"></path>
        <path id="logo-upperRight" d="M383.19-67.61l-83.66 0 0-10 93.66 0 0 30.92 -10 0Z" transform="translate(2 -2)"></path>
        <path id="logo-lowerLeft" d="M0 16.75l83.66 0 0 10 -93.66 0 0-30.92 10 0Z" transform="translate(-2 2)"></path>
        <path id="logo-lowerRight" d="M383.19 16.75l-83.66 0 0 10 93.66 0 0-30.92 -10 0Z" transform="translate(2 2)"></path>
    </symbol>
</svg>


<header class="Header">
    <h1 class="Header-headline">
        <a href="/">
            <svg class="Header-logo" viewBox="0 0 407.19 108.36">
                <use xlink:href="#icon-logo"></use>
            </svg>
        </a>
    </h1>
</header>

<header class="Header">
    <h1 class="Header-headline">
        <a href="/">
            <svg class="Header-logo2" viewBox="0 0 407.19 108.36">
                <use xlink:href="#icon-logo"></use>
            </svg>
        </a>
    </h1>
</header>
like image 175
Paul LeBeau Avatar answered Nov 16 '22 02:11

Paul LeBeau