将固定元素动画化到视口的中心
Animate fixed element to the center of the viewport
我在页面右上角有一个元素position: fixed;
。
我希望它在点击时 "grow and move" 到屏幕中央。
据我所知,将某些内容放置在页面死角的最佳解决方案是
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
如果我将元素最初定位为 top
和 left
属性,则一切正常,但如果元素最初定位为 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>
如何消除动画中初始跳到水平中心的问题? (即我想要 "shrinking back to top right" 的反面,这里一切正常)。
只需要在 foo
状态下将右转为左即可。
这也意味着您将翻译 属性 更改为: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()
仅在顶部和右侧属性上进行过渡,如下所示:
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>
这会改变动画轨迹并防止元素在一个方向上用 top/right 和另一个方向同时用 transform
属性.
我承认,一开始这给了我一些麻烦,但凭借一些毅力,我能够让你到达那里哈哈
这是因为您没有为 CSS 转换提供与 right
属性 定位关联的起点。您已将元素 right
属性 of 20px
切换为 left
属性 of 50%
。对于你想要的效果,你需要给它一个20px
的起始right
位置和50%
的结束right
位置对于 .bar
(摆脱 left: 50%;
)。
现在,在您解决上述问题后,您需要解决 .bar
class transform
方法 transform: translate(50%, -50%);
这是因为我们已经切换到使用 right
x-axis 定位,所以我们需要它从右边开始 50%
,而不是 -50%
(这会使元素从 off-screen -50%
of the space from the dead center of parent).
Here is your new live demo。我希望这是有道理的 :) CSS 逻辑上要求所有转换都有一个起点和一个有效的、同居的终点。有些浏览器会为您做出假设,但它们永远不应该这样做,因为这会阻碍开发 cross-platform.
我在页面右上角有一个元素position: fixed;
。
我希望它在点击时 "grow and move" 到屏幕中央。
据我所知,将某些内容放置在页面死角的最佳解决方案是
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
如果我将元素最初定位为 top
和 left
属性,则一切正常,但如果元素最初定位为 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>
如何消除动画中初始跳到水平中心的问题? (即我想要 "shrinking back to top right" 的反面,这里一切正常)。
只需要在 foo
状态下将右转为左即可。
这也意味着您将翻译 属性 更改为: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()
仅在顶部和右侧属性上进行过渡,如下所示:
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>
这会改变动画轨迹并防止元素在一个方向上用 top/right 和另一个方向同时用 transform
属性.
我承认,一开始这给了我一些麻烦,但凭借一些毅力,我能够让你到达那里哈哈
这是因为您没有为 CSS 转换提供与 right
属性 定位关联的起点。您已将元素 right
属性 of 20px
切换为 left
属性 of 50%
。对于你想要的效果,你需要给它一个20px
的起始right
位置和50%
的结束right
位置对于 .bar
(摆脱 left: 50%;
)。
现在,在您解决上述问题后,您需要解决 .bar
class transform
方法 transform: translate(50%, -50%);
这是因为我们已经切换到使用 right
x-axis 定位,所以我们需要它从右边开始 50%
,而不是 -50%
(这会使元素从 off-screen -50%
of the space from the dead center of parent).
Here is your new live demo。我希望这是有道理的 :) CSS 逻辑上要求所有转换都有一个起点和一个有效的、同居的终点。有些浏览器会为您做出假设,但它们永远不应该这样做,因为这会阻碍开发 cross-platform.