响应式SVG viewBox

时间:2018-12-10 03:26:31

标签: html css svg

我在SVG中创建了一个“汉堡包按钮”,如下所示。

body {
  margin: 0;
  text-align: center;
}

svg#ham-btn {
  margin: 2rem;
  border: 1px solid black;
  fill: #383838;
}
<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:hover #r1 {
      outline: 1px solid transparent;
      transition: transform 0.2s;
      transform-origin: 50% 50%;
      transform: rotate(37deg) translate(0%, 28.75%) scaleX(1.1);
    }
    #ham-btn:hover #r2 {
      transition: transform 0.2s;
      transform: translate(120%, 0);
    }
    #ham-btn:hover #r3 {
      outline: 1px solid transparent;
      transition: transform 0.2s;
      transform-origin: 50% 50%;
      transform: rotate(-37deg) translate(0%, -28.75%) 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>

问题

现在,如果要缩小按钮,必须手动将视口和viewBox的尺寸缩小相同的px。

有什么方法可以使响应速度更快?例如,通过将viewBox设为视口的百分比?

According to the spec,看来viewBox必须是<number>,因此不能是百分比。

有什么想法吗?

谢谢。


注释1

我尚未向按钮添加任何辅助功能或其他功能。这个问题是关于它的响应能力。


注释2

我知道我可以使SVG视口占其容器/浏览器视口的百分比。

不幸的是,这不能解决我的问题,因为要使此按钮正常工作,我的viewBox与视口的比例必须保持固定(否则,按钮将失去其形状)。

因此,我想将viewBox设为视口的百分比。

如果有兴趣,我的解决方案将利用以下优势:

  • viewBox比视口更宽,但高度相同
  • 因此,preserveAspectRatio用于使rect的水平居中
  • rect尺寸以viewBox的百分比

outline将解决Firefox转换后出现锯齿状的问题。


编辑:

如果对将来的访问者有帮助,请在以下位置找到最后一个按钮,包括完整的可访问性:https://codepen.io/magnusriga/pen/KrrJKa

2 个答案:

答案 0 :(得分:3)

为您的SVG CSS添加宽度和高度属性。设置宽度并自动设置高度。

body {
  margin: 0;
  text-align: center;
}

svg#ham-btn {
  margin: 2rem;
  border: 1px solid black;
  fill: #383838;
  /* percentage of viewport - height will autocalculate */
  width: 7vw;
  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:hover #r1 {
      transition: transform 0.2s;
      transform-origin: 50% 50%;
      transform: rotate(37deg) translate(0%, 28.75%) scaleX(1.1);
    }
    #ham-btn:hover #r2 {
      transition: x 0.2s;
      x: 120%;
    }
    #ham-btn:hover #r3 {
      transition: transform 0.2s;
      transform-origin: 50% 50%;
      transform: rotate(-37deg) translate(0%, -28.75%) 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>

答案 1 :(得分:1)

正如我在评论中告诉您的那样:我将删除svg元素的宽度和高度。然后在CSS中,我将SVG的宽度设置为20%。我正在将SVG的宽度设置为窗口宽度的50%。

为了保持比例,我将“汉堡包”放入了<symbol viewBox="0 0 80 80">中。在这种情况下,您再也不用preserveAspectRatio="xMidYMid meet"了。

body {
  margin: 0;
  text-align: center;
}

svg#ham-btn {
  width: 20%;
  margin:auto;
  top:0;bottom:0;left:0;right:0;
  border: 1px solid black;
  fill: #383838;
  position:absolute; 
}
<svg id="ham-btn" viewBox="0 0 107.5 80" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg">
  <style>
    #ham-btn {
      cursor: pointer;
    }
    #ham-btn:hover #r1 {
      outline: 1px solid transparent;
      transition: transform 0.2s;
      transform-origin: 50% 50%;
      transform: rotate(37deg) translate(0%, 28.75%) scaleX(1.1);
    }
    #ham-btn:hover #r2 {
      transition: transform 0.2s;
      transform: translate(120%, 0);
    }
    #ham-btn:hover #r3 {
      outline: 1px solid transparent;
      transition: transform 0.2s;
      transform-origin: 50% 50%;
      transform: rotate(-37deg) translate(0%, -28.75%) scaleX(1.1);
    }
    
  </style>
  <symbol id="s" viewBox="0 0 80 80"> 
  <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%" />
  </symbol>  
  
  <use xlink:href="#s"  width="80" x="13.75"/>
</svg>