是否可以在单个 CSS 转换中组合 translateX/translateY 和缩放?
Is it possible to combine translateX/translateY and scale in single CSS transition?
我一直在玩 CSS 转换循环(在 this article 之后)。
过渡本身可以分为 4 个(循环)阶段:
收缩2=>扩展=>扩展2=>收缩
这些状态由 4 类:
表示
收缩2 - stateOne
扩展 - stateTwo
扩展2 - stateThree
收缩2 - 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. Changing of expected property name (in loopTransition
function) to background
, has not effect (JSFiddle).
我完全知道有 lots of other 种方法可以使元素居中。我想了解的是:
- 是否可以将
translateX
/translateY
和 scale
组合在同一个 CSS 转换中(如果是,我做错了什么?)
- 如果
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>
在 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);
}
我一直在玩 CSS 转换循环(在 this article 之后)。
过渡本身可以分为 4 个(循环)阶段:
收缩2=>扩展=>扩展2=>收缩
这些状态由 4 类:
表示
收缩2 - stateOne
扩展 - stateTwo
扩展2 - stateThree
收缩2 - 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. Changing of expected property name (in loopTransition
function) to background
, has not effect (JSFiddle).
我完全知道有 lots of other 种方法可以使元素居中。我想了解的是:
- 是否可以将
translateX
/translateY
和scale
组合在同一个 CSS 转换中(如果是,我做错了什么?) - 如果
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>
在 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); }