SVG内容的固有大小调整属性

时间:2018-10-03 06:55:55

标签: html css css3 svg flexbox

我正在为SVG元素的固有大小而苦苦挣扎。

根据SVG规范第8.12. Intrinsic sizing properties of SVG content章,我们知道:

  

要在包含CSS格式的宿主文档中添加SVG,请   必须计算具体对象的大小。具体对象尺寸必须   使用默认大小调整算法进行计算

作为“默认大小调整算法”的输入,我们在同一部分中阅读:

  

指定的大小必须根据所用的   svg元素的宽度和高度大小属性。

那:

  

内部尺寸也必须根据宽度和   高度调整属性。如果未指定宽度或高度,   使用的值为初始值“ auto”。 “自动”和百分比   长度不得用于确定固有宽度或固有宽度   高度。

因此,如果没有在最外面的svg元素上设置widthheight,则我们具有固有尺寸 width / < em> height )作为auto(建议不要这样做)。 Default Sizing Algorithm的相关部分:

  

如果指定的大小没有限制(没有宽度/高度):

     
      
  1. 如果对象具有固有的高度或宽度,则将解析其大小   好像其固有大小是指定大小一样。
  2.   
  3. 否则,将其大小解析为针对默认对象大小的包含约束
  4.   

最后,来自8.3. The initial viewport

  

初始视口的宽度,必须为该宽度的值   最外层svg元素上的presentation属性...

尽管上面有第一个粗体警告,但在最外面的svg元素上定义widthheight表示属性是正常的。像Adobe Illustrator这样的程序通常会忽略这些属性,而只定义一个viewBox

我的问题:

在规范中我可以找到svg元素的 width height ,如果没有width和{{1 }}上设置的属性?

而且,在同一情况下(仅给定一个svg元素),视口尺寸将是什么?


作为旁注,来自css-sizing-3 4. Intrinsic Size Determination

  

对于具有固有长宽比但没有固有尺寸的盒子:

     

如果在线轴上的可用空间是确定的,请使用拉伸   适合该大小作为内联大小并计算块大小   使用宽高比。


某些代码

展示了我无法理解的行为(即,在两种弹性盒情况下如何计算尺寸)。

注意:当按列布置时,弹性项目的宽度变为零。 (这与 SVG 有关,而不与 flexbox 有关)。

height
.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;
}

2 个答案:

答案 0 :(得分:2)

body {
  box-sizing: border-box;
}

.c1 {
  display: flex;
  flex-flow: column nowrap;
}

.c1 .i1 {
  flex: 0 1 100px;
  border: 1px solid red;
}

.c2 {
  display: flex;
  flex-flow: row nowrap;
}

.c2 .i2 {
  flex: 0 1 100px;
  border: 1px solid blue;
}
<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>


<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>

"The ‘viewBox’ attribute, in conjunction with the ‘preserveAspectRatio’ attribute, provides the capability to stretch an SVG viewport to fit a particular container element."

.i2元素的宽度大约为100px。内部的svg会缩放以适合可用宽度。

.i1元素的宽度为可用空间的100%。内部的svg会缩放以适合.i1的可用宽度。

.i1.i2元素的宽度由flexbox布局决定。如果您删除.i1.i2元素内的svg:

  • .i2将折叠:默认情况下,空元素的高度为0。宽度为100px(由flex基础确定)
  • .i1不会折叠,因为其高度由flex基础(100px)确定,而其宽度默认为100%。

答案 1 :(得分:1)

SVG元素被视为替换元素,并遵守大小不定的替换元素300px x 150px的规则。

您可以在CSS3规范中找到相关的规范语言:

https://www.w3.org/TR/css-sizing-3/

  

对于没有固有长宽比的盒子:如果可用空间为   确定合适的尺寸,使用拉伸配合   尺寸。

     

否则,如果框具有确定的非零最小尺寸   (最小宽度/最小高度),请使用该尺寸。

     

否则,使用300px作为宽度,和/或150px作为高度,   需要。