首页 > 解决方案 > 如何为边框设置动画,使其从头到尾缓慢显示

问题描述

我想为边框设置动画缓慢显示,例如Codepen,但有一些区别:

一段简单的代码看起来像这样

<div class="boxes">
  <div class="row">
    <div
      class="col-lg-6"
      data-aos="zoom-in-right"
      data-aos-duration="800"
    >
      <div class="right-box left">
        <h2>Heading1.</h2>
        <p>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit.
          Nulla in erat et quam semper convallis. Phasellus vel nisl
          id leo suscipit molestie. Sed nec dignissim urna. Donec
          sit amet tortor nulla. Etiam tempus dui id ipsum commodo,
          et laoreet tortor luctus. Ut dapibus.
        </p>
      </div>
    </div>
    <div
      class="col-lg-6"
      data-aos="zoom-in-left"
      data-aos-duration="800"
    >
      <div class="left-box">
        <img
          src="https://via.placeholder.com/650x430"
          class="img-fluid"
          alt=""
        />
      </div>
    </div>
  </div>
</div>

但要详细查看,请查看此 jsfiddle 链接https://jsfiddle.net/ah0rokpj/1/ 请以全视图或更高屏幕尺寸查看此 jsfiddle,否则不会显示。我希望那个石灰边界是动画的。

在此处输入图像描述

我希望它像图像一样被动画化。

标签: javascripthtmlcss

解决方案


使元素的边框看起来有动画效果的一种方法是通过逐渐缩小覆盖每个边框的 5px 宽(或高,取决于哪个边框)100% 宽的元素,依次逐渐显露边框。

此代码段通过为元素上的 after 伪元素设置动画来实现这一点,同时将一个接一个的边框设置为所需的最终颜色。

您可以将此片段中的类movingBorder 放到其他元素上以获得移动边框效果。

.movingBorder {
  width: 60vw;
  height: 60vh;
  border: solid 5px lime;
  position: relative;
  background: pink;
  animation: changeBorders 5s linear;
}

@keyframes changeBorders {
  0% {
    border: solid 5px white;
    border-left: solid 5px lime;
  }
  25% {
    border: solid 5px white;
    border-left: solid 5px lime;
  }
  25.02% {
    border: solid 5px white;
    border-left: solid 5px lime;
    border-bottom: solid 5px lime;
  }
  50% {
    border: solid 5px white;
    border-left: solid 5px lime;
    border-bottom: solid 5px lime;
  }
  50.02% {
    border: solid 5px white;
    border-left: solid 5px lime;
    border-bottom: solid 5px lime;
    border-right: solid 5px lime;
  }
  75% {
    border: solid 5px white;
    border-left: solid 5px lime;
    border-bottom: solid 5px lime;
    border-right: solid 5px lime;
  }
  75.02% {
    border: solid 5px lime;
  }
}

.movingBorder::after {
  width: 5px;
  background-color: white;
  height: 0px;
  position: absolute;
  bottom: 0;
  left: -5px;
  z-index: 1;
  animation: movedown 5s linear;
  animation-fill-mode: forwards;
  content: '';
  display: inline-block;
}

@keyframes movedown {
  0% {
    height: calc(100% + 10px);
    width: 5px;
    bottom: -5px;
    left: -5px;
  }
  25% {
    height: 5px;
    width: 5px;
    bottom: -5px;
    left: -5px;
  }
  25.01% {
    height: 5px;
    width: calc(100% + 10px);
    bottom: -5px;
    left: -5px;
  }
  50% {
    height: 5px;
    width: 0%;
    left: 100%;
    bottom: -5px;
  }
  50.01% {
    height: calc(100% + 10px);
    width: 5px;
    left: 100%;
    bottom: -5px;
  }
  75% {
    height: 0;
    width: 5px;
    left: 100%;
    bottom: 100%;
  }
  75.01% {
    height: 5px;
    width: calc(100% + 10px);
    left: 0%;
    bottom: 100%;
  }
  99.01% {
    height: 5px;
    width: 0;
    left: 0;
    bottom: 100%;
  }
}
<div class="movingBorder" style="background: pink; width: 60vw; height: 60vh;"></div>

更新:以上适用于方形边框,但要求是设置了半径的边框。此代码段将 after 元素放在最初具有此形状的边框(位于 before 伪元素上)上:

在此处输入图像描述

这一步向左移动,逐渐露出石灰边界的顶部。然后左边部分设置为透明,伪元素向右移动,逐渐露出底部边框。

注意:在完整页面中运行此代码段以查看效果。动画延迟 10 秒,因此您有时间执行此操作(否则动画在您到达之前已经完成)。

* {
  margin: 0px;
  padding: 0px;
  list-style: none;
  border: none;
  text-decoration: none;
  outline: none;
}

::-webkit-input-placeholder {
  color: inherit;
  opacity: 1;
}

:-ms-input-placeholder {
  color: inherit;
  opacity: 1;
}

::placeholder {
  color: inherit;
  opacity: 1;
}

html,
body {
  height: 100%;
}

.col-lg- {}

.col-md- {}

.col-sm- {}

.col- {}

.img-fluid {}

.container-fluid {}

.justify-content-center {}

.row {}

.my-auto {}

.p0 {}

.container {
  width: 100%;
  max-width: 1170px;
}

.container-fluid {
  width: 100%;
  max-width: 1440px;
}

@media (max-width: 1199px) {
  .container {
    width: 100%;
    max-width: 100%;
  }
}


/*** ### Section One ### ***/

.section-one {
  position: relative;
  background: #ffffff;
}

.section-one h2 {
  color: #000000;
  font-size: 32px;
  margin: 0px 0px 10px 0px;
  padding: 0px;
  font-family: "AzoSans-Medium";
}

