【问题标题】:Responsively Position SVG within a Parent响应式地将 SVG 定位在父级中
【发布时间】:2018-07-22 02:38:11
【问题描述】:

我有一个 SVG 叠加层,它是一个带有一个孔的形状。无论如何我可以设置它,以便将叠加层有效地固定在右下角并保持圆圈按比例保持相同的位置,同时扩展 SVG 的其余部分以填充容器的剩余区域?

我已经设法让 SVG(看似)留在右下角,但我不知道如何让它填满容器的其余部分?我需要在不明显扭曲圆形的情况下这样做。

codepen:https://codepen.io/emilychews/pen/KQmZEd

body {
  width: 100%; 
  height: 100vh;
  padding: 0; margin: 0;
  display: flex;}

#box {
  margin: auto;
  position: relative;
  width: 33%;
  height: 200px;
  background: url(https://lorempixel.com/400/400/) center/cover;
  overflow: hidden;
}

#overlay {
position: absolute;
bottom: 0; 
right: 0;
}
<div id="box">
    <svg id="overlay" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 232.71 170.5"><g id="Layer_2" data-name="Layer 2"><g id="Layer_2-2" data-name="Layer 2-2"><path d="M0,0V170.5H232.71V0ZM187.37,148.19a23,23,0,1,1,23-23h0A23,23,0,0,1,187.37,148.19Z" transform="translate(0 0)" fill="#015668"/></g></g></svg>
</div>

【问题讨论】:

  • 我不清楚你想要的想法是什么样的,因为你只发布了“错误”的结果。请考虑在您的问题中包含样机图片。
  • @PaulLeBeau 你是对的,让我们首先说在此之前还有另一个问题,我们看到他的问题:stackoverflow.com/questions/48737295/… .. 在这里他找到了 SVG 的解决方案,他的目的是涵盖所有带有他的 SVG 的框,并保持圆圈的比例,并在 div 调整大小时始终保持在底部。换句话说,他只想通过洞看到图像

标签: html css svg responsive


【解决方案1】:

我会这样做。我将提供分步说明,以便更容易遵循“魔法”。 :)

我们的想法是使用一个简单的方形 SVG,其宽度和高度为 100x100,viewBox。然后我们可以在 viewBox 的右下角定位将成为我们未来孔的圆圈。

body {
  width: 100%; 
  height: 100vh;
  padding: 0; margin: 0;
  display: flex;}

#box {
  margin: auto;
  position: relative;
  width: 33%;
  height: 200px;
  background: url(https://lorempixel.com/400/400/) center/cover;
  overflow: hidden;
}
<div id="box">
  <svg width="100%" height="100%" viewBox="0 0 100 100">
    <rect x="0" y="0" width="100" height="100" fill="#015668"/>
    <circle cx="70" cy="70" r="20" fill="black"/><!-- the hole -->
  </svg>
</div>

然后我们使用preserveAspectRatio="xMaxYMax meet" 告诉渲染器我们想要右下角的SVG内容。

body {
  width: 100%; 
  height: 100vh;
  padding: 0; margin: 0;
  display: flex;}

#box {
  margin: auto;
  position: relative;
  width: 33%;
  height: 200px;
  background: url(https://lorempixel.com/400/400/) center/cover;
  overflow: hidden;
}
<div id="box">
  <svg width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="xMaxYMax meet">
    <rect x="0" y="0" width="100" height="100" fill="#015668"/>
    <circle cx="70" cy="70" r="20" fill="black"/><!-- the hole -->
  </svg>
</div>

下一步是使矩形变宽并从viewBox 的左侧开始,以填充 SVG 左侧的视口区域。我们将通过使其从x="-900" 开始并成为width="1000" 来做到这一点。这意味着它向左延伸比(100 宽)viewBox 多 9 倍。这应该足以满足周围最庞大的显示器的需求。

我们也会在垂直方向上做同样的事情。以防万一视口变得又高又瘦。如果您调整窗口大小使其宽度变窄,就会发生这种情况。

body {
  width: 100%; 
  height: 100vh;
  padding: 0; margin: 0;
  display: flex;}

#box {
  margin: auto;
  position: relative;
  width: 33%;
  height: 200px;
  background: url(https://lorempixel.com/400/400/) center/cover;
  overflow: hidden;
}
<div id="box">
  <svg width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="xMaxYMax meet">
    <rect x="-900" y="-900" width="1000" height="1000" fill="#015668"/>
    <circle cx="70" cy="70" r="20" fill="black"/><!-- the hole -->
  </svg>
</div>

最后,我们将其转换为遮罩,并将其应用到以相同方式填充视口的矩形。

body {
  width: 100%; 
  height: 100vh;
  padding: 0; margin: 0;
  display: flex;}

