带圆角和缩进曲线边框的正方形

Square with rounded corners and indented curved border

我想知道是否可以在纯 CSS 中制作一个带有圆角和缩进边框的正方形。

目前我有这个:

#custom-square {
     position: relative;
     display: block;
     width: 75px;
     height: 75px;
     border: 2px solid #8A6EF1;
     border-radius: 10px;
     background-color: white;
}

考虑到对齐 的麻烦和代码量,SVG 似乎更合适。选择 svg 的其他几个原因是:

  • 控制路径(颜色、宽度、曲线...)
  • 用纯色、渐变或图像控制填充
  • 更少的代码
  • 您可以在非纯背景(渐变或图像)上显示它
  • 维护用户交互的形状边界(悬停、单击...)

这是一个使用 inline svg with a path element.
的基本示例 曲线用 Cubic Bezier curves :

绘制

svg{width:30%;}
<svg viewbox="0 0 10 10">
  <path d="M1.5 0.5 Q5 1 8.5 0.5 Q9.5 0.5 9.5 1.5 Q9 5 9.5 8.5 Q9.5 9.5 8.5 9.5 Q5 9 1.5 9.5 Q0.5 9.5 0.5 8.5 Q1 5 0.5 1.5 Q0.5 0.5 1.5 0.5z" 
        fill="none" stroke-width="0.2" stroke="#8A6FF2" />
</svg>

此模型草稿已尽可能接近纯 CSS,但仍需要嵌套 div。您需要调整前/后圆的大小/半径。

Pen

div {

  position: absolute;
  top: 100px;
  left: 100px;
  width: 100px;
  height: 100px; 
  border: 4px solid purple;
  border-radius: 30px;
  //overflow: hidden;
  box-sizing: border-box;

  &:before {
    position: absolute;
    top: -4px;
    left: -94px;
    content: ' ';
    width: 100px;
    height: 100px;
    border: 4px solid purple;
    border-radius: 50px;
    box-sizing: border-box;
    background-color: white;
    clip: rect(0px, 100px, 100px, 90px);
  }

  &:after {
    position: absolute;
    top: -4px;
    right: -94px;
    content: ' ';
    width: 100px;
    height: 100px;
    border: 4px solid purple;
    border-radius: 50px;
    box-sizing: border-box;
    background-color: white;
    clip: rect(0px, 10px, 100px, 0px);
  }
}

div > div {
  position: absolute;
  top: -4px;
  left: -4px;
  transform: rotate(90deg);
  border-color: transparent;
}

SVG 可能是这里的方式,但这里有一个非常接近纯 CSS 的近似值。通过增加外圈的大小可以做得更好。

#middle {
  width: 96px;
  height: 96px;
  border-radius: 10px;
  background-color: green;
  border: 2px solid #8A6EF1;
}
.outside {
  width: 100px;
  height: 100px;
  position: relative;
  overflow: hidden;
  margin: 0;
  padding: 0;
}
.cutout {
  width: 96px;
  height: 96px;
  border-radius: 50%;
  background-color: white;
  border: 2px solid #8A6EF1;
}
#top {
  top: -100px;
  height: 10px;
}
#right {
  top: -110px;
  left: 90px;
  width: 10px;
}
#bottom {
  top: -120px;
  height: 10px;
}
#left {
  top: -220px;
  width: 10px;
}
#top > .cutout {
  margin-top: -90px;
}
#left > .cutout {
  margin-left: -90px;
}
<div id="wrapper">
  <div id="middle">
  </div>
  <div id="top" class="outside">
    <div class="cutout">
    </div>
  </div>
  <div id="right" class="outside">
    <div class="cutout">
    </div>
  </div>
  <div id="bottom" class="outside">
    <div class="cutout">
    </div>
  </div>
  <div id="left" class="outside">
    <div class="cutout">
    </div>
  </div>
</div>

另一种创建此边框的纯 CSS 方法是使用 border-image 属性。所需要的只是创建一个具有所需边框形状的图像,并使用 border-image-source 属性.

将其设置为一个元素

.shape.large {
  height: 300px;
  width: 300px;
  border-image-source: url(http://i.stack.imgur.com/Qkh6A.png);
  border-image-width: 34px; /* the width of the border portions in the image - refer to image at the end of the answer for the exact portion details*/
  border-image-slice: 34; /* equal to border-image-width */
  border-width: 34px; /* equal to border-image-width */
}
.shape.small {
  height: 100px;
  width: 100px;
  border-image-source: url(http://i.stack.imgur.com/Mra4B.png);
  border-image-width: 14px;
  border-image-slice: 14;
  border-width: 14px;
}
.shape.small.fill {
  background: aliceblue content-box;
  border-image-source: url(http://i.stack.imgur.com/Ovj03.png);
  border-width: 14px;
}

/* Just for demo */

body {
  background: url(http://lorempixel.com/800/800/abstract/2);
}
.shape.small {
  float: left;
}
.shape.large {
  clear: both;
}
<div class='shape small'>Some content</div>
<div class='shape small fill'>Some content</div>
<div class='shape large'>Some content</div>

At present this method is definitely not much advantageous compared to SVG but it is an option and in my opinion is better than the other CSS only approaches that are possible.

这种方法的优点是:

  • 极少且复杂度低的代码。
  • 更好地控制曲线及其半径(与 SVG 一样),因为可以单独创建具有所需边界曲率的图像。
  • 可以放置在图像或渐变背景之上。
  • 可以在不支持它的浏览器中优雅地降级(变成实心方形边框)。

缺点是:

  • 容器仍然是正方形,因此 hover 与 SVG 不同,效果不会受限于形状的边界。
  • 向形状添加纯色填充是可能的(通过使用图像的填充版本),但是添加渐变或图像填充很棘手,因为边框仍然是块(也就是说,边框的两边都有透明区域)曲线)。
  • 输出是有响应的,但随着尺寸增加或减少超过阈值,形状开始看起来有点压缩或拉伸。所以,这更适合基于断点的设计。
  • browser support 不错,但也不是很好。它适用于 Chrome、Firefox、Safari、Opera 和 IE11+。

边框图像宽度的计算:

边框区域的宽度或高度(变为border-image-width)只是下图中突出显示部分的宽度。