为什么填充会导致跳动的动画?

时间:2018-11-21 11:16:29

标签: html css

当我在父元素上应用顶部和底部填充时,为什么::before伪元素会在高度过渡期间跳动?

a {
  font-size: 2em;
  font-family: sans-serif;
  text-transform: uppercase;
  color: #fff;
  text-decoration: none;
  position: relative;
  /* Removing this padding resolves the animation issue, but why? */
  padding: 1em;
}

a::before {
  content: "";
  width: 0.06em;
  height: 0%;
  position: absolute;
  background: #fff;
  left: 0;
  transition: height 0.25s linear;
}

a:hover::before {
  height: 100%;
  bottom: 0;
}

.container {
  background: #3a3a3a;
  height: 100%;
  display: flex;
  padding-top: 1em;
  justify-content: center;
  align-items: flex-start;
}

body,
html {
  height: 100%;
  margin: 0;
}
<div class="container">
  <a href="#">Hover Me</a>
</div>

3 个答案:

答案 0 :(得分:1)

如果您在某个元素上具有填充,则在其子元素之一上应用绝对位置,填充量将作为该子元素的偏移量添加。

假设您拥有padding-top:10px;,它将变成top:10px,我认为某些浏览器确实可以做到这一点。

演示

*,
*:before,
*:after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.test {
  width: 100px;
  height: 100px;
  padding-top: 15px;
  border: 5px solid red;
}

.test>div {
  height: 50px;
  width: 50px;
  border: 5px solid red;
}

.test:hover>div {
  position: absolute;
  /* uncomment this line to see it */
  /* top: 0; */
}
<div class="test">
  <div></div>
</div>


现在解决您的问题。

a {
  font-size: 2em;
  font-family: sans-serif;
  text-transform: uppercase;
  color: #fff;
  text-decoration: none;
  position: relative;
  padding: 1em;
}

a::before {
  content: "";
  width: 0.06em;
  height: 0%;
  position: absolute;
  background: #fff;
  left: 0;
  /* rest the top here */
  top: 0;
  transition: height 0.25s linear;
}

a:hover::before {
  height: 100%;
  bottom: 0;
  /* unsetting the top because top:0 bottom:0; is full heiht which will prevent the animation the way you want it*/
  /* unsetting the top and not the bottom so it goes upward */
  top: unset;
}

.container {
  background: #3a3a3a;
  height: 100%;
  display: flex;
  padding-top: 1em;
  justify-content: center;
  align-items: flex-start;
}

body,
html {
  height: 100%;
  margin: 0;
}
<div class="container">
  <a href="#">Hover Me</a>
</div>

答案 1 :(得分:1)

bottom: 0规则从a:hover::before移至a::before规则集。

通常,请尽量减少选择器中:hover之类的规则数量-每当应用“悬停”规则集时,由于无法从心智上计算布局引擎的呈现方式而导致事物跳跃或移动的可能性事物,越高,越多的属性被覆盖。您不需要在那里的bottom: 0,但是如果需要与底部对齐,请将其设置在没有:hover的同一规则集上,即a::before-无论如何,它都会被处于“悬停”状态的元素继承。另一方面,如果您只希望元素的高度在悬停时过渡,那么这是应该在此处设置的唯一规则,不是吗?

答案 2 :(得分:0)

问题出在内容未正确对齐之前。 这是解决方案...

a {
  font-size: 2em;
  font-family: sans-serif;
  text-transform: uppercase;
  color: #fff;
  text-decoration: none;
  position: relative;
  /* Removing this padding resolves the animation issue, but why? */
  padding: 1em;
}

a::before {
  content: "";
  width: 0.06em;
  height: 0%;
  position: absolute;
  background: #fff;
  bottom:0;
  left: 0;
  transition: height 0.25s linear;
}

a:hover::before {
  top:0;
  height: 100%;
}

.container {
  background: #3a3a3a;
  height: 100%;
  display: flex;
  padding-top: 1em;
  justify-content: center;
  align-items: flex-start;
}

body,
html {
  height: 100%;
  margin: 0;
}
<div class="container">
  <a href="#">Hover Me</a>
</div>