#box {
  margin: auto;
  position: relative;
  width: 33%;
  height: 200px;
  background: url(https://lorempixel.com/400/400/) center/cover;
  overflow: hidden;
}
<div id="box">
  <svg width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="xMaxYMax meet">
    <defs>
      <mask id="mymask">
        <rect x="-900" y="-900" width="1000" height="1000" fill="white" fill-opacity="0.9"/>
        <circle cx="70" cy="70" r="20" fill="black"/><!-- the hole -->
      </mask>
    </defs>
    <rect x="-900" y="-900" width="1000" height="1000" fill="#015668" mask="url(#mymask)"/>
  </svg>
</div>

最后的测试。让我们把“盒子”变大,以检查它是否正确响应。这次我们将其设置为 400px 高。尝试调整浏览器窗口的大小以检查响应能力。

body {
  width: 100%; 
  height: 100vh;
  padding: 0; margin: 0;
  display: flex;}

#box {
  margin: auto;
  position: relative;
  width: 33%;
  height: 400px;
  background: url(https://lorempixel.com/400/400/) center/cover;
  overflow: hidden;
}
<div id="box">
  <svg width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="xMaxYMax meet">
    <defs>
      <mask id="mymask">
        <rect x="-900" y="-900" width="1000" height="1000" fill="white" fill-opacity="0.9"/>
        <circle cx="70" cy="70" r="20" fill="black"/><!-- the hole -->
      </mask>
    </defs>
    <rect x="-900" y="-900" width="1000" height="1000" fill="#015668" mask="url(#mymask)"/>
  </svg>
</div>

【讨论】:

    【解决方案2】:

    我会考虑另一种想法,使用蒙版创建孔,您可以轻松控制圆的位置和大小。然后诀窍是让整个 svg 以大宽度/高度溢出以始终覆盖 div 并保持相同大小的圆圈:

    body {
      width: 100%;
      height: 100vh;
      padding: 0;
      margin: 0;
      display: flex;
    }
    
    #box {
      margin: auto;
      position: relative;
      width: 33%;
      height: 200px;
      background: url(https://lorempixel.com/400/400/) center/cover;
      overflow: hidden;
    }
    
    #overlay {
      position: absolute;
      bottom: 0;
      right: 0;
      width:1000px;
      height:1000px;
    }
    <div id="box">
      <svg  id="overlay" viewbox="0 0 400 400" >
      <defs>
        <mask id="hole">
          <rect width="100%" height="100%" fill="white"/>
          <!-- This circle is your hole -->
          <circle r="20" cx="370" cy="370" fill="black"/>
        </mask>
      </defs>
    
      <rect x=0 y=0 width=400 height=400 mask="url(#hole)" fill="green" />
        
    </svg>
    </div>

    如果你想在宽度变化时调整圆圈的大小,你可以试试这个:

    body {
      width: 100%;
      height: 100vh;
      padding: 0;
      margin: 0;
      display: flex;
    }
    
    #box {
      margin: auto;
      position: relative;
      width: 33%;
      height: 200px;
      background: url(https://lorempixel.com/400/400/) center/cover;
      overflow: hidden;
    }
    
    #overlay {
      position: absolute;
      bottom: 0;
      right: 0;
      width:100%;
    }
    <div id="box">
      <svg  id="overlay" viewbox="0 0 400 10000" >
      <defs>
        <mask id="hole">
          <rect width="100%" height="100%" fill="white"/>
          <!-- This circle is your hole -->
          <circle r="80" cx="300" cy="9900" fill="black"/>
        </mask>
      </defs>
    
      <rect x=0 y=0 width=400 height=10000 mask="url(#hole)" fill="green" />
        
    </svg>
    </div>

    而且您可以轻松获得上一个问题中所需的不透明度:

    body {
      width: 100%;
      height: 100vh;
      padding: 0;
      margin: 0;
      display: flex;
    }
    
    #box {
      margin: auto;
      position: relative;
      width: 33%;
      height: 200px;
      background: url(https://lorempixel.com/400/400/) center/cover;
      overflow: hidden;
    }
    
    #overlay {
      position: absolute;
      bottom: 0;
      right: 0;
      width:100%;
    }
    <div id="box">
      <svg  id="overlay" viewbox="0 0 400 10000" >
      <defs>
        <mask id="hole">
          <rect width="100%" height="100%" fill="white"/>
          <!-- This circle is your hole -->
          <circle r="80" cx="300" cy="9900" fill="black"/>
        </mask>
      </defs>
    
      <rect x=0 y=0 width=400 height=10000 mask="url(#hole)" fill="rgba(0,0,255,0.5)" />
        
    </svg>
    </div>

    【讨论】:

    • 嗨,谢谢@TemaniAfif,我稍后会玩这些,并标记哪个最有效。感谢您的所有帮助。
    猜你喜欢
    • 2013-09-07
    • 1970-01-01
    • 2021-07-02
    • 1970-01-01
    • 1970-01-01
    • 2018-08-23
    • 1970-01-01
    • 2013-05-24
    • 1970-01-01
    相关资源
    最近更新 更多