是否可以在单个 CSS 过渡中结合 translateX/translateY 和缩放?
Posted
技术标签:
【中文标题】是否可以在单个 CSS 过渡中结合 translateX/translateY 和缩放?【英文标题】:Is it possible to combine translateX/translateY and scale in single CSS transition? 【发布时间】:2018-03-24 02:56:44 【问题描述】:我一直在玩 CSS 转换的循环(在 this article 之后)。
过渡本身可以分为 4 个(循环)阶段:shrinked2=>expanded=>expanded2=>shrinked
这些状态由 4 个类表示:shrinked2 - stateOne
expanded - stateTwo
expanded2 - stateThree
shrinked2 - stateFour
最初,我正在通过 id 设置元素的宽度和高度,以百分比形式进行转换。然后,为了触发转换,我通过上面列出的状态类更改transform: scale
。
就他而言,它基本上对我来说很好,这里是demonstration on JSFiddle。
现在,作为下一步,我想在页面上垂直和水平地居中过渡元素(并将其保留在那里)。我通过将以下内容添加到元素 id 来做到这一点:
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
以及在状态类中为每个transform:
附加translateX(-50%) translateY(-50%)
。现在这种方式 scale
不会应用于元素(即在转换时不会更改大小) - 只有 background
属性受到影响,转换只发生一次(即不再循环),就好像 transitionend
是从未被解雇。
这是the result on JSFiddle。将预期的属性名称(在loopTransition
函数中)更改为background
、has not effect (JSFiddle)。
我完全知道有lots 的other 方法来居中元素。我想了解的是:
-
是否可以在同一个 CSS 过渡中组合
translateX
/translateY
和 scale
(如果是,我做错了什么?)
如果以top: 50%; left: 50%; transform: translateX(-50%) translateY(-50%);
为中心的元素与一般过渡或特别是scale
不兼容,建议使用什么方法?
var the_circle = document.getElementById('circle');
the_circle.addEventListener("transitionend", loopTransition);
function startTransition()
var the_circle = document.getElementById('circle');
if (the_circle.className === 'stateOne paused')
the_circle.style.transitionDuration = 1;
the_circle.className = 'stateTwo animated';
else
stopTransition();
function stopTransition()
var the_circle = document.getElementById('circle');
the_circle.style.transitionDuration = "0.5s"
the_circle.className = "stateOne paused"
function loopTransition(e)
var the_circle = document.getElementById('circle');
if (e.propertyName === "transform")
if (the_circle.className.indexOf('paused') !== -1)
stopTransition()
else
if (the_circle.className === "stateTwo animated")
the_circle.style.transitionDuration = "1s";
the_circle.className = "stateThree animated";
else if (the_circle.className === "stateThree animated")
the_circle.style.transitionDuration = "1s";
the_circle.className = "stateFour animated";
else if (the_circle.className === "stateFour animated")
the_circle.style.transitionDuration = "1s";
the_circle.className = "stateOne animated";
else if (the_circle.className === "stateOne animated")
the_circle.style.transitionDuration = "1s";
the_circle.className = "stateTwo animated";
#circle
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
position: absolute;
width: 10%;
padding-top: 10%;
border-radius: 50%;
transition: all 1s;
.stateOne
background: #800080;
transform: scale(1.0001, 1.0001) translateX(-50%) translateY(-50%);
.stateTwo
background: #ffe6ff;
transform: scale(2, 2) translateX(-50%) translateY(-50%);
.stateThree
background: #ffe6ff;
transform: scale(2.0001, 2.0001) translateX(-50%) translateY(-50%);
.stateFour
background: #800080;
transform: scale(1, 1) translateX(-50%) translateY(-50%);
<div id='circle' class="stateOne paused" onclick=startTransition()></div>
【问题讨论】:
你试过animation
& keyframes
吗?
@Svenskunganka 是的,我有,(请参阅:another question 和 JSFiddle),它工作得非常好。不过,由于我正在为学习目的做这些事情,我的目标是让它现在与 transition
一起工作。
【参考方案1】:
在 CSS 中,#id
选择器优先于 .class
选择器。因此,.state
类中的 transform
声明永远不会被应用。解决方案是:
增加规则的specificity,即#circle.stateTwo
,
将!important
标志添加到您的声明中:
transform: scale(2, 2) translate(-50%, -50%) !important;
但是应该避免这种情况,并尽可能使用第一种方法。
一种不与动画混合的更简单的居中元素方法是使用flexbox:
.flex-container
display: flex;
align-items: center;
justify-content: center;
width: 100vw;
height: 100vh;
#circle
width: 10%;
padding-top: 10%;
border-radius: 50%;
transition: all 1s;
.stateOne
background: #800080;
transform: scale(1.0001, 1.0001);
.stateTwo
background: #ffe6ff;
transform: scale(2, 2);
.stateThree
background: #ffe6ff;
transform: scale(2.0001, 2.0001);
.stateFour
background: #800080;
transform: scale(1, 1);
【讨论】:
我假设left
和 right
按百分比定位不考虑 scale
转换,但 translate 会。稍后我可能会对此进行测试...
第一个建议的方法(使用#circle.stateTwo
)最初使元素居中,尽管fails (JSFiddle) 使其在过渡期间保持居中,但我很感激并解释为什么会发生这种情况。第二种,方法(使用flexbox
)works (JSFiddle) 符合预期,所以我想我会坚持下去。无论如何,感谢您的回答!以上是关于是否可以在单个 CSS 过渡中结合 translateX/translateY 和缩放?的主要内容,如果未能解决你的问题,请参考以下文章
css3中transition 过渡效果如何只对transform:scale 起作用,对其它像transform: translate不起作用!