svg嵌套svg
The following is a short extract from Tiffany’s new book, CSS Master, 2nd Edition.
以下是Tiffany的新书CSS Master第二版的摘录。
With HTML documents, we might show, hide, or rearrange parts of the page based on the conditions of the viewport. If the browser window is 480 pixels wide, for example, we might shift our navigation from a horizontal one to a vertical, collapsible list. We can do something similar with media queries and SVG documents. Consider a logo, such as that of the fictitious Hexagon Web Design & Development below.
对于HTML文档,我们可能会根据视口的条件显示,隐藏或重新排列页面的各个部分。 例如,如果浏览器窗口的宽度为480像素,我们可能会将导航从水平列表更改为可折叠的垂直列表。 我们可以对媒体查询和SVG文档执行类似的操作。 考虑徽标,例如下面虚构的Hexagon Web设计与开发徽标。

Without media queries, this SVG logo would simply stretch or shrink to fit the viewport or its container. But with media queries, we can do more clever things.
如果没有媒体查询,此SVG徽标将仅会拉伸或收缩以适合视口或其容器。 但是借助媒体查询,我们可以做更多聪明的事情。
Let’s distinguish between the HTML document viewport and the SVG document viewport. When SVG is inline, the HTML viewport and the SVG viewport are one and the same. The SVG document behaves like any other HTML element. On the other hand, when an SVG document is linked—as with the object
or img
elements—we’re dealing with the SVG document viewport.
让我们区分HTML文档视口和SVG文档视口。 当SVG内联时,HTML视口和SVG视口是相同的。 SVG文档的行为类似于任何其他HTML元素。 另一方面,当链接SVG文档时(与object
或img
元素一样),我们将处理SVG文档视口。
Media queries work in both cases, but when the SVG document is linked, its viewport is independent of its HTML document. In that case, the size of the browser window doesn’t determine the size of the SVG viewport. Instead, the viewport size is determined by the dimensions of the object
, iframe
, or img
element. Take the (abridged) SVG document that follows as an example:[^4]
两种情况下都可以使用媒体查询,但是在链接SVG文档时,其视口独立于HTML文档。 在这种情况下,浏览器窗口的大小不会决定SVG视口的大小。 取而代之的是,视口大小由object
, iframe
或img
元素的尺寸确定。 以下面的(节略的)SVG文档为例:[^ 4]
<svg version="1.1" id="HexagonLogo" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 555 174" xml:space="preserve">
<defs>
<style type="text/css">
/* CSS goes here */
</style>
</defs>
<g id="hex">
<polygon id="hexagonbg" points="55.2,162 10,86.5 55.2,11 145.5,11 190.7,86.5 145.5,162 "/>
<path id="letterH" fill="#FFFFFF" d="M58,35.5h33v35.2h18.4V35.5 h33.2v103.4h-33.2v-38.3H91v38.3H58V35.5z M77.5,126.5V87.3h45.6v39.2h4V47.9h-4v35.6H77.5V47.9h-4v78.6H77.5z"/>
</g>
<g id="word-mark">
<g id="hexagon-word">
...
</g>
<g id="web-design-and-dev">
...
</g>
</g>
</svg>
In smaller viewports, let’s show just the H in a hexagon symbol:
在较小的视口中,让我们仅以六角形符号显示H:
@media (max-width: 20em) {
[id=word-mark] {
display: none;
}
}
In smaller viewports, let’s show just the H in a hexagon symbol:
在较小的视口中,让我们仅以六角形符号显示H:
Now, whenever our SVG’s container is less than or equal to 20em
, only the symbol portion of our logo will be visible, as indicated below.
现在,每当我们的SVG容器小于或等于20em
,只有徽标的符号部分才可见,如下所示。

