SVG Basics

Scalable Vector Graphics (SVG) is a Scalable Vector Graphics based on XML syntax. Compared with.png,.jpg and other scalar images, its file capacity is smaller, and the image will not be distorted when zooming in, zooming out or rotating. However, vector graphics can’t easily produce images that vary in color too much, so SVG is often used for ICONS and icon animations in web development.

Here are the. SVG and. PNG file sizes for the same shopping cart icon downloaded from iconfont:

The use of SVG

As an image file

PNG /.jpg is used in exactly the same way as scalar images such as.svg files with img tags and CSS background images:

<img height="100" width="100" src="./cart.svg">
Copy the code
.cart-icon{
   height: 100px;
   width: 100px;
   background: url(./cart.svg);
   background-size: cover;
}
Copy the code

You can also use ,,

As a label

HTML5 supports inline SVG, and we can use < SVG > tags as one of the HTML tags directly in the page structure, as part of the DOM, and then manipulate them with JavaScript and CSS.

<body>
    <svg>
        <rect width="100" height="100" fill="yellow" />
    </svg>
</body>
Copy the code

The above code snippet draws a yellow square 100px by 100px on the page. SVG has some predefined shape elements that are used in the form of tags:

,

, , , , etc. Each tag has its own attributes (such as width, height, and fill of

above), which together determine how the shape looks. More details on shape tags and attributes can be found in the documentation and won’t be covered here.

Icon to draw

Draws a play icon

<body>
    <svg>
        <circle cx="50" cy="50" r="50"  fill="lightblue"/>
        <line x1="35" y1="30" x2="35" y2="70" stroke-width="5" stroke="white"></line>
        <line x1="65" y1="30" x2="65" y2="70" stroke-width="5" stroke="white"></line>
    </svg>
</body>
Copy the code
// For the sake of observation, we will give the SVG a blue border, as will be the case later. <style> svg{ border: 1px solid blue; } </style>Copy the code

First, draw the light blue background of the play icon using the

tag, and then draw two vertical lines with .

Here are some points to note:

  1. One of the rules for SVG elements is to “come from behind” (when graphics coordinates overlap, the graphics of trailing tags will appear higher up), so the white line drawn by the tag will appear above the blue circle of the

    tag.

  2. In SVG, you may or may not specify units of value. If you do not specify a unit for the value, pixels (px) are used by default.

  3. < SVG > elements can be set by width and height. If not, the default is 300px by 150px, with the blue border above.

Coordinates in SVG

 <circle cx="50" cy="50" r="50"  fill="lightblue"/>
Copy the code

In the above line of code, we know that the position of the center of the circle is (50,50) and the radius is 50.

The origin, on the other hand, is the upper-left corner of the SVG tag.

If the coordinates of the graph exceed the width and height of SVG

<svg height="100" width="100">
    <circle cx="60" cy="60" r="50"  fill="lightblue"/>
</svg>
Copy the code

As shown above, if the coordinates of the graph exceed the width and height of the SVG, the excess will be cropped and will not be displayed.

We can divide the drawing and display of SVG into two parts: the canvas and the visible area.

A canvas can be thought of as a large two-dimensional (or even infinitely large) surface<svg>The top left corner of the element is the origin, and the graph on this plane (as in the example above)circle,lineCoordinates can be positioned anywhere in the plane.

