【问题标题】:SVG: how to round stroke and rectangle corners?SVG:如何圆角和矩形角?
【发布时间】:2019-11-19 00:51:13
【问题描述】:

是否可以在 SVG 中对矩形进行圆角处理,同时确保笔划符合圆角的圆度?下面的代码不起作用。

无中风:

stroke-width="0px"

<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
    <rect width="100%" height="100%" stroke="red" stroke-width="0px" rx="10px" ry="10px" stroke-linejoin="round" />
</svg>

带笔画:

stroke-width="10px"

<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
    <rect width="100%" height="100%" stroke="red" stroke-width="10px" rx="10px" ry="10px" stroke-linejoin="round" />
</svg>

笔触似乎是沿着原来的尖角而不是圆角。

【问题讨论】:

  • overflow:visible 添加到svg,你就会明白发生了什么(一半在里面,一半在外面)
  • @TemaniAfif 你对在圆角矩形上强制边框有什么建议?
  • 为什么要舍入 svg 而不是 div?
  • @NathanielFlick rect 元素充当图标的背景元素。理想情况下,我们可以使用纯 SVG,因此用户可以选择以 SVG 或光栅格式下载。

标签: html css svg


【解决方案1】:

<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
    <rect width="100%" height="100%" stroke="red" stroke-width="10px" rx="10px" ry="10px" stroke-linejoin="round" />
</svg>

宽字符串超出画布 SVG 的 svg 边框。因此,字符串被部分裁剪。

您必须减小矩形的大小以使线条可见,并将矩形的左上角向右和向下移动x="5"y="5"

<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
    <rect x="5" y="5" width="90" height="90" stroke="red" stroke-width="10px" rx="10px" ry="10px" stroke-linejoin="round" />
</svg>

更新

添加了视图框。矩形xy的坐标增加了,SVG包装在一个容器中,可以作为一个单独的块嵌入到HTML页面中。 自适应应用

.container {
width:30%;
height:30%
}
<div class="container">
<svg  viewBox="0 0 110 110" xmlns="http://www.w3.org/2000/svg">
    <rect x="10" y="10" width="90" height="90" stroke="red" stroke-width="10px" rx="10px" ry="10px" stroke-linejoin="round" />
</svg>
</div>

从图中可以看出,一个宽笔画的正方形完全在SVG画布内部

【讨论】:

  • 这可行,但似乎笔画在浏览器中的呈现不一致。在某些浏览器中,它似乎呈现在元素边框的中心,而某些浏览器则完全在里面?详情stackoverflow.com/questions/7241393/…
  • @Crashalot Stroke svg 元素始终相对于元素的边框对称显示。笔触宽度为 10 像素 - 元素外 5px 元素内 5px。在 sn-p 中,我的示例适用于 Chrome Firefox。如果其他浏览器笔画不正确,那么尝试放大视口,增加矩形`x`和y的初始坐标
  • 我认为这里的挑战是在 SVG 内部有一个自适应矩形。在您的两个示例中,您要么固定矩形的宽度/高度,要么固定比率,所以是的,它是自适应的,但始终保持正方形。我们不能有这样的东西:jsfiddle.net/9cd62hy5/1 矩形总是 100% 的 SVG 的宽度/高度。我在这里找到了使用 calc() 的解决方案:stackoverflow.com/a/51496341/8620333 但它只能在 Chrome 上找到。 (PS:在第二种情况下使用高度是没有用的,因为父级没有定义高度)
  • @Temani Afif 我回答了问题 OP Is it possible to round a rectangle in SVG while ensuring the stroke obeys the roundedness of corners? 我在第一个示例中解释了为什么圆形笔划不可见,因为它不完全适合 SVG 画布。第二个示例是关于如何在 SVG 中制作矩形或任何其他形状自适应的奖励。即:添加viewBox并删除SVG文件头中的固定宽度/高度。我总是仔细研究您对本网站参与者问题的创造性回答。我真的很喜欢你的很多答案。
  • 您完全回答了这个问题,但我认为 OP 遗漏了一些细节,因为我很确定这个问题是由于他的旧问题所面临的问题而被问到的:stackoverflow.com/q/58784579/8620333 我向他建议的地方转向 SVG,因为 CSS 解决方案有点 hacky,这就是为什么我认为响应部分(这里没有明确要求)很重要,这就是为什么他使用 100% 的高度/宽度。我添加了一个答案,因为我注意到 firefox 用 calc() 解决了这个问题,所以它应该是一个很好的解决方案(不知道其他浏览器)[谢谢你的赞美 btw]
【解决方案2】:

第一个简单的解决方案是使溢出可见并添加一些边距以纠正此问题

svg {
  overflow:visible;
  margin:5px; /*half the stroke*/
}
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
    <rect width="100%" height="100%" stroke="red" stroke-width="10px" rx="10px" ry="10px" stroke-linejoin="round" />
</svg>

<svg width="150" height="80" xmlns="http://www.w3.org/2000/svg">
    <rect width="100%" height="100%" stroke="red" stroke-width="10px" rx="10px" ry="10px" stroke-linejoin="round" />
</svg>

<svg width="100" height="200" xmlns="http://www.w3.org/2000/svg">
    <rect width="100%" height="100%" stroke="red" stroke-width="10px" rx="10px" ry="10px" stroke-linejoin="round" />
</svg>

或者你使用calc(),如下所示:

svg rect{
  height:calc(100% - 10px);
  width:calc(100% - 10px);
  x:5px;
  y:5px;
}
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
    <rect width="100%" height="100%" stroke="red" stroke-width="10px" rx="10px" ry="10px" stroke-linejoin="round" />
</svg>

<svg width="150" height="80" xmlns="http://www.w3.org/2000/svg">
    <rect width="100%" height="100%" stroke="red" stroke-width="10px" rx="10px" ry="10px" stroke-linejoin="round" />
</svg>

<svg width="100" height="200" xmlns="http://www.w3.org/2000/svg">
    <rect width="100%" height="100%" stroke="red" stroke-width="10px" rx="10px" ry="10px" stroke-linejoin="round" />
</svg>

也可以作为背景:

.box {
    background:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"  ><rect x="5" y="5" width="100%" height="100%" style="height:calc(100% - 10px);width:calc(100% - 10px)" stroke="red" stroke-width="10" rx="10" ry="10" stroke-linejoin="round" /></svg>');
    color: #fff;
    padding:25px;
    display:inline-block;
    margin: 75px 0;
}
<div class="box"> Some text here</div>

<div class="box"> text very loooooooooooong here</div>


<div class="box"> a text <br> two line here</div>

【讨论】:

  • 为什么在svg标记里定义宽/高,还要用css样式规则定义大小?内联大小不会超过 css 大小吗?
  • @Crashalot 不,CSS 一将覆盖,因为它是宽度/高度属性而不是内联宽度/高度,因此 CSS 比它更具体,您可以简单地删除属性一。您不必定义它们,我只是从第一个到第二个 sn-p 保持相同的 SVG
  • @Crashalot 相关问题,了解为什么 CSS 会覆盖属性:stackoverflow.com/a/56727105/8620333
【解决方案3】:

<svg width="400" height="180">
    <rect x="50" y="20" rx="20" ry="20" width="150" height="150"
          style="fill:red;stroke:black;stroke-width:5;opacity:0.5" />
</svg>

【讨论】:

    猜你喜欢
    • 2018-02-03
    • 2012-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多