Переход сразу после анимации

На моем элементе у меня работает CSS-анимация, если у нее есть определенный класс (wiggle), и переход, как только у него есть другой (right):

<div class = "outer">
  <div class = "inner wiggle"></div>
</div>
@keyframes wiggle {
  from {
    left: 10%;
  }
  50% {
    left: 30%;
  }
  to {
    left: 10%;
  }
}

.inner {
  left: 0;

  &.wiggle {
    animation: wiggle 2s infinite;
  }

  &.right {
    left: 90%;
    transition: left 2s;
  }
}

Теперь, если удалить класс wiggle и одновременно добавить right, переход не будет воспроизведен; left: 90% применяется немедленно. Однако, если между удалением первого и добавлением второго есть задержка, переход произойдет должным образом.

Вот JSFiddle, иллюстрирующий проблему.

Похоже, что при переходе из анимации значения (такие как left в данном случае) не имеют явного значения для перехода, поэтому они просто отображаются в свое окончательное состояние.

Это ожидаемое поведение, т.е. часть спецификации? Или браузеры свободны, как справиться с этим случаем?

Я тестировал последние версии Firefox и Chromium.


Разъяснение:Я в основном не ищу обходные пути, особенно не сложные, но скорее по той причине, что Зачем именно браузеры ведут себя так же, как они.

stackoverflow.com/a/33652438/9288348, stackoverflow.com/questions/33829469/… Думаю, у них такая же проблема.
Jeremy 04.04.2018 14:46

Я думаю, что это может быть ошибка в рендеринге браузера или около того, но если вам нужно решение, я могу дать вам его с transform.!

Jithin Raj P R 04.04.2018 14:52

@Jeremy, первый выглядит так, как будто он вызван тем же поведением, но не совсем той же проблемой, а второй немного отличается, по крайней мере, это решение, которое применимо в моем случае.

Cedric Reichenbach 04.04.2018 14:55

@weBBer Ну, я пытаюсь проделать то же самое и с другими свойствами, left был просто самым простым для визуализации и изолирования проблемы. Например, для opacity такого обходного пути нет.

Cedric Reichenbach 04.04.2018 14:57

@CedricReichenbach Я не имел в виду ту же проблему, извините. Но я думаю, что у обоих была одна и та же причина. Поскольку у вас не может быть animation и transition на одном элементе.

Jeremy 04.04.2018 14:59
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
CSS: FlexBox
CSS: FlexBox
Ранее разработчики использовали макеты с помощью Position и Float. После появления flexbox сценарий полностью изменился.
0
5
154
3

Ответы 3

Я думаю, что это может быть ошибка в рендеринге браузера или около того, но если вам нужно решение, я могу дать вам один альтернативный метод с transform.

Рабочая рабочий пример для вас:

$('#toggle').click(() => {
  $('.inner').removeClass('wiggle').addClass('right');
});
@keyframes wiggle {
  from {
    left: 10%;
  }
  50% {
    left: 30%;
  }
  to {
    left: 10%;
  }
}

.outer {
  height: 5em;
  background-color: black;
  position: relative;
}

.inner {
  height: 100%;
  width: 10%;
  position: absolute;
  transform: translate(0%);
  background-color: green;
  transition: transform 2s ease-in-out;
}

.inner.wiggle {
  animation: wiggle 2s infinite;
}

.inner.right {
  transform: translate(900%);
}
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>
  Animated
</h2>
<div class = "outer">
  <div class = "inner wiggle"></div>
</div>
<h2>
  Not animated
</h2>
<div class = "outer">
  <div class = "inner"></div>
</div>
<hr>
<button id = "toggle">
move right
</button>

Надеюсь, это было полезно для вас.

Как упоминалось в другом моем комментарии, это всего лишь обходной путь с использованием других свойств CSS. Однако я ищу общее решение, подходящее для любой собственности.

Cedric Reichenbach 04.04.2018 14:58

@CedricReichenbach понял, братан. Кто-нибудь может предложить вам общее решение, чтобы оно также могло мне помочь :)

Jithin Raj P R 04.04.2018 15:00

Его внешний вид - это ожидаемое поведение. Я думаю, что когда вы добавляете класс right с left:90%, он не может выбрать начальное значение для свойства css left. В качестве альтернативы вы можете создать еще один ключевой кадр для класса .right.

$('#toggle').click(() => {
  $('.inner').removeClass('wiggle').addClass('right');
});
@keyframes wiggle {
  0% {
    left: 10%;
  }
  50% {
    left: 30%;
  }
  100% {
    left: 10%;
  }
}

@keyframes right {
  100% {
    left: 90%;
  }
}

.outer {
  height: 5em;
  background-color: black;
  position: relative;
}

.inner {
  height: 100%;
  width: 10%;
  position: absolute;
  left: 0;
  background-color: green;
  transition: left 2s;
}

.wiggle {
  animation: wiggle 2s infinite;
}

.right {
  animation: right 2s forwards;
}
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>
  Animated
</h2>
<div class = "outer">
  <div class = "inner wiggle"></div>
</div>
<h2>
  Not animated
</h2>
<div class = "outer">
  <div class = "inner"></div>
</div>
<hr>
<button id = "toggle">
move right
</button>

Этот обходной путь может вам помочь, идея состоит в том, чтобы использовать css переменные, идея состоит в том, чтобы установить анимацию с альтернативной функцией, поэтому в этом случае нам понадобятся только From и To ... с другой стороны, нам нужно настроить и событие для каждой итерации, таким образом мы знаем, когда итерация заканчивается,

Итак, когда мы нажимаем кнопку, вы можете изменить значение переменной и удалить класс ...

$('#toggle').click(() => {
  $('.inner').addClass('right');
});
let flag = false;
$(".inner").on("animationiteration webkitAnimationIteration oAnimationIteration MSAnimationIteration", function(){ 
  flag && $(".inner").removeClass('wiggle');
  if ($(".inner").hasClass('right')) flag = true;  
});
:root {
     --from: 10%;
     --to: 30%;
   }
   
   
@keyframes wiggle {
  from {
    left: var(--from);
  }

  to {
    left: var(--to);
  }
}

.outer {
  height: 5em;
  background-color: black;
  position: relative;
}

.inner {
  height: 100%;
  width: 10%;
  position: absolute;
  transform: translate(0%);
  background-color: green;
  transition: transform 2s ease-in-out;
  left:90%;
}

.inner.wiggle {
  left:10%;
  animation: wiggle 1s infinite;
  animation-direction: alternate;
}

.inner.right {
  --to:90%;
  animation-direction: normal;
  animation-duration:2s;
}
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h2>
  Animated
</h2>
<div class = "outer">
  <div class = "inner wiggle"></div>
</div>
<hr>
<button id = "toggle">
move right
</button>

Учтите, что это ошибка, когда анимация возвращается в начальную точку ...

Хм, интересный подход; поэтому вместо того, чтобы отключать анимацию, мы просто ее изменяем. Однако это все еще обходной путь и довольно сложный. Я в основном ищу не идеальный обходной путь, а скорее по причине, почему именно он ведет себя именно так.

Cedric Reichenbach 04.04.2018 16:04

Другие вопросы по теме