Search code examples
htmlcssimagesvgvector-graphics

How do I Display a .svg Icon Without it Getting Clipped?


I am trying to display these social media icons on my website in such a way that I can change the color using css (so i can add the hover effect shown in the code below).

However, since these are vector image files (.svg) I couldn't seem to find a way to insert the image into my web page using the conventional <img src=""> method. So I proceeded to create CSS classes to get the image to appear as a CSS mask (thus allowing me to change the color via CSS).

However, I quickly noticed that the sides of the otherwise circular vector graphic icons were slightly cutoff. Being the perfectionist that I am, I wanted to make the icons actually appear round as they were supposed to. So, after checking out the webkit-mask MSDN entry I increased the width of the .media-buttons class and used -webkit-mask-position to shift the image a few pixels down and to the left as is evident in my code below. This obviously did not work.

It has also come to my attention that -webkit-mask is not fully supported by all browsers.

CSS:

#cross{-webkit-mask: url("http://path/to/image.svg") no-repeat;}
.media-buttons {
    width: 202px;
    height: 202px;
    background: #000;
    -webkit-mask-position: 10px 10px;
}
.media-buttons:hover {background: rgb(94, 176, 201);}

HTML:

<img class="media-buttons" id="cross">

TL;DR, I am looking for a (possibly new) way to display my .svg icons that has somewhat decent browser support and the ability to manipulate the icon's color via CSS.


Solution

  • Here's one way:

    svg:hover {
      color: #009BCD;
    }
    
    p {
      color: green;
    }
    <svg width="200px" height="200px" viewBox="0 0 200 200" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns" display="none">
        <title>Cross</title>
        <description>Created with Sketch (http://www.bohemiancoding.com/sketch)</description>
        <defs></defs>
        <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
            <path d="M100,0 C44.771524,3.03201907e-14 0,44.771524 0,100 C0,155.228476 44.771524,200 100,200 C155.228476,200 200,155.228476 200,100 C200,44.771524 155.228476,-3.41060513e-14 100,0 Z M84.0763011,40 L115.923699,40 L115.923699,84.1405714 L160,84.1405714 L160,116.034408 L115.923699,116.034408 L115.923699,160.16875 L84.0763011,160.16875 L84.0763011,116.034408 L40,116.034408 L40,84.1405714 L84.0763011,84.1405714 L84.0763011,40 Z" id="Cross" fill="currentColor" sketch:type="MSShapeGroup"></path>
        </g>
    </svg>
    
    
    
    <p>
    Heh! What's this
    <svg width="1em" height="1em" viewBox="0 0 200 200">
      <use xlink:href="#Cross"/>
    </svg>
    doing in the middle of a sentence?
    </p>
    
    <svg width="50px" height="50px" viewBox="0 0 200 200">
      <use xlink:href="#Cross"/>
    </svg>

    What I did here was:

    • Copy the SVG into the HTML (and removed the XML preamble)
    • Set display="none" on the <svg> so that it is invisible on the page.
    • Changed the fill on the icons <path> element to currentColor

    Now every time you want a copy of the icon to appear, create a mini-svg that reverences the <path> in the first SVG.

    <svg width="50px" height="50px" viewBox="0 0 200 200">
      <use xlink:href="#Cross"/>
    </svg>
    

    Just set it's size with the width and height values. You just need to include each icon once and you can reference them as many times as you like.

    What is currentColor for?

    currentColor is a special color value in SVGs that tells the elements to use the value of the current color setting. It means you can set the color outside the <use> element and it gets inherited by whatever the <use> is referencing. Normally you can't style each of the icon references individually. They would all be stuck having whatever fill the original <path> is set to.

    Using just the original SVG

    svg path {
      fill: blue;
    }
    
    svg:hover path {
      fill: #009BCD;
    }
    <p>SVG just used as is</p>
    
    <svg width="100px" height="100px" viewBox="0 0 200 200" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
        <title>Cross</title>
        <description>Created with Sketch (http://www.bohemiancoding.com/sketch)</description>
        <defs></defs>
        <g id="Page-1" stroke="none" stroke-width="1" fill-rule="evenodd" sketch:type="MSPage">
            <path d="M100,0 C44.771524,3.03201907e-14 0,44.771524 0,100 C0,155.228476 44.771524,200 100,200 C155.228476,200 200,155.228476 200,100 C200,44.771524 155.228476,-3.41060513e-14 100,0 Z M84.0763011,40 L115.923699,40 L115.923699,84.1405714 L160,84.1405714 L160,116.034408 L115.923699,116.034408 L115.923699,160.16875 L84.0763011,160.16875 L84.0763011,116.034408 L40,116.034408 L40,84.1405714 L84.0763011,84.1405714 L84.0763011,40 Z" id="Cross" sketch:type="MSShapeGroup"></path>
        </g>
    </svg>