.section-one p {
  color: #000000;
  font-size: 16px;
  margin: 10px 0px;
  padding: 0px;
  font-family: "AzoSans-Regular";
}

.section-one .boxes {
  position: relative;
  margin-top: 75px;
}

.section-one .boxes:last-child {
  margin-bottom: 100px;
}

.section-one .boxes .left-box {
  position: relative;
  margin: 25px 0px 0px 0px;
  z-index: 3;
}

.section-one .boxes .left-box img {
  width: 100%;
}

.section-one .boxes .right-box {
  position: relative;
  margin: 25px 0px 0px 0px;
  height: 100%;
  z-index: 2;
}

.section-one .boxes .right-box:before,
.section-one .boxes .right-box::after {
  position: absolute;
  content: "";
  top: 50px;
  left: -30px;
  right: 0px;
  bottom: 25px;
  z-index: -2;
  /* so we can have another pseudo element overlaying it */
}

.section-one .boxes .right-box:before {
  border: 1px solid lime;
}

.section-one .boxes .right-box.left h2 {
  text-align: left;
}

.section-one .boxes .right-box.left:before,
.section-one .boxes .right-box.left::after {
  left: 0px;
  right: -30px;
}

.section-one .boxes .right-box.left:before {
  border-right: none;
  border-radius: 250px 0px 0px 250px;
}

.section-one .boxes .right-box::after {
  width: 200%;
  height: 100%;
}

.section-one .boxes .right-box.left::after {
  background-position: 0 0, 100% 75%;
  background-size: calc(50% + 30px) 100%, 50% 50%;
  background-repeat: no-repeat no-repeat, no-repeat no-repeat;
  background-image: linear-gradient(white, white), linear-gradient(white, white);
  animation: left 10s ease-in-out;
  animation-fill-mode: forwards;
  animation-delay: 10s;
  /* just to give time to go full screen on SO snippet! */
}

@keyframes left {
  0% {
    background-image: linear-gradient(white, white), linear-gradient(white, white);
    transform: translateX(0);
  }
  49.99% {
    background-image: linear-gradient(white, white), linear-gradient(white, white);
  }
  50% {
    background-image: linear-gradient(transparent, transparent), linear-gradient(white, white);
    transform: translateX(-50%);
  }
  99.99% {
    background-image: linear-gradient(transparent, transparent), linear-gradient(white, white);
    transform: translateX(0);
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}

.section-one .boxes .right-box.right h2 {
  text-align: right;
}

.section-one .boxes .right-box.right:before {
  border-left: none;
  border-radius: 0px 250px 250px 0px;
}

.section-one .boxes .right-box h2 {
  padding: 50px 0px 20px 0px;
}

.section-one .boxes .right-box p {
  display: block;
  margin: 15px auto;
  width: 100%;
  max-width: 355px;
  text-align: justify;
}

.section-one .boxes .action-btn {
  position: relative;
  text-align: right;
}

@media (max-width: 1199px) {
  .section-one h2 {
    font-size: 28px;
  }
  .section-one p {
    font-size: 15px;
  }
  .section-one .boxes {
    position: relative;
    margin-top: 50px;
  }
  .section-one .boxes:last-child {
    margin-bottom: 75px;
  }
  .section-one .boxes .right-box:before {
    left: -30px;
  }
  .section-one .boxes .right-box.left h2 {
    text-align: left;
  }
  .section-one .boxes .right-box.left:before {
    border-radius: 200px 0px 0px 200px;
  }
  .section-one .boxes .right-box.right h2 {
    text-align: left;
  }
  .section-one .boxes .right-box.right:before {
    border-radius: 0px 200px 200px 0px;
  }
  .section-one .boxes .right-box h2 {
    padding: 50px 0px 15px 0px;
  }
  .section-one .boxes .right-box p {
    display: block;
    margin: 15px auto;
    width: 100%;
    max-width: 355px;
    text-align: justify;
  }
  .section-one .boxes .action-btn {
    position: relative;
    text-align: right;
  }
}

@media (max-width: 991px) {
  .section-one h2 {
    font-size: 25px;
  }
  .section-one .boxes {
    position: relative;
    margin-top: 10px;
  }
  .section-one .boxes:last-child {
    margin-bottom: 30px;
  }
  .section-one .boxes .right-box:before {
    display: none;
  }
  .section-one .boxes .right-box.right:before {
    display: none;
  }
  .section-one .boxes .right-box h2 {
    padding: 0px 0px 15px 0px;
    margin: 0px;
  }
  .section-one .boxes .right-box p {
    display: block;
    margin: 0px auto 15px auto;
    width: 100%;
    max-width: 100%;
    text-align: justify;
  }
  .section-one .boxes .action-btn {
    position: relative;
    text-align: right;
  }
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">


<section class="section-one">
  <div class="container">
    <div class="row">
      <div class="col-lg-12">
        <div class="boxes">
          <div class="row">
            <div class="col-lg-6 aos-init" data-aos="zoom-in-right" data-aos-duration="800">
              <div class="right-box left">
                <h2>Heading1.</h2>
                <p>
                  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla in erat et quam semper convallis. Phasellus vel nisl id leo suscipit molestie. Sed nec dignissim urna. Donec sit amet tortor nulla. Etiam tempus dui id ipsum commodo, et laoreet tortor luctus.
                  Ut dapibus.
                </p>
              </div>
            </div>
            <div class="col-lg-6 aos-init" data-aos="zoom-in-left" data-aos-duration="800">
              <div class="left-box">
                <img src="https://via.placeholder.com/650x430" class="img-fluid" alt="">
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</section>


<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>

显然,当文本位于图像右侧时,必须添加等效的 CSS。


推荐阅读