【问题标题】:How to get a CSS3 animation to maintain its location after the animation has completed?动画完成后如何让 CSS3 动画保持其位置?
【发布时间】:2016-03-08 09:08:10
【问题描述】:

我为表单上的标签设置动画,以便在输入字段获得焦点时它们向上移动并缩小尺寸。

我使用了应该保持最终关键帧状态的前向填充模式。

但是,情况似乎并非如此。输入字段失去焦点后,标签会向下跳。即使在字段失去焦点后,如何确保标签仍保持在动画结束时的位置?

.bottomBox {
  background: white;
  margin: 30px auto;
  width: 640px;
  height: 595px;
  border: 1px solid #9c9c9c;
}
.bottomBox h3 {
  text-align: center;
  padding: 20px 0;
}
.freeQuoteForm {
  margin: 0 auto;
  width: 530px;
  height: 430px;
  border: 1px solid #9c9c9c;
  text-align: left;
}
.formFields {
  border-bottom: 1px solid #9c9c9c;
  position: relative;
}
input,
textarea {
  font-family: "Sinkin Sans", Verdana, Helvetica, sans-serif;
  font-size: 12px;
  font-weight: 200;
  border: none;
}
.input {
  display: inline-block;
  height: 60px;
  padding: 0px;
  background: transparent;
}
.formLabel {
  position: absolute;
  left: 10px;
  -webkit-user-select: none;
  cursor: pointer;
  color: #bfbfbf;
  font-size: 70%;
  line-height: 8em;
  padding-left: 5px;
  height: 3px;
  -webkit-transform-origin: center left;
  transform-origin: center left;
}
#lastName {
  border-left: 1px solid #9c9c9c;
}
#lastName + .formLabel {
  left: 52%;
}
#lastName,
#firstName,
#email {
  padding-left: 12px;
  width: 50%;
  box-sizing: border-box;
}
#email {
  width: 100%;
}
.input:focus {
  outline: none;
  -webkit-animation: fadeColorBlue 2s 0s 1 ease-in-out forwards;
  animation: fadeColorBlue 2s 0s 1 ease-in-out forwards;
}
input:focus + .formLabel {
  -webkit-animation: colorScaleMove 1.5s ease-in-out forwards;
  animation: colorScaleMove 1.5s ease-in-out forwards;
}
.input:valid {
  -webkit-animation: fadeColorWhite 4s ease forwards;
  animation: fadeColorWhite 4s ease forwards;
}
@-webkit-keyframes fadeColorBlue {
  0% {
    background-color: white;
  }
  100% {
    background-color: #e6f9ff;
  }
}
@keyframes fadeColorBlue {
  0% {
    background-color: white;
  }
  100% {
    background-color: #e6f9ff;
  }
}
@-webkit-keyframes fadeColorWhite {
  0% {
    background-color: #e6f9ff;
  }
  100% {
    background-color: white;
  }
}
@keyframes fadeColorWhite {
  0% {
    background-color: #e6f9ff;
  }
  100% {
    background-color: white;
  }
}
@-webkit-keyframes colorScaleMove {
  0% {
    opacity: 1;
    -webkit-transform: scale(1) translateY(0px);
    transform: scale(1) translateY(0px);
  }
  10% {
    opacity: 0;
  }
  40% {
    opacity: 0;
  }
  100% {
    opacity: 1;
    -webkit-transform: scale(0.85) translateY(-34px);
    transform: scale(0.85) translateY(-34px);
    color: black;
  }
}
@keyframes colorScaleMove {
  0% {
    opacity: 1;
    -webkit-transform: scale(1) translateY(0px);
    transform: scale(1) translateY(0px);
  }
  10% {
    opacity: 0;
  }
  40% {
    opacity: 0;
  }
  100% {
    opacity: 1;
    -webkit-transform: scale(0.85) translateY(-34px);
    transform: scale(0.85) translateY(-34px);
    color: black;
  }
}
<div class="bottomBox">
			<h3>Free Quote Form</h3>
			<form class="freeQuoteForm" autocomplete="off">
				<div class="formFields">
					<input type="text" id="firstName" class="input" required><label class="formLabel" for="firstName">First Name</label><input type="text" id="lastName" class="input" required><label class="formLabel" for="LastName">Last Name</label>
				
				</div>
				<div class="formFields">
					<input type="email" id="email" class="input" required><label class="formLabel" for="email">Email Address</label>
				</div>
			</form>

		</div>

