Html 响应式内联 SVG - svg 的内容必须填充父宽度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16813829/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Responsive INLINE SVG - content of svg must fill parent width
提问by Timidfriendly
GOAL:
目标:
I am trying to get an INLINE SVG
element to fill the full available width of the parent element. I can achieve the same effect easily using an img
and object
tag to reference the svg file, but I want to use inline svg
because I am animating the svg inner elements with javascript.
我试图让一个INLINE SVG
元素来填充父元素的全部可用宽度。我可以使用img
andobject
标记来引用 svg 文件轻松实现相同的效果,但我想使用,inline svg
因为我正在使用 javascript 为 svg 内部元素设置动画。
PROBLEM:
问题:
I can achieve this in Firefox and with some tweaks also in Chrome, but safari and IE9 & IE10 won't play ball.
我可以在 Firefox 中实现这一点,在 Chrome 中也可以进行一些调整,但 safari 和 IE9 和 IE10 无法正常运行。
- The inner content of svg doesn't always fill the svg element in all screen widths
- webkit adds a mysterious padding/height (in this example the padding is within svg element) The height of SVG element should be auto and wrap the inner svg content.
- svg 的内部内容并不总是填充所有屏幕宽度的 svg 元素
- webkit 添加了一个神秘的填充/高度(在这个例子中,填充在 svg 元素内)SVG 元素的高度应该是 auto 并包裹内部的 svg 内容。
MAIN QUESTION:
主要问题:
Is there a cross browser solution for responsive INLINE SVG:View the example in IE9 & 10 and -webkit-Safari and notice the unrequired extra height within SVG element (cyan color).
是否有响应式内联 SVG 的跨浏览器解决方案:查看 IE9 & 10 和 -webkit-Safari 中的示例,并注意 SVG 元素(青色)中不需要的额外高度。
http://jsfiddle.net/David_Knowles/9tUAd/
http://jsfiddle.net/David_Knowles/9tUAd/
<div class="block">stuff</div>
<div class="wrap">
<svg version="1.1" baseProfile="basic" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 550 350" xml:space="preserve" preserveAspectRatio="xMinYMin meet">
<rect x="0" y="0" width="550" height="350"/>
<polyline points="0,0 0,350 550,350"/>
<text x="0" y="50%" fill="#ffffff" stroke="none" width="100%">The text</text>
</svg>
</div>
<div class="block">stuff</div>
回答by Ben
The first problem is that you are setting your .svg-wrap
div to 100% height. 100% of what? In this case, that div's parent element is the body element. When you've got block-level content that's 100% of the body's height, and other in-flow elements, you're always going to have a vertical scrollbar. because you will always have contents of 100% + your .stuff
elements. Just as a general tip, constant overflow like this should be the tipoff that something is wonky in your css.
第一个问题是您将.svg-wrap
div设置为 100% 高度。100%什么?在这种情况下,该 div 的父元素是 body 元素。当您拥有 100% 主体高度的块级内容和其他流入元素时,您将始终拥有一个垂直滚动条。因为您将始终拥有 100% + 您的.stuff
元素的内容。就像一般提示一样,像这样的持续溢出应该是您的 css 中某些东西不稳定的提示。
Continuing further into the DOM, the 100% height declaration on your svg
element is forcing the svg
to expand to the overly tall wrapper. And that's another part of the culprit.
继续深入 DOM,svg
元素上的 100% 高度声明迫使svg
扩展到过高的包装器。这是罪魁祸首的另一部分。
The solution I use involves intrinsic ratios. CSS like this:
我使用的解决方案涉及内在比率。像这样的 CSS:
.svg-wrap {
background-color:red;
height:0;
padding-top:63.63%; /* 350px/550px */
position: relative;
}
svg {
background-color: cyan;
height: 100%;
display:block;
width: 100%;
position: absolute;
top:0;
left:0;
}
Tested in latest, FF, Chrome, Safari, (though not IE).
在最新的 FF、Chrome、Safari(虽然不是 IE)中测试。
The downsides of this approach are that:
这种方法的缺点是:
a) you have to precalculate ratios for all your boxes, or write a script that does so. Not too bad.
a) 您必须预先计算所有盒子的比率,或者编写一个脚本来这样做。还不错。
b) you can't use border-box
globally with the star selector, or if you do you need to override box-sizing back to content-box
for your svg containers. Do-able.
b) 您不能border-box
在全局范围内使用星形选择器,或者如果您需要将 box-sizing 覆盖回content-box
您的 svg 容器。能干。
As a side note, this obviously isn't how things are supposed to work. Browsers should be smart enough to look at the SVG viewBox attribute to get the proportions, calculate the computedwidth (after any maxWidth limits) and then compute the height.
作为旁注,这显然不是事情应该如何运作。浏览器应该足够聪明,可以查看 SVG viewBox 属性以获取比例,计算计算宽度(在任何 maxWidth 限制之后),然后计算高度。
But it doesn't currently work that way. There's another weird bug in Chrome where adding max-width:100%
to the svg creates a situation where the svg always sizes to the smallest rendered size. Try loading this fiddle in Chrome:
但它目前不是这样工作的。Chrome 中还有另一个奇怪的错误,即添加max-width:100%
到 svg 会导致 svg 始终大小为最小的渲染大小。尝试在 Chrome 中加载这个小提琴:
An you'll see no SVG at all! Weird. Even weirder, toggle off the max-width
declaration in Dev Tools, and then start playing with the width of the "result" viewport in jsfiddle. Take it slightly narrower, then wider, then narrower, then wider. Notice that once the svg gets nudged smaller, it doesn't resize back up again when the viewport gets bigger!
你根本看不到SVG!奇怪的。更奇怪的是,max-width
在 Dev Tools 中关闭声明,然后开始在 jsfiddle 中使用“结果”视口的宽度。把它稍微窄一点,然后更宽,然后更窄,然后更宽。请注意,一旦 svg 变得更小,当视口变大时它不会再次调整大小!
This is important to note because:
这一点很重要,因为:
* {max-width:100%}
is a common (and totally legit) responsive design approach, and it currently wreaks havoc with SVG in Blink. So stick to intrinsic ratios for now.
是一种常见(且完全合法)的响应式设计方法,目前它对 Blink 中的 SVG 造成了严重破坏。所以现在坚持内在比率。
回答by jvhellemond
The default display type for inlineSVG elements is display: inline;
. This means that the SVG element is placed on the typographic baseline of its parent and is aligned accordingly. There is always some space below the baseline to allow for the dangling bits of characters like g and j and such.
内联SVG 元素的默认显示类型是display: inline;
. 这意味着 SVG 元素被放置在其父元素的排版基线上并相应地对齐。基线下方总是有一些空间,以允许 g 和 j 等字符的悬空位。
Easy fix: svg { display: block;}
or svg { display: inline-block; vertical-align: top; }
.
轻松修复:svg { display: block;}
或svg { display: inline-block; vertical-align: top; }
。
回答by Michael Mullany
I'm not entirely sure what effect you're trying to achieve, but I think you might be looking for preserveAspectRatio ="xMinYMin slice"
我不完全确定你想要达到什么效果,但我认为你可能正在寻找 preserveAspectRatio ="xMinYMin slice"
回答by daviestar
I've managed to achieve consistent results in Webkit/Gecko browsers by setting a height
value other than auto
or 0
. In my example I use 1%
, but from what I can tell it could be anything. Somehow this resolves the incorrect height in Webkit (from my tests I think auto
incorrectly sets the SVG height to 100%
window height).
通过设置orheight
以外的值,我设法在 Webkit/Gecko 浏览器中获得一致的结果。在我的示例中,我使用,但据我所知,它可以是任何东西。这以某种方式解决了 Webkit 中不正确的高度(从我的测试中我认为错误地将 SVG 高度设置为窗口高度)。auto
0
1%
auto
100%
I haven't tested this in IE yet. Please let me know if it works.
我还没有在 IE 中测试过这个。请让我知道它是否有效。
回答by ryanrain
After much fiddling, the modern browser andIE11 compatible solution I used has two parts:
经过一番折腾,我使用的现代浏览器和IE11 兼容解决方案有两个部分:
- Specify both
viewBox
andpreserveAspectRatio="xMinYMin meet"
in the svg root tag. - Use css media queries to give your svg element a height in
vw
units for each layout.
- 在 svg 根标记中同时指定
viewBox
和preserveAspectRatio="xMinYMin meet"
。 - 使用 css 媒体查询为您的 svg 元素
vw
提供每个布局的单位高度。
good luck!
祝你好运!