Stop animation from replaying when parent switches from display:none to block

后端 未结 1 1590
野性不改
野性不改 2021-01-14 15:01

I have a set of tabs that each contain a child element that animates. What happens when I click each tab is that the animation of the child element within the tab runs. I do

相关标签:
1条回答
  • 2021-01-14 15:39

    Yes, animations will restart every time the display value is changed from none to something else.

    As per W3C Spec: (emphasis is mine)

    Setting the display property to ‘none’ will terminate any running animation applied to the element and its descendants. If an element has a display of ‘none’, updating display to a value other than ‘none’ will start all animations applied to the element by the ‘animation-name’ property, as well as all animations applied to descendants with display other than ‘none’.

    There is no direct way to prevent this from happening because that is the intended behavior. You can workaround the situation by using other methods to hide the element instead of using display: none.

    Following are a few suggestions on how the element could be hidden without display: none. It is not mandatory to use only one of the following workarounds, it could be some other way also as long as it doesn't involve changing the display property of the element.

    • Using height: 0, width: 0, overflow: hidden to hide the element.

      $(".toggler").on("click", function() {
        $(".parent").toggleClass("active");
      });
      .parent {
        height: 0;
        width: 0;
        overflow: hidden;
        cursor: pointer;
      }
      .child {
        width: 100px;
        height: 100px;
        background-color: red;
        position: relative;
        animation: move 200ms cubic-bezier(.91, .8, .54, 1.39) forwards;
      }
      .active {
        height: auto;
        width: auto;
        overflow: visible;
      }
      .child.red {
        background-color: red;
      }
      .child.blue {
        background-color: blue;
      }
      @keyframes move {
        from {
          left: 0;
        }
        to {
          left: 180px;
        }
      }
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <a class="toggler">Click this</a>
      
      <div class="parent active">
        <div class="child red"></div>
      </div>
      
      <div class="parent">
        <div class="child blue"></div>
      </div>

    • Adding a container, using position: absolute and opacity: 0 to hide the element.

      $(".toggler").on("click", function() {
        $(".parent").toggleClass("active");
      });
      .container {
        position: relative;
      }
      .parent {
        position: absolute;
        opacity: 0;
        cursor: pointer;
      }
      .child {
        width: 100px;
        height: 100px;
        background-color: red;
        position: relative;
        animation: move 200ms cubic-bezier(.91, .8, .54, 1.39) forwards;
      }
      .active {
        opacity: 1;
      }
      .child.red {
        background-color: red;
      }
      .child.blue {
        background-color: blue;
      }
      @keyframes move {
        from {
          left: 0;
        }
        to {
          left: 180px;
        }
      }
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <a class="toggler">Click this</a>
      
      <div class='container'>
        <div class="parent active">
          <div class="child red"></div>
        </div>
      
        <div class="parent">
          <div class="child blue"></div>
        </div>
      </div>

    • Adding a container, using position: absolute and visibility: hidden to hide the element.

      $(".toggler").on("click", function() {
        $(".parent").toggleClass("active");
      });
      .container {
        position: relative;
      }
      .parent {
        position: absolute;
        visibility: hidden;
        cursor: pointer;
      }
      .child {
        width: 100px;
        height: 100px;
        background-color: red;
        position: relative;
        animation: move 200ms cubic-bezier(.91, .8, .54, 1.39) forwards;
      }
      .active {
        visibility: visible;
      }
      .child.red {
        background-color: red;
      }
      .child.blue {
        background-color: blue;
      }
      @keyframes move {
        from {
          left: 0;
        }
        to {
          left: 180px;
        }
      }
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <a class="toggler">Click this</a>
      
      <div class='container'>
        <div class="parent active">
          <div class="child red"></div>
        </div>
      
        <div class="parent">
          <div class="child blue"></div>
        </div>
      </div>

    • Adding a container, using position: absolute and z-index to hide the element.

      $(".toggler").on("click", function() {
        $(".parent").toggleClass("active");
      });
      .container {
        position: relative;
      }
      .parent {
        position: absolute;
        z-index: -1;
        cursor: pointer;
      }
      .child {
        width: 100px;
        height: 100px;
        background-color: red;
        position: relative;
        animation: move 200ms cubic-bezier(.91, .8, .54, 1.39) forwards;
      }
      .active {
        z-index: 1;
      }
      .child.red {
        background-color: red;
      }
      .child.blue {
        background-color: blue;
      }
      @keyframes move {
        from {
          left: 0;
        }
        to {
          left: 180px;
        }
      }
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <a class="toggler">Click this</a>
      
      <div class='container'>
        <div class="parent active">
          <div class="child red"></div>
        </div>
      
        <div class="parent">
          <div class="child blue"></div>
        </div>
      </div>

    0 讨论(0)
提交回复
热议问题