以下是SVG2 specification的一些相关摘录:

8.3. The initial viewport

除非满足以下条件,否则初始视口的宽度必须是最外层svg元素上宽度表示属性的值:SVG内容是通过引用嵌入的单独存储的资源(例如HTML中的对象元素) ,或SVG内容嵌入在包含文档中;并使用CSS设置引用元素或包含文档的样式;并且在引用元素(例如,对象元素)上或在包含文档的最外面的svg元素上指定的CSS兼容定位属性足以 Build 视口的宽度 . 在这些条件下,必须通过定位属性 Build 视口的宽度 . [同样适用于身高]

8.12. Intrinsic sizing properties of SVG content

必须使用以下算法计算固有宽高比 . 如果算法返回null,则没有固有的宽高比 . 如果svg元素上的宽度和高度大小属性都是绝对值:返回宽度/高度如果SVG视图处于活动状态:让viewbox成为活动SVG视图定义的视图框返回viewbox.width / viewbox.height如果viewBox on正确指定了svg元素:让viewbox成为svg元素上viewBox属性定义的视图框返回viewbox.width / viewbox.height返回null


The Code

我在svg中制作了一个汉堡包按钮,我试图弄清楚它的视口尺寸究竟是怎么回事,因为我们用svg表示属性和CSS指定它 .

svg#ham-btn {
  margin: 2rem;
  border: 1px solid black;
  fill: #383838;
  width: 10vw;
  height: auto;
}
<svg id="ham-btn" width="107.5px" height="80px" viewBox="0 0 80 80" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg">
  <style>
    #ham-btn {
      cursor: pointer;
    }
    #ham-btn rect {
      transform-box: fill-box;
      transform-origin: 50% 50%;
      outline: 1px solid transparent;
      transition: transform 0.2s;
    }
    #ham-btn:hover #r2 {
      transform: translate(118%, 0);
    }
    #ham-btn:hover #r1 {
      transform: translate(0%, 191.66%) rotate(36deg) scaleX(1.1);
    }
    #ham-btn:hover #r3 {
      transform: translate(0%, -191.66%) rotate(-36deg) scaleX(1.1);
    }
    
  </style>
  <rect id="r3" x="0" y="71.25%" width="100%" height="15%" rx="5%" />
  <rect id="r2" x="0" y="42.5%" width="100%" height="15%" rx="5%"/>
  <rect id="r1" x="0" y="13.75%" width="100%" height="15%" rx="5%" />
</svg>

The Question

我的解决方案取决于视口比率(107.5 / 80)与 viewBox 比率(80/80)不同的事实 . 这是导致居中的原因(通过 preserveAspectRatio ) . 如果更改视口宽高比,则会破坏解决方案 .

因此,我的问题是:为什么CSS中的设置尺寸与直接在svg中设置它不一样?为什么CSS高度和宽度似乎没有覆盖SVG中指定的高度和宽度(因为上面的第一个规范摘录表明它应该) .

My Best Guess

  • svg width / height 表示属性定义了svg元素的内在宽高比(从上面的第二个规范摘录中可以看出)

  • 然后,CSS完全覆盖了宽度和高度(从上面的第一个规范摘录中可以看出)

  • 这解释了为什么有必要在CSS中明确地将高度设置为 auto . 如果我们没有这样做,svg的高度将回落到指定的80px,从而扭曲形状

关于这个猜测是否正确的任何想法?