コンテンツをアニメーション化するdivがあります。
#container {
position: relative;
width: 100px;
height: 100px;
border-style: inset;
}
#content {
visibility: hidden;
-webkit-animation: animDown 1s ease;
position: absolute;
top: 100px;
width: 100%;
height: 100%;
background-color: lightgreen;
}
#container:hover #content {
-webkit-animation: animUp 1s ease;
animation-fill-mode: forwards;
-webkit-animation-fill-mode: forwards;
}
@-webkit-keyframes animUp {
0% {
-webkit-transform: translateY(0);
visibility: hidden;
opacity: 0;
}
100% {
-webkit-transform: translateY(-100%);
visibility: visible;
opacity: 1;
}
}
@-webkit-keyframes animDown {
0% {
-webkit-transform: translateY(-100%);
visibility: visible;
opacity: 1;
}
100% {
-webkit-transform: translateY(0);
visibility: hidden;
opacity: 0;
}
}
<div id="container">
<div id="content"></div>
</div>
ホバーすると、コンテンツがコンテナdivにスライドします。私の問題は、ページを更新すると、ページが#content
のanimDownアニメーションが実行されます。ホバーイベント後にのみ実行することをお勧めします。
この純粋なCSSを行う方法はありますか、それともJSで何かを理解する必要がありますか?
解決策1-最初のホバー時にダウンアニメーションを追加
おそらく、ユーザーがcontainer
に初めてカーソルを合わせるまで、ダウンアニメーションをオンにしないのが最良のオプションです。
これには、mouseover
イベントをリッスンし、その時点でアニメーションを含むクラスを追加し、イベントリスナーを削除することが含まれます。これの主な(潜在的な)欠点は、Javascriptに依存していることです。
;(function(){
var c = document.getElementById('container');
function addAnim() {
c.classList.add('animated')
// remove the listener, no longer needed
c.removeEventListener('mouseover', addAnim);
};
// listen to mouseover for the container
c.addEventListener('mouseover', addAnim);
})();
#container {
position:relative;
width:100px;
height:100px;
border-style:inset;
}
#content {
position:absolute;
top:100px;
width:100%;
height:100%;
background-color:lightgreen;
opacity:0;
}
/* This gets added on first mouseover */
#container.animated #content {
-webkit-animation:animDown 1s ease;
}
#container:hover #content {
-webkit-animation:animUp 1s ease;
animation-fill-mode:forwards;
-webkit-animation-fill-mode:forwards;
}
@-webkit-keyframes animUp {
0% {
-webkit-transform:translateY(0);
opacity:0;
}
100% {
-webkit-transform:translateY(-100%);
opacity:1;
}
}
@-webkit-keyframes animDown {
0% {
-webkit-transform:translateY(-100%);
opacity:1;
}
100% {
-webkit-transform:translateY(0);
opacity:0;
}
}
<div id="container">
<div id="content"></div>
</div>
ソリューション2-非表示のアニメーションを再生
これを回避する別の方法は、最初に要素を非表示にし、非表示のときにアニメーションが再生されることを確認してから、表示することです。これの欠点は、タイミングがわずかにずれている可能性があり、あまりにも早く見えるようになり、またホバーがすぐに利用できないことです。
これには、アニメーションの長さを待機してから#content
を表示するJavascriptが必要です。つまり、初期opacity
を0
に設定して、ロード時に表示されず、キーフレームからvisibility
も削除する必要があることを意味します-これらは何もしません:
// wait for the animation length, plus a bit, then make the element visible
window.setTimeout(function() {
document.getElementById('content').style.visibility = 'visible';
}, 1100);
#container {
position:relative;
width:100px;
height:100px;
border-style:inset;
}
#content {
visibility:hidden;
-webkit-animation:animDown 1s ease;
position:absolute;
top:100px;
width:100%;
height:100%;
background-color:lightgreen;
opacity:0;
}
#container:hover #content {
-webkit-animation:animUp 1s ease;
animation-fill-mode:forwards;
-webkit-animation-fill-mode:forwards;
}
@-webkit-keyframes animUp {
0% {
-webkit-transform:translateY(0);
opacity:0;
}
100% {
-webkit-transform:translateY(-100%);
opacity:1;
}
}
@-webkit-keyframes animDown {
0% {
-webkit-transform:translateY(-100%);
opacity:1;
}
100% {
-webkit-transform:translateY(0);
opacity:0;
}
}
<div id="container">
<div id="content"></div>
</div>
解決策3-トランジションを使用
あなたのシナリオでは、代わりにkeyframe
sをtransition
に置き換えることによってのみこのCSSを作成できます。したがって、opacity:0
で始まり、ホバーだけがopacity
およびtransform
:
#container {
position:relative;
width:100px;
height:100px;
border-style:inset;
}
#content {
position:absolute;
top:100px;
width:100%;
height:100%;
background-color:lightgreen;
/* initial state - hidden */
opacity:0;
/* set properties to animate - applies to hover and revert */
transition:opacity 1s, transform 1s;
}
#container:hover #content {
/* Just set properties to change - no need to change visibility */
opacity:1;
-webkit-transform:translateY(-100%);
transform:translateY(-100%);
}
<div id="container">
<div id="content"></div>
</div>
私は常にプリロードクラスをアニメーション時間値0のbodyに設定し、それはかなりうまく機能しています。バックトランジションがいくつかあるので、それらへのロードアニメーションも削除する必要があります。アニメーション時間を一時的に0に設定することでこれを解決しました。トランジションを自分のトランジションに合わせて変更できます。
HTML
... <body class="preload">...
CSSはアニメーションを0に設定しています
body.preload *{
animation-duration: 0s !important;
-webkit-animation-duration: 0s !important;
transition:background-color 0s, opacity 0s, color 0s, width 0s, height 0s, padding 0s, margin 0s !important;}
JSは少し遅れてクラスを削除するので、アニメーションは通常の時間に発生します:)
setTimeout(function(){
document.body.className="";
},500);
この純粋なCSSを行う方法はありますか?
はい、絶対に:フォークを参照してください http://jsfiddle.net/5r32Lsme/2/ JSは本当に必要ありません。
ホバーイベント後にのみ実行することを希望します。
そのため、CSSがホバーイベントではない場合に何が起こるかをCSSに伝える必要があります-あなたの例では:
#container:not(:hover) #content {
visibility: hidden;
transition: visibility 0.01s 1s;
}
ただし、注意すべき点が2つあります。
1)上記の遷移遅延は、アニメーションの継続時間と一致する必要があります
2)アニメーションのonLoadアニメーションを非表示にするために使用するプロパティは使用できません。アニメーションでvisibilityが必要な場合は、最初のようにアニメーションを非表示にします。
#container:not(:hover) #content {
top: -8000px;
transition: top 0.01s 1s;
}
補足:
ネイティブのCSSプロパティをプレフィックスの後に配置することをお勧めします。
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
そして今、ネイティブtransformがあります
-webkit-transform: translateY(0);
transform: translateY(0);
これは純粋なCSSではありませんが、おそらく私がしたように誰かがこのスレッドを偶然見つけるでしょう:
In React ComponentDidMount()で一時クラスを次のように設定することでこれを解決しました。
componentDidMount = () => {
document.getElementById("myContainer").className =
"myContainer pageload";
};
そして、CSSで:
.myContainer.pageload {
animation: none;
}
.myContainer.pageload * {
animation: none;
}
よくわからない場合は、上記の「*」(n.b。スペース)は、要素のすべての子孫にも適用されることを意味します。スペースはすべての子孫を意味し、アスタリスクはすべてのタイプの要素を参照するワイルドカード演算子です。
2019年以降にこれを見ている場合、より良い解決策はこれです:
let div = document.querySelector('div')
document.addEventListener('DOMContentLoaded', () => {
// Adding timeout to simulate the loading of the page
setTimeout(() => {
div.classList.remove('prevent-animation')
}, 2000)
document.querySelector('button').addEventListener('click', () => {
if(div.classList.contains('after')) {
div.classList.remove('after')
} else {
div.classList.add('after')
}
})
})
div {
background-color: purple;
height: 150px;
width: 150px;
}
.animated-class {
animation: animationName 2000ms;
}
.animated-class.prevent-animation {
animation-duration: 0ms;
}
.animated-class.after {
animation: animation2 2000ms;
background-color: orange;
}
@keyframes animationName {
0% {
background-color: red;
}
50% {
background-color: blue;
}
100% {
background-color: purple;
}
}
@keyframes animation2 {
0% {
background-color: salmon;
}
50% {
background-color: green;
}
100% {
background-color: orange;
}
}
<div class="animated-class prevent-animation"></div>
<button id="btn">Toggle between animations</button>
必要になるまで実行されない(表示される)回転アニメーション
以下のCSSでは、メニュー項目を表示するための上下矢印を使用できます。アニメーションはページの読み込み時に実行されるようには見えませんが、実際には実行されます。
@keyframes rotateDown {
from { transform: rotate(180deg); }
to { transform: rotate(0deg); }
}
@keyframes rotateUp {
from { transform: rotate(180deg); }
to { transform: rotate(0deg); }
}
div.menu input[type='checkbox'] + label.menu::before {
display :inline-block;
content : "▼";
color : #b78369;
opacity : 0.5;
font-size : 1.2em;
}
div.menu input[type='checkbox']:checked + label.menu::before {
display : inline-block;
content : "▲";
color : #b78369;
opacity : 0.5;
font-size : 1.2em;
}
div.menu input[type='checkbox'] + label.menu {
display : inline-block;
animation-name : rotateDown;
animation-duration : 1ms;
}
div.menu input[type='checkbox']:checked + label.menu {
display : inline-block;
animation-name : rotateUp;
animation-duration : 1ms;
}
div.menu input[type='checkbox'] + label.menu:hover {
animation-duration : 500ms;
}
div.menu input[type='checkbox']:checked + label.menu:hover {
animation-duration : 500ms;
}
上から下まで: