响应INLINE SVG - svg的内容必须填充父宽度

时间:2013-05-29 12:24:37

标签: html svg responsive-design

目标:

我正在尝试使用INLINE SVG元素来填充父元素的完整可用宽度。我可以使用imgobject标记轻松地实现相同的效果来引用svg文件,但我想使用inline svg,因为我使用javascript为svg内部元素设置动画。

问题:

我可以在Firefox中实现这一点,并且在Chrome中也有一些调整,但是safari和IE9& IE10不会打球。

  • svg的内部内容并不总是在所有屏幕宽度中填充svg元素
  • webkit添加了一个神秘的填充/高度(在这个例子中,填充在svg元素内)SVG元素的高度应该是auto并包装内部svg内容。

主要问题:

是否有针对响应式INLINE SVG的跨浏览器解决方案:查看IE9中的示例& 10和-webkit-Safari并注意SVG元素中不需要的额外高度(青色)。

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> 

5 个答案:

答案 0 :(得分:23)

第一个问题是您将.svg-wrap div设置为100%高度。 100%的是什么?在这种情况下,div的父元素是body元素。当你的块级内容是身体高度的100%,以及其他流入元素时,你总是会有一个垂直的滚动条。因为您将始终拥有100%+ .stuff元素的内容。正如一般性提示一样,像这样的不断溢出应该是你的css中某些东西不稳定的提示。

继续进一步深入DOM,svg元素上的100%高度声明强制svg扩展为过高的包装器。这是罪魁祸首的另一部分。

我使用的解决方案涉及intrinsic ratios。像这样的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;
}

http://jsfiddle.net/pcEjd/

经过最新测试,FF,Chrome,Safari,(虽然不是IE)。

这种方法的缺点是:

a)你必须预先计算所有盒子的比例,或者写一个这样做的脚本。还不错。

b)您无法在全局范围内使用border-box星号选择器,或者您需要将svg容器的大小调整覆盖回content-box。做-能。

作为旁注,这显然不是事情应该如何运作。浏览器应足够智能,以查看SVG viewBox属性以获取比例,计算计算宽度(在任何maxWidth限制之后),然后计算高度。

但它目前没有那种方式。 Chrome中还有一个奇怪的错误,即向svg添加max-width:100%会产生一种情况,即svg始终会调整为最小的渲染大小。尝试在Chrome中加载此小提琴:

http://jsfiddle.net/ynmey/1/

你根本看不到SVG!奇怪的。甚至更奇怪,切换Dev Tools中的max-width声明,然后在jsfiddle中开始播放“result”视口的宽度。稍微窄一点,然后更宽,然后更窄,然后更宽。请注意,一旦svg被轻微缩小,当视口变大时它不会再次调整大小!

这一点很重要,因为:

 * {max-width:100%}

是一种常见的(并且完全合法的)响应式设计方法,它目前在Blink中对SVG造成严重破坏。所以现在坚持内在比率。

答案 1 :(得分:7)

内嵌 SVG元素的默认显示类型为display: inline;。这意味着SVG元素被放置在其父级的印刷基线上并相应地对齐。基线下方总有一些空间允许悬空的字符,如g和j等。

轻松修复:svg { display: block;}svg { display: inline-block; vertical-align: top; }

答案 2 :(得分:3)

通过设置heightauto以外的0值,我成功地在Webkit / Gecko浏览器中获得了一致的结果。在我的例子中,我使用1%,但从我可以说它可能是任何东西。不知怎的,这解决了Webkit中不正确的高度(从我的测试中我认为auto错误地将SVG高度设置为100%窗口高度。)

我还没有在IE中测试过这个。如果有效,请告诉我。

http://jsfiddle.net/yXeru/

答案 3 :(得分:2)

我不完全确定你想要达到的效果,但我认为你可能正在寻找preserveAspectRatio =“xMinYMin slice”

答案 4 :(得分:0)

经过反复摆弄,我使用的现代浏览器 IE11兼容解决方案包括两个部分:

  1. 在svg根标记中同时指定viewBoxpreserveAspectRatio="xMinYMin meet"
  2. 使用CSS媒体查询为每个布局以svg元素以vw为单位指定高度。

祝你好运!