Как предотвратить запуск анимации ключевого кадра 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?

http://jsfiddle.net/d0yhve8y/

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;
}

сверху вниз:

  1. создать вращений. Для этого есть два... один для стрелки вниз и один для стрелки вверх. Нужны две стрелки, потому что после вращения они возвращаются в свое естественное состояние. Так, стрелка вниз запускает и вращает вниз, а стрелка вверх начинает вниз и вращается.
  2. создайте маленькие стрелки. Это прямая реализация:: before
  3. ставим анимацию на этикетке. Нет ничего особенного, там за исключением того, что продолжительность анимации составляет 1мс.
  4. мышь управляет скоростью анимации. Когда мышь нависает над элементом, продолжительность анимации устанавливается в достаточное время, чтобы кажется гладким.

работы на моем сайте:!--3-->


есть ли способ сделать этот чистый 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);