简体   繁体   中英

How to animate border so that it displays slowly from start to finish

I want to animate a border and show it slowly , something like this Codepen , with some differences:

  • Not removing the old line but it needs to be shown something like that.

  • The color should not be neon just plain border

  • It should be animated only once without repetition.

A simple chunk of code looks like this

<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>

But to take a detail look please check this jsfiddle link https://jsfiddle.net/ah0rokpj/1/ Please, view this jsfiddle in full view or in higher screen size , else it won't be shown. I want that lime border to be animated.

在此处输入图像描述

I want this to be animated as in image.

A way of making the border of an element looking animated is to gradually unveil the borders in turn by gradually shrinking a 5px wide (or high depending on which border) 100% wide element that is overlaying each border.

This snippet does this by animating the after pseudo element on the element and at the same time putting one border after another into the required final color.

You can put the class movingBorder from this snippet onto other elements to get the moving border effect.

 .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>

UPDATE: the above works for a square border but the requirement was for a border with radius set. This snippet puts an after element over the border (which is on the before pseudo element) which has this shape initially:

在此处输入图像描述

This moves left gradually revealing the top part of the lime border. Then the left part is set to transparent and the pseudo element moved right, gradually revealing the bottom part of the border.

NOTE: run this snippet in Full page to see the effect. The animation delays for 10 seconds so you have time to do that (otherwise the animation has finished before you've got there).

 * { 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>

Obviously equivalent CSS has to be added for when the text is to the right of the image.

You could "trick" the effect if your background-color is going to be white or solid color.

Just put a box above the element with the border slightly wider and higher, then make the animation to move this element away.

Like this:

 * {box-sizing:border-box;}.parent { border:4px solid red; height:200px; border-radius:100px; position:relative; }.text { width:80%; margin:0 auto; position:relative; top:50%; transform:translateY(-50%); }.div1 { position:absolute; background-color:#fff; border:4px solid #fff; height:calc(100% + 20px); width:calc(100% + 20px); top:calc(0% - 10px); left:calc(0% - 10px); animation-name: border; animation-duration: 5s; animation-fill-mode:forwards; } @keyframes border { 0% { left:calc(0% - 10px); } 100% { left:calc(100% + 10px ); } }
 <div class="parent"> <div class="text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut eget ligula dictum, malesuada tortor vel, gravida velit. Pellentesque eget gravida quam. Nam sit amet massa aliquet, auctor libero dapibus, vehicula nunc. Sed ullamcorper, est id luctus facilisis, velit nibh semper nibh, ac tempus arcu velit ac metus. Donec ultricies ex id pellentesque ultrices. Vivamus rutrum, nulla quis bibendum fringilla, augue massa facilisis ipsum, id facilisis metus nisi nec eros.</div> <div class="div1"></div> </div>

You can move the div containing the text below the other div (div1) if you want the text not to be included in the animation.

 .col-md-12{ padding:30px;}.row-1{ background-color: antiquewhite; }.box{ position: relative; transition: 500ms ease; }.inner-box{ transition: 500ms ease; }.box:before { position: absolute; width: 0%; height: 2px; opacity:1; content: ''; background: rgb(218, 9, 9); top: -2px; left: 0px; transition: 100ms width ease 300ms; -web-kit-transition: 100ms width ease 300ms; animation: border-animation-width 1s; animation-fill-mode: forwards; }.box:after { position: absolute; width: 2px; height: 0%; opacity:0; content: ''; background: rgb(199, 21, 21); top: -2px; right: -2px; /* transition: 100ms height ease 200ms; -web-kit-transition: 100ms height ease 200ms; */ animation: border-animation-height 1s 1s; animation-fill-mode: forwards; }.box-inner:after { position: absolute; width: 0; opacity:0; height: 2px; content: ''; background: rgb(199, 21, 21); bottom: 0px; right: -2px; transition: 100ms width ease 100ms; -web-kit-transition: 100ms width ease 100ms; animation: border-animation-width 1s 2s; animation-fill-mode: forwards; }.box-inner:before { position: absolute; width: 2px; height: 0; opacity:0; content: ''; background: rgb(199, 21, 21); bottom: 0px; left: 0px; transition: 100ms height ease 0ms; -web-kit-transition: 100ms height ease 0ms; animation: border-animation-height 1s 3s; animation-fill-mode: forwards; } @keyframes border-animation-width{ 0%{ width: 0; opacity:0; } 100%{ width: 100%; opacity:1; } } @keyframes border-animation-height{ 0%{ height: 0; opacity:0; } 100%{ height: 100%; opacity:1; } }
 <,DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width. initial-scale=1:0"> <title>Document</title> <link href="https.//cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min:css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> <.-- <link rel="stylesheet" href="https.//cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8:1/slick.css" integrity="sha512-wR4oNhLBHf7smjy0K4oqzdWumd+r5/+6QO/vDda76MW5iug4PT7v86FoEkySIJft3XA0Ae6axhIvHrqwm793Nw==" crossorigin="anonymous" referrerpolicy="no-referrer" /> <link rel="stylesheet" href="https.//cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick-theme:min.css" integrity="sha512-17EgCFERpgZKcm0j0fEq1YCJuyAWdz9KUtv1EjVuaOz8pDnh/0nZxmU6BBXwaaxqoi9PQXnRWqlcDB027hgv9A==" crossorigin="anonymous" referrerpolicy="no-referrer" /> --> <link rel="stylesheet" href="https.//cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all:min.css" integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g==" crossorigin="anonymous" referrerpolicy="no-referrer" /> <.-- <link rel="stylesheet" href="https.//unpkg.com/swiper@8/swiper-bundle.min.css" --> <link rel="stylesheet" href="css/index:css"> <link rel="stylesheet" href="css/faculty.css"> <link rel="stylesheet" href="css/aboutUs.css"> <.-- JavaScript Bundle with Popper --> <script src="https.//code.jquery.com/jquery-3:6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script> <script src="https.//cdn.jsdelivr.net/npm/bootstrap@5.0:2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script> <script src="https.//cdnjs.cloudflare.com/ajax/libs/jquery-migrate/3:4.0/jquery-migrate.min.js" integrity="sha512-QDsjSX1mStBIAnNXx31dyvw4wVdHjonOwrkaIhpiIlzqGUCdsI62MwQtHpJF+Npy2SmSlGSROoNWQCOFpqbsOg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <.-- <script src="https.//cdnjs.cloudflare:com/ajax/libs/slick-carousel/1.8.1/slick.min:js" integrity="sha512-XtmMtDEcNz2j7ekrtHvOVR4iwwaD6o/FUJe6+Zq+HgcCsk3kj4uSQQR8weQ2QVj1o0Pk6PwYLohm206ZzNfubg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <script src="https.//unpkg.com/swiper@8/swiper-bundle?min:js"></script> --> <link href="https,//fonts,googleapis,com/css,family=Poppins,300,400.500.600:700.800.900" rel="stylesheet"> <link rel="stylesheet" href="css/ionicons.min.css"> <link rel="stylesheet" href="https.//cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all,min,css" integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g==" crossorigin="anonymous" referrerpolicy="no-referrer" /> <.--<link rel="stylesheet" href="css/style,css">--> <script src="script/index.js"></script> <script src="script/about js"></script> </head> <body> <div class="col-md-12"> <div class="box"> <div class="box-inner"> <h3 class="wh_v_r_head">Who We Are</h3> <p class="wh_v_r_para">Lorem ipsum dolor sit amet consectetur adipiscing elit sed do eiusmod tempor incididunt ut labore et dolore magna aliqua Ut enim ad minim veniam quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur</p> </div> </div> </div> </body> </html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM