Как предотвратить анимацию ключевого кадра 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>
Ответы
Ответ 1
Решение 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
Я всегда устанавливаю класс preload в тело с значением времени анимации 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);
Ответ 3
Есть ли способ сделать этот чистый CSS?
Да, абсолютно: см. Вилку http://jsfiddle.net/5r32Lsme/2/ Нет необходимости в JS.
и я предпочел бы, чтобы он запускался только после события наведения.
Поэтому вам нужно указать CSS, что происходит, когда это НЕ событие hover, а также - в вашем примере:
#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;
}
Сиденит:
Рекомендуется поместить собственные свойства CSS после префикса, поэтому он должен быть
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
и теперь существует собственное преобразование
-webkit-transform: translateY(0);
transform: translateY(0);
Ответ 4
Это не чистый CSS, но, возможно, кто-то наткнется на эту тему, как я:
В React я решил это, установив временный класс в ComponentDidMount() примерно так:
componentDidMount = () => {
document.getElementById("myContainer").className =
"myContainer pageload";
};
а затем в css:
.myContainer.pageload {
animation: none;
}
.myContainer.pageload * {
animation: none;
}
Если вы не знакомы, то знак "*" (пробел) выше означает, что он также применим ко всем потомкам элемента. Пробел означает все потомки, а звездочка - это подстановочный оператор, который относится ко всем типам элементов.
Ответ 5
Вращение анимации, которое (появляется) не запускается до тех пор, пока это не понадобится.
В 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 мс.
- Мышь управляет скоростью анимации. Когда мышь нависает над элементом, продолжительность анимации устанавливается достаточно, чтобы выглядеть гладкой.
Работа на моем сайте
Ответ 6
Если вы посмотрите на это после 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>