环绕式CSS边框动画

4
我正在尝试使用纯CSS实现环绕式边框动画。目前的方法是使用:before和:after伪元素进行大小更改。一个用于顶部和右侧边框,另一个用于底部和左侧边框。但是,由于宽度和高度的差异,每个边框的时间相等,但由于宽度比高度大得多,因此看起来速度要快得多,导致出现奇怪的效果。您如何在不知道div大小的情况下修复它?同时,欢迎任何使用SCSS /原始CSS获得相同动画的不同方法。看起来我无法更改SO片段的大小,但如果您想玩一下,这里是一个codepen链接:https://codepen.io/lollobaldo2000/pen/KKPazNw?editors=1100

* {
  box-sizing: border-box;
}

body {
  background: black;
}

.square {
  background: black;
  display: block;
  width: 500px;
  height: 200px;
  position: absolute;
  top: 50%;
  left: 50%;
  margin: -100px auto auto -250px;
}
.square:before, .square:after {
  content: '';
  width: 0%;
  height: 0%;
  position: absolute;
  border: 1px solid #FB0;
  animation-fill-mode: forwards;
}
.square:before {
  left: 0;
  top: 0;
  border-bottom: 0;
  border-left: 0;
  animation: btm 2s ease-in forwards;
}
.square:after {
  visibility: hidden;
  right: 0;
  bottom: 0;
  border-top: 0;
  border-right: 0;
  animation: btm 2s 2s ease-out forwards;
}

@keyframes btm {
  0% {
visibility: visible;
width: 0;
height: 0;
  }
  50% {
width: 100%;
height: 0;
  }
  100% {
width: 100%;
height: calc(100% - 1px);
visibility: visible;
  }
}
<div class="square">
</div>

2个回答

6

通过使用一个小的SVG来定义边框,然后动画 stroke-dashoffset,您可以轻松实现此操作。

.square {
  display:inline-block;
  margin:5px;
  width:200px;
  height:100px;
  position:relative;
  vertical-align:top;
}


svg {
 overflow:visible;
 position:absolute;
 top:0;
 left:0;
 width:100%;
 height:100%;
}

rect {
 fill:transparent;
 stroke:#FB0;
 stroke-dasharray: 1000;
 stroke-dashoffset: 1000;
 animation:change 5s linear forwards;
}

@keyframes change {
  to {
   stroke-dashoffset: 0;
  }
}

body {
  background: black;
}
<div class="square">
<svg  preserveAspectRatio="none"><rect x=0 y=0 width=100% height=100% /></svg>
</div>


<div class="square" style="width:100px;">
<svg  preserveAspectRatio="none"><rect x=0 y=0 width=100% height=100% /></svg>
</div>


<div class="square" style="height:250px;">
<svg  preserveAspectRatio="none"><rect x=0 y=0 width=100% height=100% /></svg>
</div>


太好了。有什么办法可以将它作为背景添加,以便在我的HTML中没有<svg>标签? - Lorenzo
@Lorenzo,你可以将SVG添加为背景,但是你将无法在背景上触发动画。你必须将其作为元素才能运行动画。 - Temani Afif
点赞,因为它指引了我正确的方向。我进行了一些探索,结果发现有多种方法可以将<style>包含在SVG中。请看我添加的答案。 - Lorenzo

1
正如 @Temani 所说,SVG 是可行的方法。您可以将包括动画在内的样式直接插入到 SVG 中。我将其添加为内联 url()。请注意,在某些字符中需要进行转义:

body{background:black;}
.square{
width: 300px;
height:100px;
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg'%3e%3cstyle%3e rect %7b fill: transparent; stroke: %23FF9800; stroke-dasharray: 1000; stroke-dashoffset: 1000; animation:change 3s ease-in-out forwards; stroke-width: 5;%7d %40keyframes change %7b to %7b stroke-dashoffset: 0;%7d %7d %3c/style%3e%3crect width='100%25' height='100%25' /%3e%3c/svg%3e ");
}
<div class="square">
</div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接