一个奇奇怪怪的边框实现

许久不见,甚是想念。一直没想好水点啥,刚好就找到一个,那就弄~

预览效果

实现思路

猛地一看,太猛了!这玩意能弄出来?是的,可以。

遇到任何复杂的图形,我们都要想着进行拆分——能不能将它拆分为几个部分呢?

对于这个图案,我们也能发现一些规律:四周的圆头都是圆拼接成的,间隔了个透明的而已。那么如何将一张图挖成这个样子就是我们要解决的问题。

第一步:打底

我们开始不妨直接给一个底,有个基础背景,以方便我们后续创作。

background: #458eff;

第二步:挖孔

想得到目标图案,我们其实可以先将整个蓝色背景进行挖掉一些圆形,然后将四周用实色填充。

说干就干,我们直接先将整体挖空,我们直接使用mask进行遮罩即可。

mask: radial-gradient(var(--s), 
      #0000 calc(100% - 1px), #000) 
      var(--s) var(--s) / 
      calc(2 * var(--s)) calc(2 * var(--s));

其中 --s 为我们定义圆的尺寸。得到下图左图。

我们发现它自己填满了整个背景,我们需要的是它只覆盖我们 padding 样式的区域,因此,我们给它添加一个限制

mask: radial-gradient(var(--s), 
      #0000 calc(100% - 1px), #000) 
      var(--s) var(--s) / 
      calc(2 * var(--s)) calc(2 * var(--s)) padding-box;

这样,就达到了我们的需求,见下右图。



第三步:镶边

那么接下来我们直接将上述得到图形的四周用实色圆形填充即可。

单独的填充圆先看看

mask: radial-gradient(var(--s), #000 100%, 
      #0000 calc(100% + 1px)) 0 0 /
      calc(4 * var(--s)) calc(4 * var(--s));

此时图形如下图左侧所示。

那么我们直接将此图层放到挖空图层上层加以覆盖,相当于一个拼接。此时结果如下右图所示。



第四步:补色

此时,基本的图形已经达到了预期,但是中间仍有一层露出来的,这个简单,我们再补一层纯色,放在最上层将其遮住即可。

mask: conic-gradient(#000 0 0) no-repeat 50% / calc(100% - 
      6 * var(--s)) calc(100% - 6 * var(--s));

它就是一个纯色的正方形,如下左图。

将其与以上遮罩层组合,即可得到最终图案,见下右图。



到这里,我滴任务完成辣~

完整代码

<img class="box" src="https://linux.do/logo-200.svg" alt="">
.box {
  --s: 30px; /* size */
  --w: 400px; /* width */
  width: round(down, var(--w), 4 * var(--s));
  aspect-ratio: 1;
  border: calc(2 * var(--s)) solid #0000;
  padding: calc(1.5 * var(--s));
  box-sizing: border-box;
  background: #458eff;
  mask: conic-gradient(#000 0 0) no-repeat 50% / calc(100% - 6 * var(--s))
      calc(100% - 6 * var(--s)),
    radial-gradient(var(--s), #000 100%, #0000 calc(100% + 1px)) 0 0 /
      calc(4 * var(--s)) calc(4 * var(--s)),
    radial-gradient(var(--s), #0000 calc(100% - 1px), #000) var(--s) var(--s) /
      calc(2 * var(--s)) calc(2 * var(--s)) padding-box;
}

:bullseye:重点再说一下 round,这个函数是根据我们给定的宽度来自适应向上还是向下自适应。例如这里我们给的是 400px ,但是我们圆的尺寸为30,因此 我们想让其能完美呈现,那么宽度就要为 30*13=390px 或者 30*14=420px

如果按照给定的尺寸,不是多了就是少了,因此我们就用round让它自己来调整,第一个参数如果是 up 那就向上取,即 420,向下就是390了。

放个codepen就结束啦!


好了,今天的内容就到此结束了!希望对大家有用。

如果可以的话,点点赞、点点认可,我想要内个:white_check_mark:


往期汇总

100 个赞

@snaily 围观大佬 大鹅太强了 :tieba_087:

5 个赞

学习了:folded_hands:

3 个赞

排列组合!

4 个赞

那你能不能就是把头像整成圆角矩形然后一圈蓝色光晕再加个没电的电池icon呀 :bili_040:

6 个赞

佬是真的厉害

4 个赞

你看他历史贴有的

4 个赞

你是否在寻找 充电特效PLUS ~ 船新版本 :grinning:

9 个赞

巨佬来啦!

7 个赞

《css从熟悉到了解》 :tieba_087:

4 个赞

大鹅老师终于开课啦!好强的大鹅巨佬!来学习学习~

3 个赞

瓜瓜巨佬!

4 个赞

大佬真强!

3 个赞

大鹅老师太强了,期待大鹅蓝勾 :tieba_013:

3 个赞

哇酷哇酷~

5 个赞

不愧是CSS之王 :star_struck:

4 个赞

这是真的把CSS玩明白了的

4 个赞

真厉害,学习了

2 个赞

大鹅真是知识渊博

2 个赞

这是高手,已经到了我看了也看不懂语法的境界了。我赶快去翻一翻文档

2 个赞