Deeply analyze the usage of viewbox attribute when HTML5 uses SVG images

Time:2021-12-5

Quickly understand the parameters of viewbox

The viewbox property is used to specify the origin and size of the coordinate system of the user’s SVG image. All the content drawn in SVG is completed relative to this coordinate system. Because the SVG canvas is infinitely extended in all directions, you can even draw graphics outside the boundary of the coordinate system; However, these graphics positioned relative to the SVG window can also be controlled by the position of the user coordinate system.

The viewbox property uses four parameters to specify the location of the coordinate system origin and its size: X, y, width, height. Initially, this coordinate system is equivalent to the initialized window coordinate system (determined by the width and height of the SVG image), and its origin is (0,0) – that is, the upper left corner of the SVG.

The position of the origin can be adjusted by changing the values of the X and Y parameters. Changing the values of width and height can change the size of the coordinate system. Just use the viewbox attribute to help you expand or crop the SVG canvas. Read along with the example.

Important: in this article, I will not change the default behavior (scale and position) of viewbox in SVG window. Because, according to the default behavior of the attribute, the contents of the viewbox will be completely contained in the window as much as possible, and then placed in the center. However, using the preservespecificity property allows you to freely change the size and position of the viewbox, but this is not a necessary technique in this article, so we won’t go into it here.
Use the viewbox to clip the SVG, that is, use the viewbox attribute to make the SVG of art direction

A while ago, one of my customers asked to set the SVG avatar of his website to different sizes according to different screen sizes, so that only a small part of it can be seen on the small screen, a larger part can be seen on the medium screen size, and then the complete content can be seen on the large screen. At that time, the first idea in my mind was that his requirement was to use the viewbox attribute to crop the SVG image, and then display a part of the image he wanted to see according to different screen sizes.

By changing the size and origin position of the SVG coordinate system, we can crop the SVG and display the part we want to display in the window.

Let’s see how it works.

Suppose we have the following complete SVG image, and then we want to cut it to the size of a small screen. This picture is a free house vector designed by freepik. It is licensed under the creative common attribute 3.0 Unported protocol. For simplicity, let’s assume that the image is only to be cropped into the content displayed on the small and medium-sized screen and the complete content displayed on the large screen, as shown below.

The picture on the left is the complete picture we will crop using the viewbox attribute, and the picture on the right is the area we want to display on the small screen.

Now crop the SVG by changing the value of the viewbox attribute. There are some things to consider, which we will talk about later. But first, we need to change the coordinate system to match the contents of the virtual box rectangle in the above picture., By adjusting the origin of the system and the values of width and height, we can change its initial 0 0 800 parameter value.

But how do we know the new coordinates and dimensions? The point is not to go through a lot of repeated experiments and mistakes.

There are several ways. Because we are already in the graphic editor (my example uses AI), we can use the editor panel to obtain the position and size of elements.

The reason why I draw this dotted rectangle is not only to represent what I want to display on the small screen, but also that we can obtain the position and size of this rectangle and use them as the value of viewbox. Using the transformation panel of AI (as shown in the figure below), we get these values we need. By selecting the rectangle and clicking the transformation link in the upper right corner, we get the panel shown in the figure below, including the X, y, width and height values we need.

The transformation panel in this AI can be used to obtain the values of the position and size of the selected rectangle

You may have noticed that the above value is not an integer, so we need to modify it manually. According to the above information, we change the value of viewbox to 0 200 512 512.

Because the aspect ratio of the new viewbox is the same as that of the SVG window (both square), the content in the viewbox will be expanded, and only the selected area will be displayed in the window. After changing the value of viewbox, the results are as follows:

Newly cropped SVG. Only the location where we specify to use the viewbox property is visible in the window. The blue border represents the window of SVG.

In this regard, there is a problem to be solved:

If the aspect ratio of the cropped area (i.e. viewbox)= Aspect ratio of SVG window?

In this case, there will be obvious overflow. The obvious overflow is not the extension beyond the boundary of SVG window, but the overflow defined by viewbox relative to the new user coordinate system. The corresponding description is shown in the figure below.

If the aspect ratio of the viewbox is different from that of the window, the content in the SVG will overflow the user coordinate system, and the result may be this.

The black border represents the new user coordinate system, and the blue border is the SVG window.

The black border in the upper right figure is the area defined by viewbox. According to the default behavior of the viewbox in the window, it will be centered and enlarged as much as possible to ensure that its content is included in the window (blue border) as much as possible.

Because the SVG canvas is conceptually infinite in all directions, you can draw graphics outside the boundary of the user coordinate system, and the content will overflow and move directly, as shown in the above figure.

If you change the aspect ratio of SVG windows (width and height of SVG) to adapt them to the aspect ratio of viewbox, you won’t see overflow, because the zoom of viewbox is adapted to the window, just like the previous example.