To trigger this view from the HTML document, set the width of the SVG container:
要从HTML文档触发此视图,请设置SVG容器的宽度:
<object data="hexlogo.svg" type="image/svg+xml" style="width: 20em;"></object>
As you may have noticed from looking at the image above, our SVG image retains its intrinsic dimensions even though part of it has been hidden. This, unfortunately, is a limitation of SVG. To fix it, we need to change the viewBox
attribute of the SVG document, but only when the viewport is below a certain size. This is a great use case for matchMedia
.
从上图中您可能已经注意到,我们的SVG图像保留了其固有尺寸,即使其中一部分已被隐藏。 不幸的是,这是SVG的局限性。 要解决此问题,我们需要更改SVG文档的viewBox
属性,但仅当视口小于一定大小时才需要更改。 这是matchMedia
。
The viewBox
attribute, as its name suggests, determines the viewable area of an SVG element. By adjusting it, we can determine which part of an SVG image fills the viewport. What follows is an example using matchMedia
and a media query to update the viewBox
attribute:
顾名思义, viewBox
属性确定SVG元素的可视区域。 通过对其进行调整,我们可以确定SVG图像的哪一部分填充了视口。 以下是使用matchMedia
和媒体查询来更新viewBox
属性的示例:
<script type="text/javascript">
var svg, originalViewBox, max20em, mq, updateViewBox;
svg = document.querySelector('svg');
/* Store the original value in a variable */
originalViewBox = svg.getAttribute('viewBox');
/* Define our media query and media query object */
mq = matchMedia("(max-width: 20em)");
/* Define the handler */
updateViewBox = function(){
if (mq.matches) {
/* Change the viewBox dimensions to show the hexagon */
svg.setAttribute('viewBox', "0 0 200 174");
} else {
svg.setAttribute('viewBox', originalViewBox);
}
}
/* Fire on document load */
// WebKit/Blink browsers
svg.onload = updateViewBox;
// Firefox & IE
svg.addEventListener('SVGLoad', updateViewBox, true);
/* Fire if the media condition changes */
mq.addListener(updateViewBox);
</script>
Note: Browsers are a little bit of a mess when it comes to handling the SVGLoad
event. In my tests, addEventListener
worked most consistently with Firefox. For best results in Chrome and Safari, use the onload
event attribute. Microsoft Edge also works best with onload
, but only when used as an attribute of the <svg>
tag. In other words, <svg onload="updateViewBox">
.
注意:在处理SVGLoad
事件时,浏览器有点混乱。 在我的测试中, addEventListener
与Firefox最为一致。 为了在Chrome和Safari中获得最佳效果,请使用onload
事件属性。 Microsoft Edge也与onload
使用时效果最好,但仅当用作<svg>
标记的属性时。 换句话说,是<svg onload="updateViewBox">
。
Now, whenever the SVG container is 20em
or less, the value of viewBox
will be "0 0 200 174"
. When it exceeds 20em
, viewBox
will be restored to its initial value as represented below.
现在,每当SVG容器20em
或小于20em
, viewBox
的值将为"0 0 200 174"
。 当它超过20em
, viewBox
将恢复为其初始值,如下所示。

Note: For a fuller primer on creating interactive SVG documents, read the “Dynamic SVG and JavaScript” chapter of An SVG Primer for Today’s Browsers from the W3C.
注意:有关创建交互式SVG文档的更完整入门知识,请阅读 W3C的“ 当今浏览器的SVG入门 ”中的“ 动态SVG和JavaScript ”一章 。
Since this technique uses either the onload
event attribute or the SVGLoad
event, it’s a good idea to embed our CSS and JavaScript within the SVG file. When CSS is external, the SVGLoad
event may fire before its associated CSS finishes loading.
由于此技术使用onload
事件属性或SVGLoad
事件,因此最好将CSS和JavaScript嵌入SVG文件中。 如果CSS是外部的,则SVGLoad
事件可能在关联CSS完成加载之前触发。
使用background-size
媒体查询 (Using Media Queries with background-size
)
SVG documents and media queries aren’t limited to foreground images. We can also resize the SVG viewport using the CSS background-size
property. All of the latest major browsers support this technique, but older browser versions don’t. Be careful when using this technique in production.
SVG文档和媒体查询不限于前景图像。 我们还可以使用CSS background-size
属性调整SVG视口background-size
。 所有最新的主要浏览器都支持此技术,但较旧的浏览器版本不支持。 在生产中使用此技术时要小心。
We’ll start with this SVG document:
我们将从这个SVG文档开始:
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="Layer_1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="-20 -20 250 250" xml:space="preserve">
<style type="text/css">
circle {
stroke: #000;
stroke-width: 30;
fill: #009688;
}
@media (width: 100px) {
circle {
fill: #673ab7;
}
}
@media (width: 300px) {
circle {
fill: #ffc107;
}
}
</style>
</defs>
<circle cx="100" cy="100" r="100" />
<circle cx="100" cy="100" r="50" />
</svg>
This is a simple case. Our circle
elements will get a new fill
color at specific viewport widths. When the viewport is 20 pixels wide, the fill will be teal. When it’s 300 pixels wide, it will be yellow.
这是一个简单的情况。 我们的circle
元素将在特定的视口宽度处获得新的fill
颜色。 当视口为20像素宽时,填充将为蓝绿色。 宽度为300像素时,它将为黄色。
To make this work, we have to use our SVG image as a background image and set the selector’s background-size
property. In this case, we’ll use our image as a background for the body element
and for li
elements. The image below shows the results:
为了使这项工作有效,我们必须将SVG图像用作背景图像,并设置选择器的background-size
属性。 在这种情况下,我们将使用图像作为body element
和li
元素的背景。 下图显示了结果:
body, li {
background: url(../images/circles.svg);
}
body {
background-color: #9c27b0;
background-size: 300px auto;
}
li {
background-size: 20px auto;
background-repeat: no-repeat;
background-position: left 3px;
padding-left: 25px;
}

翻译自: https://www.sitepoint.com/using-svg-with-media-queries/
svg嵌套svg