Как предотвратить запуск анимации ключевого кадра css при загрузке страницы?
у меня есть 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. Моя проблема в том, когда я обновляю страницу, и страница загружает
есть ли способ сделать этот чистый CSS, или я должен что-то выяснить в JS?
4 ответов
Решение 1-Добавление анимации при первом наведении
вероятно, лучший вариант - не ставить анимацию вниз, пока пользователь не завис над container
впервые.
это включает в себя прослушивание mouseover
событие затем добавляет класс с анимацией в этот момент и удаляет прослушиватель событий. Основным (потенциальным) недостатком этого является то, что он полагается на Яваскрипт.
;(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-воспроизведение анимации скрыто
другой способ обойти это-изначально скрыть элемент, убедиться, что анимация воспроизводится, пока она скрыта, а затем сделать ее видимой. Недостатком этого является то, что время может быть немного выключено, и оно становится видимым слишком рано, а также наведение не доступно сразу.
для этого требуется некоторый Javascript, который ждет для длины анимации и только потом делает #content
видны. Это означает, что вам также нужно установить начальное opacity
to 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 - использовать переходы
в вашем сценарии вы можете сделать этот CSS только путем замены keyframe
С transition
вместо, Итак, это начинается с 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 и его работа довольно хорошо. У меня есть некоторые обратные переходы, поэтому мне тоже нужно удалить анимацию загрузки. Я решил это, временно установив время анимации в 0. Вы можете изменить переходы, чтобы соответствовать вашим.
HTML-код
... <body class="preload">...
CSS устанавливает анимацию в 0s
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 ниже позволяет стрелки вверх и вниз для отображения пунктов меню.
Анимация, похоже, не запускается при загрузке страницы, но это действительно так.
@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;
}
сверху вниз:
- создать вращений. Для этого есть два... один для стрелки вниз и один для стрелки вверх. Нужны две стрелки, потому что после вращения они возвращаются в свое естественное состояние. Так, стрелка вниз запускает и вращает вниз, а стрелка вверх начинает вниз и вращается.
- создайте маленькие стрелки. Это прямая реализация:: before
- ставим анимацию на этикетке. Нет ничего особенного, там за исключением того, что продолжительность анимации составляет 1мс.
- мышь управляет скоростью анимации. Когда мышь нависает над элементом, продолжительность анимации устанавливается в достаточное время, чтобы кажется гладким.
есть ли способ сделать этот чистый CSS ?
Да, абсолютно: см. вилку http://jsfiddle.net/5r32Lsme/2/ В JS действительно нет необходимости.
и я бы предпочел, чтобы он запускался только после события наведения.
поэтому вам нужно рассказать CSS, что происходит, когда это не событие наведения-в вашем примере:
#container:not(:hover) #content {
visibility: hidden;
transition: visibility 0.01s 1s;
}
но есть две вещи, чтобы отметить:
1) задержка перехода выше должно соответствовать продолжительности анимации
2) вы не можете использовать свойство, которое вы используете, чтобы скрыть анимацию onLoad в анимации. Если вам нужно видимость в анимации, скрыть анимацию изначально как например
#container:not(:hover) #content {
top: -8000px;
transition: top 0.01s 1s;
}
sidenote:
рекомендуется поместить собственные свойства CSS после префиксных, поэтому он должен быть
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
и теперь есть родной преобразование
-webkit-transform: translateY(0);
transform: translateY(0);