将固定元素设置为视口中心的动画

时间:2019-05-07 16:22:13

标签: css css-transitions css-animations

我在页面的右上角有一个position: fixed;元素。
我希望它在单击时“增长并移动”到屏幕的中央。

我知道的最好的解决方案是将某些内容放置在页面的中心位置

position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);

如果我最初将元素放置在topleft属性中,那么一切都会很好,但是如果最初将元素放置在right中而不是在元素中,则动画会出现讨厌的跳跃left

const myFunc = function() {
  let f = document.getElementById('element')

  if (f.className.includes('bar')) {
    f.className = 'foo'
  } else {
    f.className = 'foo bar'
  }
}
.wrapper {
  position: relative;
  width: 100%;
  height: 100%;
}

.foo {
  position: fixed;
  top: 20px;
  right: 20px;
  width: 200px;
  height: 50px;
  background-color: blue;
  transition: 0.5s all;
}

.bar {
  position: fixed;
  top: 50%;
  left: 50%;
  width: 500px;
  height: 500px;
  background-color: red;
  transform: translate(-50%, -50%);
  transition: 0.5s all;
}
<div class="wrapper">
  <div class="foo" id="element" onclick="myFunc()">
  </div>
</div>

Codepen

如何摆脱动画中向水平中心的初始跳跃? (即,我想要“缩小到右上角”的反义词,这里一切正常。)

2 个答案:

答案 0 :(得分:3)

您只需要在foo状态下从右向左更改。
这也意味着您将translation属性更改为:translate(50%,-50%);,因为tanslateX值应从左到右位于元素的中心:

const myFunc = function () {
  let f = document.getElementById('element')

  if(f.className.includes('bar')) {
    f.className = 'foo'
  }
  else {
    f.className = 'foo bar'
  }
}
.wrapper {
  position: relative;
  width: 100%;
  height: 100%;
}

.foo {
  position: fixed;
  top: 20px;
  right: 20px;
  width: 200px;
  height: 50px;
  background-color: blue;
  transition: 0.5s all;
}

.bar {
  position: fixed;
  top: 50%;
  right: 50%;
  width: 500px;
  height: 500px;
  background-color: red;
  transform: translate(50%, -50%);
  transition: 0.5s all;
}
<div class="wrapper">
  <div class="foo" id="element" onclick="myFunc()">
  </div>
</div>

另一方面,如果您知道两种状态下元素的大小,都可以使用calc()仅在top和right属性上进行过渡,如下所示:

const myFunc = function() {
  let f = document.getElementById('element')

  if (f.className.includes('bar')) {
    f.className = 'foo'
  } else {
    f.className = 'foo bar'
  }
}
.wrapper {
  position: relative;
  width: 100%;
  height: 100%;
}

.foo {
  position: fixed;
  top: 20px;
  right: 20px;
  width: 200px;
  height: 50px;
  background-color: blue;
  transition: 0.5s all;
}

.bar {
  position: fixed;
  top: calc(50% - 250px);
  right: calc(50% - 250px);
  width: 500px;
  height: 500px;
  background-color: red;
  transition: 0.5s all;
}
<div class="wrapper">
  <div class="foo" id="element" onclick="myFunc()">
  </div>
</div>

这会更改动画轨迹,并通过transform属性阻止元素在一个方向上朝上/向右动画,或者同时在另一个方向上动画。

答案 1 :(得分:0)

我承认,起初这给我带来了一些麻烦,但是有了一些毅力,我才能够带你到这里

这是因为您没有为CSS过渡提供关联right属性位置的起点。您已从赋予元素right的{​​{1}}属性到20px的{​​{1}}属性。为了获得想要的效果,您需要为{{}赋予left的起始50%位置和right结束 20px位置1}}(摆脱right)。

现在,在解决上述问题之后,您需要通过将其设置为50%来解决.barleft: 50%;方法,这是因为我们已切换为使用{ {1}} x轴定位,因此我们需要它从右侧移.bar,而不是transform(这会使元素偏离屏幕transform: translate(50%, -50%);的空间父母的死点)。

Here is your new live demo。我希望这是有道理的:) CSS在逻辑上要求所有转换都具有起点和有效的,同居的终点。一些浏览器会为您做出假设,但绝对不要这样做,因为这会阻碍跨平台的开发。