However, in some cases, you may not be able or want to change the aspect ratio of SVG at all. For example, if you use SVG sprite as a set of images to display the images on the page. In most cases, the image has a fixed aspect ratio – and you don’t want to change the size of the image just to adapt to the content of a small image in it. Or maybe you have embedded an icon system and want all icons to remain the same size at the same time.

In order to cut off superfluous things (for example, some other icons on sprite are displayed in the window), you can use < clippath > to cut off the superfluous parts. The clipping path can be a < rect > element that covers the entire viewbox area, and then applies the element to the root SVG.

However, one more thing to remember: ensure that the X and Y attributes of < rect > are consistent with those of the viewbox. Unless rect will be relatively positioned at the origin of the original / initialized system, the final cut content of SVG is uncertain.

CSS CodeCopy contents to clipboard
  1. <svg xmlns=“http://w3.org/2000/svg” viewBox=“vx vy width height” clip-path=“url(#clipper)” width=“..” height=“..”>   
  2.     <!– SVG content here –>   
  3.     <clipPath id=“clipper”>   
  4.         <rect x=“vx” y=“vy” width=“100%” height=“100%”></rect>   
  5.     </clipPath>   
  6. </svg>  

Of course, cutting the excess part means that you are still using different aspect ratios, and you still need to solve the extra white space on both sides of the content. If SVG is a continuous scene, as in our previous example, it is not necessary, because you also need to adjust the aspect ratio of the window. If SVG is a set of icons and you only use it once in different windows, this may not be a problem.

It is important to remember that the aspect ratio of the viewbox should be consistent with that of the window; In addition, you need to set a fixed to avoid any uncertain and redundant blanks in SVG.

Therefore, viewbox can be used to crop SVG and show only some parts of SVG as needed. But how does it apply to instances?

Art directing SVG in responsive design

There is nothing to be added in this part, except the code of the actual process. So, suppose you have the SVG shown above and want to use it as a avatar. For example, on a small and medium-sized screen, you only want to display the cut part of the content, and then display the complete avatar on a large screen.

By changing the width and height values of the SVG window, we can use CSS. However, to change the value of viewbox, we need to use JavaScript at present.

Not all SVG attributes and CSS attributes can be used equally; Only a set of properties with the same effect as CSS properties can be set in CSS. You can view an overview of this set of SVG attributes that can be used as CSS attributes in this table. In svg2, many attributes (such as X, y, CX, cy, R, etc.) can be added to this list; But these are properties that we can use now.

In order to show different parts of SVG, you need to change the value of viewbox based on different media queries. You can use modernizr to find the media query conditions, and then change the value of viewbox in JavaScript. Examples are as follows:

CSS CodeCopy contents to clipboard
  1. //   Get root  < Reference to SVG >
  2. var   svgRoot  = …; //  It depends on how you embed and reference SVG
  3. //   Defines the parameter value of the viewbox
  4. var vbValue = ‘0 200 512 512’;   
  5. //   Use modernizr’s media query retrieval to change the value of viewbox
  6. if (Modernizr.mq(‘(max-width: 700px)’)) {   
  7.    svgRoot.setAttribute(‘viewBox’, vbValue);   
  8. }   
  9. //   Other dimensions

This can work, but wouldn’t it be better if we could use CSS to complete this effect?

Use the viewbox property of CSS to crop the SVG

Disclaimer: at the time of writing this article, there is no cssviewbox attribute. This is just an example to explain why this attribute is useful and how I imagine it can be used.

Ideally, we can use it this way:

CSS CodeCopy contents to clipboard
  1. <style>   
  2.   
  3. @media screen and (max-width700px) {   
  4.     svg {          
  5.         viewBox: 0 200 512 512;    
  6.     }    
  7. }   
  8.   
  9. /* etc. */  
  10.   
  11. </style>  

These styles will be put into (or taken out of) SVG, and then SVG will adjust its viewbox value according to the size of the window. Make it a page window (inline < SVG >), or a window determined by the size of any other element that references SVG (which can give us some nearly identical element queries).

However, this is not possible at present, because there is no viewbox attribute in CSS.

A while ago, I asked an editor of SVG specification about this problem. He said that I can make suggestions to svgwg according to actual usage and examples. After some discussion on twitter, I found that there was a similar svgwg proposal thread a few years ago. The original proposal still exists today, so I hope that through some practical examples, this proposal can be promoted and implemented in the near future. If you also want to see the viewbox attribute in CSS, please help achieve this goal and promote the forwarding and comments of this proposal.

Things to remember when using viewbox to complete SVG art direction

When working on my client’s project, I spent less than a minute to art direct the avatar according to the other party’s requirements. However, this eventually separates three independent SVGs instead of the same SVG and different viewboxes on different screen sizes.

The reason why we choose three SVGs is that the size of the complete SVG is too large and reaches more than 100kb at the mobile end. The initial SVG is about 200KB. I can compress the file to nearly half the size by optimizing SVG, but the image is still too large for mobile devices, so we can only use three images of different sizes in the end. When art directing SVG, you need to remember: performance issues. If your SVG is too large, don’t use viewbox for art direct.