And the visible region, in this case, is<svg>Element width and height (heightandwidthProperty, and only the graphs within this area will be displayed.

If the center of the circle is moved to (-5,-5), the display is as follows:

<svg height="100" width="100">
   <circle cx="-5" cy="-5" r="50"  fill="lightblue"/>
</svg>
Copy the code

One drawing, adaptive to multiple container sizes

We know that in order for the graph to be fully visible, the coordinates of each point of the graph must be in the visible region.

However, the more common requirement is to draw an icon and use it in multiple places, A page, B page, C page…

The size of the icon may be different each time you use it, that is, the width and height of the < SVG > element will have different values. In this case, how to ensure that the graphics are fully displayed? On the other hand, as vector graphics, one of the great advantages of ICONS drawn with < SVG > is that they are scalable.

viewBox

This requires the viewBox attribute of the < SVG > element. It specifies new visible region rules.

Let’s look at usage first:

<svg height="120" width="120" viewBox="0 0 100 100"> 
  <circle cx="50" cy="50" r="50"  fill="lightblue"/>
</svg>
<svg height="80" width="80" viewBox="0 0 100 100"> 
  <circle cx="50" cy="50" r="50"  fill="lightblue"/>
</svg>
<svg height="50" width="50" viewBox="0 0 100 100"> 
   <circle cx="50" cy="50" r="50"  fill="lightblue"/>
</svg>
Copy the code

ViewBox propertiesThere are four values:

ViewBox ="x, y, width, height" // x: top left abscess, y: top left abscess, width: width, height: heightCopy the code

The < SVG > element with the viewBox attribute is “smarter”, it says to the canvas, I don’t care about my width and height, I now show you an area in which I will display the graphics completely, this area is: top left coordinate (x,y), width to the right, height to the bottom. This rectangular area will cover my width and height, and you will draw in it!

ViewBox =”0 0 100 100″ indicates that the rectangle from 0 to 100 in the x direction and 0 to 100 in the y direction becomes the “new visible area” in which the graphics are fully displayed.

Regardless of the width and height of the < SVG > element, the content of the “new visible area” is mapped to the < SVG > element. There are some rules for mapping, which we will see in more detail below. This example is a relatively simple scale scaling, and the “new visible area” is enlarged or shrunk to cover the < SVG > element.

The whole canvas is the original image, the “new visible area” is the selected area of the screenshot, and the < SVG > element is where the screenshot is pasted.

A < SVG > element with no viewBox attribute set defaults to the viewBox attribute:

viewBox="0, 0, width of svg, height of svg"
Copy the code

The upper-left coordinates of the viewBox property (x, y) can also be other than (0,0), for example:

<svg height="120" width="120" viewBox="10 10 100 100"> 
   <circle cx="50" cy="50" r="50"  fill="lightblue"/>
</svg>
Copy the code

At this point, the canvas is in the x direction0 ~ 10The y direction0 ~ 10If this area is not visible, the graph in it will not be displayed.

However, for convenience, the upper-left coordinates (x, y) of the viewBox property are usually set to (0,0).

preserveAspectRatio

In addition to the geometric scaling above, another common situation is that the width/height ratio of a viewBox attribute is different from that of a < SVG > element.

Suppose there is A requirement that you draw A square shopping cart icon on page A (W :h=1:1), A flat shopping cart icon on page B (W :h=5:4), and everything else is the same. This is where the SVG icon needs to be stretched, and the stretch ratio is different, not proportional.

Case study:

<svg height="100" width="100" viewBox="0 0 100 100"> 
   <circle cx="50" cy="50" r="50"  fill="lightblue"/>
</svg>
<svg height="50" width="100" viewBox="0 0 100 100">  
   <circle cx="50" cy="50" r="50"  fill="lightblue"/>
</svg>
Copy the code

By default, whenViewBox propertiesthewidth/height, and<svg>Elements of thewidth/heightWhen it’s different, it stays the sameViewBox areaThe ratio of length to width, and thenViewBox areaTo adapt to<svg>Element, coincident with the short side (height) and the long side (width) in the center.

This is determined by the preserveAspectRatio property.

PreserveAspectRatio is an attribute of the < SVG > element, but applies to the viewBox.

// Default is preserveAspectRatio="xMidYMid meet" < SVG height="50" width="100" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet"> <circle cx="50" cy="50" r="50" fill="lightblue"/> </svg>Copy the code

Its value is a combination of two values separated by a space. The first value shows how the viewBox aligns with the < SVG > element; The second value indicates how the aspect ratio is maintained.

Let’s look at the second value. There are three cases: meet, slice, and None.

  • meet: keepViewBox areaThe ratio of length to width is reducedViewBox areaMake it all in<svg>In the element, the scaling ratio is: the minimum of the scaling ratio in the two directions (in the following example: 50/100 vs 120/100, take 50/100).
  • slice: keepViewBox areaRatio of length to width, zoom inViewBox areaFill,<svg>Element, and the scaling ratio is: the maximum of the scaling ratio in the two directions (in the following example: 50/100 vs 120/100, take 120/100). But beyond<svg>Parts of the element are clipped.
  • none: don’t keepViewBox areaThe ratio of length to width,ViewBox areaand<svg>The elements overlap perfectly.

The following is an example:

<svg height="100" width="100" viewBox="0 0 100 100"> 
   <circle cx="50" cy="50" r="50"  fill="lightblue"/>
</svg>
<svg height="50" width="120" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet">  
   <circle cx="50" cy="50" r="50"  fill="lightblue"/>
</svg>
<svg height="50" width="120" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid slice">  
   <circle cx="50" cy="50" r="50"  fill="lightblue"/>
</svg>
<svg height="50" width="120" viewBox="0 0 100 100" preserveAspectRatio="none">  
   <circle cx="50" cy="50" r="50"  fill="lightblue"/>
</svg>
Copy the code

Let’s look at the first value: xMidYMid. It definesViewBox areaThe relative<svg>The position of the element. There are three cases in x and Y directions (Min, Mid and Max) respectively. For example, in the X direction, the alignment is left, middle, and right.

If preserveAspectRatio=” None “, the relative position is not set. The official documentation lists “None” as the first value of preserveAspectRatio. We used it as the second value above, just to make sense.

Problem: Page A requires you to draw A square shopping cart icon (W :h=1:1), page B has A flatter shopping cart icon (W :h=5:4)

Answer: When drawing ICONS, set viewBox and preserveAspectRatio=” None “. When using SVG, set width and height as required.

Icon color customization

The player icon we drew above is blue, if we need orange for another page, we don’t want to change the SVG drawing code, how can the color of the icon be controlled externally?

Set the color that you want to change dynamically to currentColor, which is inherited from the parent element when using an SVG icon.

<svg height="50" width="50" style="color: rgb(210, 105, 30);"  viewBox="0 0 100 100">
    <circle cx="50" cy="50" r="50"  fill="currentColor"/>
    <line x1="35" y1="30" x2="35" y2="70" stroke-width="5" stroke="white"></line>
    <line x1="65" y1="30" x2="65" y2="70" stroke-width="5" stroke="white"></line>
</svg>

<svg height="50" width="50" style="color: rgb(210, 30, 114);" viewBox="0 0 100 100">
    <circle cx="50" cy="50" r="50"  fill="currentColor"/>
    <line x1="35" y1="30" x2="35" y2="70" stroke-width="5" stroke="white"></line>
    <line x1="65" y1="30" x2="65" y2="70" stroke-width="5" stroke="white"></line>
</svg>

<svg height="50" width="50" style="color: rgb(30, 210, 84);" viewBox="0 0 100 100">
    <circle cx="50" cy="50" r="50"  fill="currentColor"/>
    <line x1="35" y1="30" x2="35" y2="70" stroke-width="5" stroke="white"></line>
    <line x1="65" y1="30" x2="65" y2="70" stroke-width="5" stroke="white"></line>
</svg>
Copy the code

SVG Component Encapsulation

The ICONS we used above are all copied and pasted SVG drawing code, which is inefficient and inelegant. Next we wrap the icon as a component so that we can define it once and reference it multiple times. Fortunately, SVG has a set of built-in tags to support componentization.

<use>

<svg>     
   <line id="ALine" x1="35" y1="30" x2="35" y2="70" stroke-width="5" stroke="coral"></line>
</svg>
<svg>
   <use href="#ALine"></use>
</svg>
<svg>
   <use href="#ALine"></use>
</svg>
Copy the code

We draw a line with the line tag, and if we want to draw the same line elsewhere, we can specify an ID for the line tag. Where needed, use the

tag to set the href attribute to the previously defined ID.


is a built-in tag in SVG that takes the target nodes pointed to by the href attribute and copies them elsewhere.

The effect is the same as the nodes being deep-cloned into an invisible DOM and pasted into the use tag, much like clone template elements in HTML5.

<g>

Drawing an icon often requires more than one label. So how do you specify id?

We can put all the labels in a group and give the group an ID.

Draw a multi-colored play icon, and the code can be simplified as follows:

<svg> <g id="play"> <circle cx="50" cy="50" r="50" fill="currentColor"/> <line x1="35" y1="30" x2="35" y2="70" stroke-width="5" stroke="white"></line> <line x1="65" y1="30" x2="65" y2="70" stroke-width="5" stroke="white"></line> </g> </svg> <svg style="color: rgb(210, 105, 30);" > <use href="#play"></use> </svg> <svg style="color: rgb(210, 30, 114);" > <use href="#play"></use> </svg> <svg style="color: rgb(30, 210, 84);" > <use href="#play"></use> </svg>Copy the code

The first black button is used to define components and we don’t want it on the page. We can modify its CSS properties to hide it, but it is recommended<defs>The label.

<defs>

SVG allows us to define graphic elements that need to be reused later. It is recommended that all reference elements that need to be used again be defined within the

tag. Doing so increases the legibility and accessibility of SVG content. Graphic elements defined in the

tag are not rendered directly. You can render these elements anywhere in your viewport using the

tag.


<svg> <defs> <g id="play"> <circle cx="50" cy="50" r="50" fill="currentColor"/> <line x1="35" y1="30" x2="35" y2="70" stroke-width="5" stroke="white"></line> <line x1="65" y1="30" x2="65" y2="70" stroke-width="5" stroke="white"></line> </g> </defs> </svg> <svg style="color: rgb(210, 105, 30);" > <use href="#play"></use> </svg> <svg style="color: rgb(210, 30, 114);" > <use href="#play"></use> </svg> <svg style="color: rgb(30, 210, 84);" > <use href="#play"></use> </svg>Copy the code

<defs>The icon is no longer displayed, but the SVG is still there. We can change the CSS properties of SVG to hide it, or set the size to 0.

<svg width="0" height="0"> 
   <defs>
        <g id="play">
            <circle cx="50" cy="50" r="50"  fill="currentColor"/>
            <line x1="35" y1="30" x2="35" y2="70" stroke-width="5" stroke="white"></line>
            <line x1="65" y1="30" x2="65" y2="70" stroke-width="5" stroke="white"></line>
        </g>
    </defs>
</svg>
Copy the code

<symbol>

To adapt the icon to the container size, we use the viewBox property.

<svg width="0" height="0" viewBox="0 0 100 100"> 
   <defs>
       <g id="play">
            <circle cx="50" cy="50" r="50"  fill="currentColor"/>
            <line x1="35" y1="30" x2="35" y2="70" stroke-width="5" stroke="white"></line>
            <line x1="65" y1="30" x2="65" y2="70" stroke-width="5" stroke="white"></line>
       </g>
   </defs>
</svg>
Copy the code

The first instinct is to use the viewBox attribute on the SVG tag that defines the component, but it doesn’t work.

<svg height="50" width="50" style="color: rgb(210, 105, 30);" > <use href="#play"></use> </svg> <svg height="100" width="100" style="color: rgb(210, 30, 114);" > <use href="#play"></use> </svg> <svg height="200" width="200" style="color: rgb(30, 210, 84);" > <use href="#play"></use> </svg>Copy the code


gets the target nodes pointed to by the href attribute and copies them elsewhere. It does not copy the SVG tag that defines the outer layer of the component.

In this case, we use symbol.

The Symbol element is used to define a graphic template object that can be instantiated with a use element. The symbol element works with graphics by being used multiple times within the same document, adding structure and semantics. Well-structured documents can be presented more vividly, like speeches or braille, thus improving accessibility. Note that a symbol element itself is not rendered (similar to defs). Only instances of the Symbol element (that is, a use element that references symbol) can be rendered.

Most importantly, on the < Symbol > tag, you can define viewBox and preserveAspectRatio, which perfectly solves the problem of icon component adaptation.

<svg width="0" height="0"> <symbol id="play" viewBox="0 0 100 100"> <circle cx="50" cy="50" r="50" fill="currentColor"/>  <line x1="35" y1="30" x2="35" y2="70" stroke-width="5" stroke="white"></line> <line x1="65" y1="30" x2="65" y2="70" stroke-width="5" stroke="white"></line> </symbol> </svg> <svg height="50" width="50" style="color: rgb(210, 105, 30);" > <use href="#play"></use> </svg> <svg height="100" width="100" style="color: rgb(210, 30, 114);" > <use href="#play"></use> </svg> <svg height="200" width="200" style="color: rgb(30, 210, 84);" > <use href="#play"></use> </svg>Copy the code

conclusion

This article focuses on the use of SVG, basic icon drawing, icon size and color adaptation principle, as well as the packaging of icon components, in order to use SVG more elegantly in projects. For complex ICONS, you can download the icon SVG code on IconFont and adapt it to fit your project.

That’s all for today. See you next time!