【发布时间】:2019-03-08 08:20:32
【问题描述】:
我正在努力解决 SVG 元素的固有大小问题。
根据 SVG 规范,8.12. Intrinsic sizing properties of SVG content 章,我们知道:
为了在使用 CSS 格式化的宿主文档中包含 SVG, 必须计算具体对象的大小。具体对象大小必须 使用默认大小算法计算
作为默认大小算法的输入,我们在同一部分中读到:
指定的尺寸必须根据使用的值确定 “svg”元素的宽度和高度尺寸属性。
还有:
内在尺寸也必须由宽度和 高度尺寸属性。如果未指定宽度或高度, 使用的值是初始值'auto'。 'auto' 和百分比 不得使用长度来确定内在宽度或内在 高度。
所以,如果我们没有在最外层的 svg 元素上设置 width 和 height,我们就有 固有尺寸 (width / height)为auto(含糊地建议不要这样做)。 Default Sizing Algorithm的相关部分:
如果指定的尺寸没有约束(没有宽/高):
- 如果对象具有固有高度或宽度,则解析其大小 就好像它的内在大小被指定为指定大小一样。
- 否则,其大小将被解析为针对默认对象大小的包含约束
最后来自8.3. The initial viewport:
初始视口的宽度,必须是宽度的值 最外层 svg 元素上的presentation 属性...
尽管上面有第一个粗体警告,不在最外层的 svg 元素上定义 width 和 height 表示属性是正常的。 Adobe Illustrator 等程序通常会忽略这些属性,而只是定义一个 viewBox。
所以我的问题是:
如果没有设置 width 和 height 属性,我可以在规范中的何处找到 svg 元素使用的 width 和 height 将是什么有吗?
同样,在同样的场景中,viewport 的尺寸会是多少(仅给定一个 svg 元素)?
附带说明,来自 css-sizing-3 4. Intrinsic Size Determination:
对于具有固有纵横比但没有固有大小的框:
如果内联轴上的可用空间是确定的,则使用拉伸 适合内联大小的大小并计算块大小 使用纵横比。
一些代码
展示了我无法理解的行为(即在两种 flexbox 情况下如何计算尺寸)。
注意:当布局为列时,弹性项目的宽度为零。 (这与 SVG 有关,与 flexbox 无关)。
.c1,
.c2 {
display: flex;
height: 500px;
align-items: flex-start;
}
.c1 {
flex-flow: row nowrap;
border: 1px solid green;
}
.c1 .i1 {
flex: 0 1 100px;
border: 1px solid blue;
}
.c2 {
flex-flow: column nowrap;
border: 1px solid green;
}
.c2 .i2 {
flex: 0 1 100px;
border: 1px solid red;
}
<div class="c1">
<div class="i1">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 300 300">
<defs>
<g id="SVG" fill="#fff" transform="scale(2) translate(20,79)">
<path id="S" d="M 5.482,31.319 C2.163,28.001 0.109,23.419 0.109,18.358 C0.109,8.232 8.322,0.024 18.443,0.024 C28.569,0.024 36.782,8.232 36.782,18.358 L26.042,18.358 C26.042,14.164 22.638,10.765 18.443,10.765 C14.249,10.765 10.850,14.164 10.850,18.358 C10.850,20.453 11.701,22.351 13.070,23.721 L13.075,23.721 C14.450,25.101 15.595,25.500 18.443,25.952 L18.443,25.952 C23.509,26.479 28.091,28.006 31.409,31.324 L31.409,31.324 C34.728,34.643 36.782,39.225 36.782,44.286 C36.782,54.412 28.569,62.625 18.443,62.625 C8.322,62.625 0.109,54.412 0.109,44.286 L10.850,44.286 C10.850,48.480 14.249,51.884 18.443,51.884 C22.638,51.884 26.042,48.480 26.042,44.286 C26.042,42.191 25.191,40.298 23.821,38.923 L23.816,38.923 C22.441,37.548 20.468,37.074 18.443,36.697 L18.443,36.692 C13.533,35.939 8.800,34.638 5.482,31.319 L5.482,31.319 L5.482,31.319 Z"/>
<path id="V" d="M 73.452,0.024 L60.482,62.625 L49.742,62.625 L36.782,0.024 L47.522,0.024 L55.122,36.687 L62.712,0.024 L73.452,0.024 Z"/>
<path id="G" d="M 91.792,25.952 L110.126,25.952 L110.126,44.286 L110.131,44.286 C110.131,54.413 101.918,62.626 91.792,62.626 C81.665,62.626 73.458,54.413 73.458,44.286 L73.458,44.286 L73.458,18.359 L73.453,18.359 C73.453,8.233 81.665,0.025 91.792,0.025 C101.913,0.025 110.126,8.233 110.126,18.359 L99.385,18.359 C99.385,14.169 95.981,10.765 91.792,10.765 C87.597,10.765 84.198,14.169 84.198,18.359 L84.198,44.286 L84.198,44.286 C84.198,48.481 87.597,51.880 91.792,51.880 C95.981,51.880 99.380,48.481 99.385,44.291 L99.385,44.286 L99.385,36.698 L91.792,36.698 L91.792,25.952 L91.792,25.952 Z"/>
</g>
</defs>
<path id="base" fill="#000" d="M8.5,150 H291.5 V250 C291.5,273.5 273.5,291.5 250,291.5 H50 C26.5,291.5 8.5,273.5 8.5,250 Z"/>
<g stroke-width="38" stroke="#000">
<g id="svgstar" transform="translate(150, 150)">
<path id="svgbar" fill="#ffb13b" d="M-84.1487,-15.8513 a22.4171,22.4171 0 1 0 0,31.7026 h168.2974 a22.4171,22.4171 0 1 0 0,-31.7026 Z"/>
<use xlink:href="#svgbar" transform="rotate(45)"/>
<use xlink:href="#svgbar" transform="rotate(90)"/>
<use xlink:href="#svgbar" transform="rotate(135)"/>
</g>
</g>
<use xlink:href="#svgstar"/>
<use xlink:href="#base" opacity="0.85"/>
<use xlink:href="#SVG"/>
</svg>
</div>
</div>
<div class="c2">
<div class="i2">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 300 300">
<defs>
<g id="SVG" fill="#fff" transform="scale(2) translate(20,79)">
<path id="S" d="M 5.482,31.319 C2.163,28.001 0.109,23.419 0.109,18.358 C0.109,8.232 8.322,0.024 18.443,0.024 C28.569,0.024 36.782,8.232 36.782,18.358 L26.042,18.358 C26.042,14.164 22.638,10.765 18.443,10.765 C14.249,10.765 10.850,14.164 10.850,18.358 C10.850,20.453 11.701,22.351 13.070,23.721 L13.075,23.721 C14.450,25.101 15.595,25.500 18.443,25.952 L18.443,25.952 C23.509,26.479 28.091,28.006 31.409,31.324 L31.409,31.324 C34.728,34.643 36.782,39.225 36.782,44.286 C36.782,54.412 28.569,62.625 18.443,62.625 C8.322,62.625 0.109,54.412 0.109,44.286 L10.850,44.286 C10.850,48.480 14.249,51.884 18.443,51.884 C22.638,51.884 26.042,48.480 26.042,44.286 C26.042,42.191 25.191,40.298 23.821,38.923 L23.816,38.923 C22.441,37.548 20.468,37.074 18.443,36.697 L18.443,36.692 C13.533,35.939 8.800,34.638 5.482,31.319 L5.482,31.319 L5.482,31.319 Z"/>
<path id="V" d="M 73.452,0.024 L60.482,62.625 L49.742,62.625 L36.782,0.024 L47.522,0.024 L55.122,36.687 L62.712,0.024 L73.452,0.024 Z"/>
<path id="G" d="M 91.792,25.952 L110.126,25.952 L110.126,44.286 L110.131,44.286 C110.131,54.413 101.918,62.626 91.792,62.626 C81.665,62.626 73.458,54.413 73.458,44.286 L73.458,44.286 L73.458,18.359 L73.453,18.359 C73.453,8.233 81.665,0.025 91.792,0.025 C101.913,0.025 110.126,8.233 110.126,18.359 L99.385,18.359 C99.385,14.169 95.981,10.765 91.792,10.765 C87.597,10.765 84.198,14.169 84.198,18.359 L84.198,44.286 L84.198,44.286 C84.198,48.481 87.597,51.880 91.792,51.880 C95.981,51.880 99.380,48.481 99.385,44.291 L99.385,44.286 L99.385,36.698 L91.792,36.698 L91.792,25.952 L91.792,25.952 Z"/>
</g>
</defs>
<path id="base" fill="#000" d="M8.5,150 H291.5 V250 C291.5,273.5 273.5,291.5 250,291.5 H50 C26.5,291.5 8.5,273.5 8.5,250 Z"/>
<g stroke-width="38" stroke="#000">
<g id="svgstar" transform="translate(150, 150)">
<path id="svgbar" fill="#ffb13b" d="M-84.1487,-15.8513 a22.4171,22.4171 0 1 0 0,31.7026 h168.2974 a22.4171,22.4171 0 1 0 0,-31.7026 Z"/>
<use xlink:href="#svgbar" transform="rotate(45)"/>
<use xlink:href="#svgbar" transform="rotate(90)"/>
<use xlink:href="#svgbar" transform="rotate(135)"/>
</g>
</g>
<use xlink:href="#svgstar"/>
<use xlink:href="#base" opacity="0.85"/>
<use xlink:href="#SVG"/>
</svg>
</div>
</div>
【问题讨论】:
-
对于 SVG 等待 stackoverflow.com/users/1038015/robert-longson 他肯定会得到答案 ;)
-
我觉得这将以 flexbox 问题结束
-
嘿嘿嘿@temaniafif!我不这么认为,因为如果你删除两个 svg 项目,你会看到交叉轴折叠到 0 大小,正如 flexbox 所预期的那样,当 align-items 没有拉伸时。当您在每个中引入 SVG 时,两者突然开始表现不同。方向:列的宽度仍保持为 0,但高度尊重方向:行的 svg 纵横比。对此完全感到困惑。 svg 规范是巨大的
-
我发现这篇文章对于理解 SVG 坐标和调整大小特别有用 sarasoueidan.com/blog/svg-coordinate-systems
-
如果你添加这个 css 块会变得非常有趣:
svg { width: auto; height: 100%; }如果你调整窗口大小,SVG 将会增长。