【问题讨论】:

    标签: javascript html css css-animations


    【解决方案1】:

    属性-值对 animation-fill-mode: forwards 用于维持动画最后一个关键帧的状态只有在动画本身适用时。当动画不再适用(或已移除)时,它不会保持状态。

    在您的 sn-p 中,动画仅在输入具有焦点时才适用于元素,因此当它失去焦点时,元素(标签)会弹回其原始位置。如果您想将标签保持在动画的结束位置,那么您应该使用 JavaScript,监听 animationend 事件,使用 getComputedStyle 获取最终的 transform 值,然后通过内联样式将其设置回元素,例如在下面的sn-p中。

    没有纯 CSS 方法可以让元素保留其动画结束位置,即使在动画被移除后也是如此。

    JS 代码:

    window.onload = function() {
      var els = document.querySelectorAll('.formLabel');
      for (i = 0; i < els.length; i++) {
        els[i].addEventListener('animationend', function() {
          var currTransform = window.getComputedStyle(this).transform;
          this.style.transform = currTransform;
        });
      }
    }
    

    演示:

    window.onload = function() {
      var els = document.querySelectorAll('.formLabel');
      for (i = 0; i < els.length; i++) {
        els[i].addEventListener('animationend', function() {
          var currTransform = window.getComputedStyle(this).transform;
          this.style.transform = currTransform;
        });
      }
    }
    .bottomBox {
      background: white;
      margin: 30px auto;
      width: 640px;
      height: 595px;
      border: 1px solid #9c9c9c;
    }
    .bottomBox h3 {
      text-align: center;
      padding: 20px 0;
    }
    .freeQuoteForm {
      margin: 0 auto;
      width: 530px;
      height: 430px;
      border: 1px solid #9c9c9c;
      text-align: left;
    }
    .formFields {
      border-bottom: 1px solid #9c9c9c;
      position: relative;
    }
    input,
    textarea {
      font-family: "Sinkin Sans", Verdana, Helvetica, sans-serif;
      font-size: 12px;
      font-weight: 200;
      border: none;
    }
    .input {
      display: inline-block;
      height: 60px;
      padding: 0px;
      background: transparent;
    }
    .formLabel {
      position: absolute;
      left: 10px;
      -webkit-user-select: none;
      cursor: pointer;
      color: #bfbfbf;
      font-size: 70%;
      line-height: 8em;
      padding-left: 5px;
      height: 3px;
      transform-origin: center left;
    }
    #lastName {
      border-left: 1px solid #9c9c9c;
    }
    #lastName + .formLabel {
      left: 52%;
    }
    #lastName,
    #firstName,
    #email {
      padding-left: 12px;
      width: 50%;
      box-sizing: border-box;
    }
    #email {
      width: 100%;
    }
    .input:focus {
      outline: none;
      animation: fadeColorBlue 2s 0s 1 ease-in-out forwards;
    }
    input:focus + .formLabel {
      animation: colorScaleMove 1.5s ease-in-out forwards;
    }
    .input:valid {
      animation: fadeColorWhite 4s ease forwards;
    }
    @keyframes fadeColorBlue {
      0% {
        background-color: white;
      }
      100% {
        background-color: #e6f9ff;
      }
    }
    @keyframes fadeColorWhite {
      0% {
        background-color: #e6f9ff;
      }
      100% {
        background-color: white;
      }
    }
    @keyframes colorScaleMove {
      0% {
        opacity: 1;
        transform: scale(1) translateY(0px);
      }
      10% {
        opacity: 0;
      }
      40% {
        opacity: 0;
      }
      100% {
        opacity: 1;
        transform: scale(0.85) translateY(-34px);
        color: black;
      }
    }
    <div class="bottomBox">
            <h3>Free Quote Form</h3>
            <form class="freeQuoteForm" autocomplete="off">
                <div class="formFields">
                    <input type="text" id="firstName" class="input" required><label class="formLabel" for="firstName">First Name</label><input type="text" id="lastName" class="input" required><label class="formLabel" for="LastName">Last Name</label>
    
                </div>
                <div class="formFields">
                    <input type="email" id="email" class="input" required><label class="formLabel" for="email">Email Address</label>
                </div>
            </form>
    
        </div>

    请注意,如果您需要支持较旧的浏览器,您可能还必须收听带有浏览器前缀版本的 animationend 事件。

    【讨论】:

    • 感谢 Harry 帮助我理解为什么动画没有停留在最终位置,也感谢您对如何解决这个问题提出了很好的建议。
    猜你喜欢
    • 1970-01-01
    • 2012-05-12
    • 2013-06-22
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 2012-10-17
    • 1970-01-01
    • 2013-06-22
    相关资源
    最近更新 更多