Now, if you choose to use three different SVG images, there are many possible ways to do it – depending on how you embed SVG, what you want to do and what you don’t want to do.

It is ideal to use the < picture > element to complete different SVG images. It can not only provide us with different SVG options according to the browser, but also does not need to use JavaScript. It also allows us to provide a variety of optimized degraded images for browsers that do not support it (IE8 and below)< Picture > it is very useful for using SVG. You can read all SVG fallbacks in this article.

However, as mentioned earlier, < picture > is not the best choice if you want SVG with animation or interactive effects. Just like embedding SVG with < img >, SVG cannot be added with styles and animations. Unless the styles and animations are defined in the < SVG > file, SVG cannot add scripts (for security reasons), nor can there be any interaction (CSS or JS) – for example, hovering, there will be no interaction effect.

Therefore, I always say: SVG provides us with many options that allow us to complete almost everything; You need to make a trade-off, clear priorities, and sometimes even compromise to make the best choice. But for performance, never compromise is conducive to development!

Before we finish, because we mentioned the problem of changing the size of the SVG canvas using the viewbox attribute, let’s take another example. We can use this attribute to help us save some time and energy when dealing with SVG.

Extend SVG canvas with viewbox

Just as the viewbox attribute can be used to scale SVG, it can also be used to extend the SVG canvas.

A few weeks ago, I created a tool that can generate SVG circular menus. I created several examples to demonstrate how to use JavaScript to make the generated menu move. The demo is embedded on the application page using the < Object > element< The boundary of Object > defines the boundary of SVG window. Any content outside these boundaries is overflow and hidden by default.

It should be noted that “beyond the boundary” refers to the content in SVG. It is still on the infinite SVG canvas, but it exceeds the infinite rectangle defined by the window

Translator’s note: for the contents of SVG canvas and window, you can read the relevant articles on w3cplus.
For the created menu, the size of SVG is just enough to include the menu without being larger. Any extra white space around the menu is avoided.

I applied a bounce animation to a menu as an example of menu animation. This bouncing effect “lengthens” the menu items, and also causes the menu items to be cut out separately (i.e. overflow) when they bounce.

At first, because the SVG window is defined by the < Object > element, the window is as large as the menu itself. The bouncing effect on menu items causes these menu items to overflow when bouncing.

These lovely bounce animations are applied to projects that use the bounce time function to zoom in from 0 to 100% (that is, the project is initially invisible and reduced). The effect is to shrink the project back to 100% if it bounces to more than 100%. This effect will cause the project to overflow when bouncing beyond the SVG boundary.

The following figure shows the effect of the zoom menu item when it is enlarged beyond the boundary (gray border) of < Object >, where < Object > is used to embed the zoom menu item.

The diagram above shows the effect when the menu item is enlarged to overflow the boundary of SVG window. The gray border represents the border of the SVG window (that is, the < Object > element).

Setting overflow: visible to < Object > does not solve the problem, because < Object > and < iframe > are actually similar. What we need to do is to expand the SVG canvas in the window created by < Object > so that the scaled item has enough “bounce” space without exceeding its boundary. We can do this using the viewbox attribute.

To extend the SVG canvas, simply increase its size. Therefore, we use the size of 700 x 500px instead of the original size of the SVG menu of 500 x 250. This also increases the height of the canvas in the window by 100px and the width of the canvas in the window by 200px. I determine these values according to the space that these menu items need to enlarge in the bounce effect. Depending on your SVG and what you want to do, these values are not required to be consistent.

Now, in order to ensure that the menu is placed in the center of the window, we need to move the position of the coordinate system by 100px in the negative direction (i.e. up and left). Applying this movement to the origin of the coordinate system is the same as applying a translation transformation to the menu in the system. As a result, the menu remains centered in the window.

In this figure, the blue border represents the SVG window boundary (i.e. < Object > element), and the gray border represents the initial size of the user coordinate system. Blue numbers and arrows represent the extension of the coordinate system in the window.

While extending the size of the user coordinate system, you also increase the area of the visible area of the canvas in the window. The result is that the contents of the canvas will appear slightly smaller – depending on how much you enlarge the canvas. But for the menu, this result is acceptable.

The following screen record shows the results of extending the SVG canvas and the menu animation within the SVG boundary.

Once the SVG canvas is expanded, the menu items will have enough space to zoom, and the bouncing effect will not be cut due to overflow.

Extend the SVG canvas by changing the four parameter values of the viewbox attribute, so that all problems and the problem of menu items being cut can be solved. Viewbox is really great~~

Conclusion

The viewbox property is great. It is an enhanced version of SVG. By using this attribute, you can save a lot of time when working with SVG, and you can quickly solve the problem of SVG without the help of a graphical editor. All in all, this is really convenient for editing SVG.

I strongly recommend that you learn this attribute thoroughly and let it shine in your work. If you want to use it for art direct SVG, don’t forget that performance is the key.