In-depth analysis of viewBox attribute usage when HTML5 uses SVG images, html5viewbox
This article mainly introduces how to parse the viewBox attribute usage when using SVG images in HTML5, including some content related to responsive design. For more information, see
Quick introduction to viewBox Parameters
The viewBox attribute is used to specify the origin and size of the coordinate system of the SVG image. All the content drawn in SVG is relative to the coordinate system. Because the SVG canvas is infinitely extended in all directions, you can even draw images outside the boundaries of the coordinate system. However, these images are relative to those located in the SVG window, it can also be controlled by the position of the user coordinate system.
The viewBox attribute uses four parameters to specify the position 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 in (0, 0) -- that is, the upper left corner of SVG.
You can adjust the position of the origin by changing the values of x and y. You can change the size of the coordinate system by changing the values of width and height. You can extend or crop the SVG canvas by using the viewBox attribute only. Read with the example.
Important: In this article, I will not change the default behavior (ratio and position) of viewBox In the SVG window ). Because, according to the default behavior of properties, viewBox content will be fully included in the window as much as possible, and then placed in the central position. However, using the preserveAspectratio attribute allows you to freely change the size and position of the viewBox. However, this is not a required technique in this article, so we will not explain it in detail here.
Crop SVG using viewBox, that is, use the viewBox attribute to create the SVG of Art Direction
A while ago, one of my clients asked him to set the SVG avatar of his website to a different size based on different screen sizes, so that only a small part of it is visible on a small screen, the larger part is displayed on the medium screen size, and the complete content is displayed on the large screen. At that time, I first came up with the idea 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 based on different screen sizes.
By changing the size and origin location of the SVG coordinate system, we can crop the SVG and display the part of content we want to display in the window.
Let's take a look at how to implement it.
Suppose we have the following complete SVG image, and we want to crop it into a small screen size. This is a free-of-charge housing vector map designed by Freepik, which is licensed by the Creative Commons Attribution 3.0 Unported protocol. For the sake of simplicity, we first assume that the image is only cropped to the content displayed on a small screen and the complete content displayed on the large screen, as shown below.
The picture on the left is the complete image we want to crop using the viewBox attribute, and the picture on the right is the area we want to display on the small screen.
Now, you can crop SVG by changing the value of the viewBox attribute. We will discuss some things to consider later. But first, we need to change the coordinate system so that it matches the content of the dotted box rectangular area in the above image ., By adjusting the system origin and width and height values, we can change its initial 0 0 800 800 parameter value.
But how do we know the new coordinates and new dimensions? The focus is not to go through a large number of repeated experiments or errors.
There are several methods. Because we are already in the graphic editor (my example uses AI), we can use the panel of the editor to get the position and size of the element.
I drew the rectangle of the dotted line to show the content I want to display on a small screen. Another reason is that we can get the position and size of the rectangle, use them as viewBox values. Using the AI transform Panel (for example), we get the values we need. By selecting a rectangle and clicking the transform link in the upper right corner, we get the panel shown in, including the required values of x, y, width, and height.
The transform panel in AI can be used to obtain the position and size of the selected rectangle.
You may have noticed that the above value is not an integer, so we need to manually modify it. Based on the above information, we changed 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 is displayed in the window. After changing the value of viewBox
The newly cropped SVG. Only the location specified to use the viewBox attribute is visible in the window. The blue border indicates the SVG window.
At this point, there is a problem that needs to be solved:
If the aspect ratio of the cropped area (that is, viewBox) is! = SVG window aspect ratio?
In this case, there will be obvious overflow. Obviously, overflow refers not to the extension beyond the SVG window boundary, but to the overflow defined by viewBox relative to the new user coordinate system. Corresponding descriptions are provided.
If the viewBox aspect ratio is different from the window aspect ratio, the content in SVG overflows the user's coordinate system, and the result may be like this.
The black border represents the new user coordinate system, and the blue border represents the SVG window.
The black border in the upper right is the area defined by viewBox. Based on the default behavior of viewBox in the window, it is centered and zoomed as much as possible to ensure that its content is included in the window as much as possible (blue border.
In terms of concept, the SVG canvas is infinitely scalable in all directions. You can draw images outside the boundaries of the user's coordinate system, and the content will overflow directly, as shown in.
If you change the aspect ratio (SVG width and height) of the SVG window to adapt them to the aspect ratio of the viewBox, you will not see the overflow, because viewBox scaling is applicable to Windows, it is the same as the previous example.
However, in some cases, you may not or do not want to change the aspect ratio of SVG. For example, if you use SVG sprite as a set of images to display page slices. In most cases, an image has a fixed Aspect Ratio-and you don't want to change the size of the image to adapt to the content of a small image in it. Alternatively, you may embed an icon system and want all icons to be of the same size at the same time.
You can use <clipPath> to cut out unnecessary items (for example, some other icons on sprite are displayed in the window. The cropping path can be a <rect> element that overwrites the entire viewBox area, and then applies this element to the root SVG.
However, make sure that the x and y attributes of <rect> are consistent with those of viewBox, unless rect is located at the origin of the original/initialized system, the contents finally cropped by SVG are also uncertain.
Copy the content to the clipboard using CSS Code.
- <Svg xmlns = "http://w3.org/2000/svg" viewBox = "vx vy width height" clip-path = "url (# clipper)" width = "..." height = "...">
- <! -- SVG content here -->
- <ClipPath id = "clipper">
- <Rect x = "vx" y = "vy" width = "100%" height = "100%"> </rect>
- </ClipPath>
- </Svg>
Of course, cropping excess content means you are still using different aspect ratios, and you still need to solve the extra gaps on both sides of the content. If SVG is a continuous scenario, as in the previous example, it is unnecessary because you still need to adjust the aspect ratio of the window. If SVG is a group of icons and you only use them once in different windows, this may not be a problem.
One important thing to remember here is that the viewBox aspect ratio should be the same as the window aspect ratio. In addition, you need to set a fixed value to avoid any uncertain unnecessary blank spaces in SVG.
Therefore, viewBox can be used to crop SVG and display only a part of SVG as needed. But how does it apply to instances?
Art Directing SVG in responsive design
This part has nothing to add, except the actual process code. Therefore, suppose you want to use SVG as the Avatar, for example, you only want to display the cropped part of the content on a small-sized screen, then, the full avatar is displayed on the screen.
To change 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.
Not all SVG attributes can be used in the same way as CSS attributes. Only a group of attributes with the same effect as CSS attributes can be set in CSS. You can view 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. However, these attributes are available now.
To display different parts of SVG, you need to change the viewBox value based on different media queries. You can use Modernizr to find the media query conditions, and then change the viewBox value in JavaScript. Example:
Copy the content to the clipboard using CSS Code.
- // Obtain the reference of root <svg>
- Var svgRoot =...; // depends on how you embed and reference SVG
- // Define the parameter value of viewBox
- Var vbValue = '0 200 512 512 ';
- // Use the Modernizr media query to retrieve the viewBox Value
- If (Modernizr. mq ('(max-width: 700px )')){
- SvgRoot. setAttribute ('viewbox', vbValue );
- }
- // Other dimensions
This can be run, but isn't it better if we can use CSS to do this?
Use the viewBox attribute of CSS to crop SVG
Disclaimer: when writing this article, there is no CSSviewBox attribute. This is just an example to explain why this property is useful and how it is used.
Ideally, we can use it like this:
Copy the content to the clipboard using CSS Code.
- <Style>
- @ Media screen and (max-width: 700px ){
- Svg {
- ViewBox: 0 200 512 512;
- }
- }
- /* Etc .*/
- </Style>
These styles are put in (or extracted) SVG, and SVG then adjusts its viewBox value based on the size of the window. Make it a page window (Inline <svg> ), or you can use any other window that references the size of SVG elements (this can give us some queries for almost identical elements ).
However, this is not possible at present, because CSS does not have the viewBox attribute.
A while ago, I asked a question about the edit of the SVG specification. He said that I could give suggestions to SVGWG based on actual usage and instances. After some discussions on Twitter, I found that a similar SVGWG proposal thread exists a few years ago. The original proposal still exists today, so I hope that it can be implemented in the near future through some practical examples. If you want to see the viewBox attribute in CSS, please help to achieve this goal and push forward and comment on this proposal.
What you need to remember when using viewBox to complete SVG Art-Direction
It took me less than a minute to perform art-direct on the profile picture as required by the customer. However, this eventually separates three independent SVG, instead of the same SVG on different screen sizes and different viewboxes.
The reason we chose the three SVG files is that the full SVG file is too large and the size of the mobile terminal is larger than kb. The initial SVG size was about KB. I can optimize SVG to compress the file to nearly half the size, but for mobile devices, the image is still too large, therefore, we can only use three images of different sizes. When using art-directing SVG, you must remember the performance problems. If your SVG is too large, do not use viewBox for art-direct.
Now, if you choose to use three different SVG images, there are also several possible ways to do it-depending on the method you embed SVG, or what you want to do or do not want to do.
Using the <picture> element to complete different SVG images is the best way. It not only provides different SVG options for us based on the browser, but also does not require JavaScript, it also allows us to do not support its browsers (IE8 and below) provides a variety of optimized degraded images. <Picture> it is very useful for using SVG. You can read all the content of SVG fallback in this article.
But as mentioned above, If you want SVG with animation or interactive effects, <picture> is not the best choice. Just like using to embed SVG, SVG cannot be added with styles and animations, unless styles and animations are defined in the <svg> file, SVG cannot add scripts (for security reasons), nor have any interaction (CSS or JS)-for example, hovering does not have interaction effect.
Therefore, I always say: SVG provides many options for us to accomplish almost all things. You need to make a trade-off, differentiate priorities, and sometimes even compromise, make the best choice based on this. However, for performance, never compromise is conducive to development!
Before we end, we mentioned the problem of using the viewBox attribute to change the SVG canvas size. Let's take a look at another example, we can use this attribute to help us save some time and effort in processing SVG.
Use viewBox to expand the SVG canvas
Just as the viewBox attribute can be used to scale SVG, it can also be used to expand the SVG canvas.
A few weeks ago, I created a tool to generate an SVG circular menu. I have created several examples to demonstrate how to use JavaScript to move the generated menu. The demo uses the <object> element to embed it into the application page. The <object> boundary defines the boundary of the SVG window. Any content beyond these boundary overflows and is hidden by default.
It should be noted that "out of boundary" refers to the content in SVG, which is still on an infinite SVG canvas, but exceeds the infinite rectangle defined by the window.
Note: You can read articles on w3cplus about SVG canvases and windows.
The size of the created menu is that the menu can be included, but not larger. This avoids unnecessary white space around the menu.
I applied a bounce animation to a menu as an example of a menu animation. This bounce effect is "stretched" each menu item, which also leads to the menu items being split separately when they bounce (that is, overflow ).
At first, because the SVG window is defined by the <object> element, the window is as big as the menu itself, and the bounce effect on the menu item causes these menu items to overflow during the bounce.
These cute bounce animations are applied to projects that use the bounce time function to zoom in from 0 to 100% (that is, the project was initially invisible and reduced ), this effect is that if the project bounce to more than 100%, it will be reduced back to 100%. This effect causes the project to overflow when the bounce value exceeds the SVG boundary.
Shows the effect of scaling a menu item when it is enlarged to the border (gray border) that exceeds <object>. <object> is used to embed this zoom menu item.
The top shows how menu items zoom in to overflow the SVG window boundary. A gray border indicates the border of the SVG window (that is, the <object> element ).
Setting overflow: visible for <object> cannot solve the problem either, 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 project has enough space to "Bounce" without exceeding its boundary. We can use the viewBox attribute to complete it.
To extend the SVG canvas, simply increase its size. Therefore, we use a 700x500 PX size instead of the original size of the 250 x SVG menu. This also increases the height of the canvas displayed in the window by PX, while the canvas width in the window increases by PX. I determined these values based on the space needed to enlarge these menu items in the bounce effect. These values are inconsistent based on your SVG and the specific content you want to complete.
Now, to ensure that the menu is placed in the center of the window, we need to move the position of the coordinate system to the negative direction PX (that is, up and down to the left ). Applying this movement to the origin of the coordinate system is the same as applying a translation conversion to the menu in the system. The result is that the menu is left centered in the window.
In this figure, the blue border represents the SVG window border (that is, the <object> element), and the gray border represents the initial size of the user's coordinate system. The blue number and arrow indicate the expansion of the coordinate system in the window.
While extending the size of the user's coordinate system, you also increase the area of the visible area of the canvas in the window. The result is that the canvas content is slightly smaller-depending on how much you enlarge the canvas. However, this result is acceptable for menus.
The following screen records show the expanded SVG canvas results and menu animation effects within the SVG boundary.
Once the SVG canvas is expanded, the menu items have enough space to zoom in and out.
The SVG canvas is extended by changing the four parameter values of the viewBox attribute, so that all problems and menu item cut problems can be solved. ViewBox is really great ~~
Conclusion
The viewBox attribute is very good. It is an enhanced SVG tool. By using this attribute, you can save a lot of time when using SVG for work. You can quickly solve the SVG problem without using a Graphical Editor. All in all, this makes it much easier to edit SVG.
I strongly recommend that you fully learn this attribute and make it shine in your work. If you want to use it for art-direct SVG, do not forget that performance is the focus.