Переходы на дисплее: свойство
В настоящее время я разрабатываю "мега раскрывающееся" меню CSS - в основном обычное раскрывающееся меню только для CSS, но содержащее различные типы контента.
На данный момент кажется, что переходы CSS 3 не применяются к свойству "display", т.е. вы не можете выполнить какой-либо переход от display: none
к display: block
(или к любой комбинации).
Есть ли способ для меню второго уровня из приведенного выше примера "исчезать", когда кто-то наводит курсор на один из пунктов меню верхнего уровня?
Я знаю, что вы можете использовать переходы в свойстве visibility:
, но я не могу придумать, как это эффективно использовать.
Я также пытался использовать высоту, но это с треском провалилось.
Я также знаю, что это легко сделать с помощью JavaScript, но я хотел испытать себя на том, чтобы использовать только CSS, и я думаю, что подойду немного.
Ответы
Ответ 1
Вы можете объединить два или более переходов, и на этот раз пригодится visibility
.
div {
border: 1px solid #eee;
}
div > ul {
visibility: hidden;
opacity: 0;
transition: visibility 0s, opacity 0.5s linear;
}
div:hover > ul {
visibility: visible;
opacity: 1;
}
<div>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
Ответ 2
Вам нужно скрыть элемент другими способами, чтобы заставить это работать.
Я достиг этого эффекта, установив абсолютно <div>
и установив скрытый opacity: 0
.
Если вы даже переключите свойство display
с none
на block
, переход на другие элементы не произойдет.
Чтобы обойти это, всегда разрешайте элементу быть display: block
, но скрывайте элемент, настраивая любое из следующих средств:
- Установите для
height
значение 0
.
- Установите для
opacity
значение 0
.
- Расположите элемент снаружи рамки другого элемента с
overflow: hidden
.
Вероятно, есть и другие решения, но вы не сможете выполнить переход, если переключите элемент на display: none
. Например, вы можете попробовать что-то вроде этого:
div {
display: none;
transition: opacity 1s ease-out;
opacity: 0;
}
div.active {
opacity: 1;
display: block;
}
Но это не сработает. Исходя из моего опыта, я обнаружил, что это ничего не делает.
Из-за этого вам всегда нужно сохранять элемент display: block
- но вы можете обойти его, выполнив что-то вроде этого:
div {
transition: opacity 1s ease-out;
opacity: 0;
height: 0;
overflow: hidden;
}
div.active {
opacity: 1;
height: auto;
}
Ответ 3
На момент написания этой статьи все основные браузеры отключали переходы CSS, если вы пытаетесь изменить свойство display
, но анимации CSS по-прежнему работают нормально, поэтому мы можем использовать их в качестве обходного пути.
Пример кода (вы можете соответственно применить его к своему меню) Демонстрация:
Добавьте следующий CSS в таблицу стилей:
@-webkit-keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
Затем примените анимацию fadeIn
к ребенку при наведении на родительский элемент (и, конечно, установите display: block
):
.parent:hover .child {
display: block;
-webkit-animation: fadeIn 1s;
animation: fadeIn 1s;
}
Обновление 2019 - метод, который также поддерживает затухание:
(Требуется некоторый код JavaScript)
// We need to keep track of faded in elements so we can apply fade out later in CSS
document.addEventListener('animationstart', function (e) {
if (e.animationName === 'fade-in') {
e.target.classList.add('did-fade-in');
}
});
document.addEventListener('animationend', function (e) {
if (e.animationName === 'fade-out') {
e.target.classList.remove('did-fade-in');
}
});
div {
border: 5px solid;
padding: 10px;
}
div:hover {
border-color: red;
}
.parent .child {
display: none;
}
.parent:hover .child {
display: block;
animation: fade-in 1s;
}
.parent:not(:hover) .child.did-fade-in {
display: block;
animation: fade-out 1s;
}
@keyframes fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fade-out {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
<div class="parent">
Parent
<div class="child">
Child
</div>
</div>
Ответ 4
Я подозреваю, что причина, по которой переходы отключены, если "отображение" изменено, происходит из-за того, что на самом деле отображается. Это не изменяет ничего, что могло бы быть плавно анимированным.
"display: none;" и "видимость: скрытая"; это две совершенно разные вещи. Оба имеют эффект, делающий элемент невидимым, но с "видимостью: скрытой"; его все еще отображается в макете, но просто не заметно. Скрытый элемент по-прежнему занимает пробел и по-прежнему отображается как встроенный или как блок или блок-строка или таблица, или что-либо, что элемент "display" сообщает ему, чтобы отображать как, и соответственно занимает место. Другие элементы автоматически не перемещаются, чтобы занять это пространство. Скрытый элемент просто не отображает фактические пиксели на выходе.
"display: none", с другой стороны, фактически полностью предотвращает рендеринг элемента. Он не занимает места макета. Другие элементы, которые занимали бы какое-то или все пространство, занимаемое этим элементом, теперь настраиваются, чтобы занять это пространство, как будто элемент просто не существовал вообще.
"display" - это не просто еще один визуальный атрибут. Он устанавливает весь режим рендеринга элемента, такой как его блок, встроенный, встроенный блок, таблица, таблица-строка, таблица-ячейка, список-элемент или что-то еще! У каждого из них очень разные разметки разметки, и не было бы разумного способа оживить или плавно перевести их (попробуйте представить плавный переход от "блока" к "встроенному" или наоборот, например!).
Вот почему переходы отключены, если отображение изменяется (даже если изменение относится к или ни от "none" - "none" - это просто invisiblity, его собственный режим рендеринга элементов, что означает отсутствие рендеринга вообще!),
Ответ 5
display
не является одним из свойств, с которыми работает переход.
См. Анимационные свойства CSS для получения списка свойств CSS, к которым могут быть применены переходы. Подробнее о том, как их интерполировать, см. в модуле "Значения и единицы измерения CSS" уровня 4, "Объединение значений: интерполяция, сложение и накопление".
До было указано в 9.1. Свойства из CSS (просто закройте всплывающее окно с предупреждением)
Я также пытался использовать высоту, но это с треском провалилось.
В прошлый раз, когда мне пришлось это сделать, я использовал вместо этого max-height
, который является анимируемым свойством (хотя это было немного хаком, оно работало), но остерегайтесь, что это может быть очень опасно для сложных страниц или пользователей с низким -конечные мобильные устройства.
Ответ 6
Вместо обратных вызовов, которых нет в CSS, мы можем использовать свойство transition-delay
.
#selector {
overflow: hidden; // Hide the element content, while height = 0
height: 0; opacity: 0;
transition: height 0ms 400ms, opacity 400ms 0ms;
}
#selector.visible {
height: auto; opacity: 1;
transition: height 0ms 0ms, opacity 600ms 0ms;
}
Итак, что здесь происходит?
Когда добавлен класс visible
, и height
, и opacity
запускают анимацию без задержки (0 мс), хотя height
занимает 0 мс для завершения анимации (эквивалентно display: block
), а opacity
занимает 600 мс.
Когда класс visible
удален, opacity
запускает анимацию (задержка 0 мс, длительность 400 мс), а высота ожидает 400 мс и только затем мгновенно (0 мс) восстанавливает начальное значение (эквивалентное display: none
в обратном вызове анимации).
Обратите внимание, что этот подход лучше, чем те, которые используют visibility
. В таких случаях элемент по-прежнему занимает место на странице, и это не всегда подходит.
Дополнительные примеры см. в этой статье.
Ответ 7
Теперь вы можете добавить собственную анимацию в свойство блока.
@keyframes showNav {
from {opacity: 0;}
to {opacity: 1;}
}
.subnav-is-opened .main-nav__secondary-nav {
display: block;
animation: showNav 250ms ease-in-out both;
}
Demo
В этой демонстрации подменю изменяется с display:none
на display:block
и все еще может исчезать.
Ответ 8
Согласно Рабочий проект W3C 19 ноября 2013 г. display
не является анимированным. К счастью, visibility
является анимированным. Вы можете связать его переход с переходом непрозрачности (JSFiddle):
-
HTML:
<a href="http://example.com" id="foo">Foo</a>
<button id="hide-button">Hide</button>
<button id="show-button">Show</button>
-
CSS
#foo {
transition-property: visibility, opacity;
transition-duration: 0s, 1s;
}
#foo.hidden {
opacity: 0;
visibility: hidden;
transition-property: opacity, visibility;
transition-duration: 1s, 0s;
transition-delay: 0s, 1s;
}
-
JavaScript для тестирования:
var foo = document.getElementById('foo');
document.getElementById('hide-button').onclick = function () {
foo.className = 'hidden';
};
document.getElementById('show-button').onclick = function () {
foo.className = '';
};
Обратите внимание: если вы просто сделаете ссылку прозрачной, не установив visibility: hidden
, она останется кликабельной.
Ответ 9
Мой аккуратный JavaScript трюк , чтобы разделить весь сценарий на две разные функции!
Чтобы подготовить вещи, объявляется одна глобальная переменная и определяется один обработчик события:
var tTimeout;
element.addEventListener("transitionend", afterTransition, true);//firefox
element.addEventListener("webkitTransitionEnd", afterTransition, true);//chrome
Затем, когда я скрываю элемент, я использую что-то вроде этого:
function hide(){
element.style.opacity = 0;
}
function afterTransition(){
element.style.display = 'none';
}
Для повторного появления элемента я делаю что-то вроде этого:
function show(){
element.style.display = 'block';
tTimeout = setTimeout(timeoutShow, 100);
}
function timeoutShow(){
element.style.opacity = 1;
}
Это работает до сих пор!
Ответ 10
Изменить: отображение в этом примере не применяется.
@keyframes hide {
0% {
display: block;
opacity: 1;
}
99% {
display: block;
}
100% {
display: none;
opacity: 0;
}
}
Что происходит выше, так это то, что через 99% экрана анимации устанавливается блокировка, а непрозрачность исчезает. В последний момент для свойства display установлено значение none.
И самый важный бит - сохранить последний кадр после окончания анимации с использованием режима анимации-заливки: вперед
.hide {
animation: hide 1s linear;
animation-fill-mode: forwards;
}
Вот два примера: https://jsfiddle.net/qwnz9tqg/3/
Ответ 11
Я столкнулся с этим сегодня, с модальным position: fixed
, который я использовал повторно. Я не мог сохранить его display: none
, а затем оживить его, поскольку он просто вскочил на внешний вид, а z-index
(отрицательные значения и т.д.) Также сделал странные вещи.
Я также использовал height: 0
to height: 100%
, но он работал только тогда, когда появился модальный. Это то же самое, что если вы использовали left: -100%
или что-то еще.
Тогда мне показалось, что был простой ответ. Et voila:
Во-первых, ваш скрытый модальный. Обратите внимание, что height
есть 0
, и проверьте объявление height
в переходах... он имеет 500ms
, который длиннее моего перехода opacity
. Помните, что это влияет на переход к постепенному исчезновению: возвращение модального состояния в состояние по умолчанию.
#modal-overlay {
background: #999;
background: rgba(33,33,33,.2);
display: block;
overflow: hidden;
height: 0;
width: 100%;
position: fixed;
top: 0;
left: 0;
opacity: 0;
z-index: 1;
-webkit-transition: height 0s 500ms, opacity 300ms ease-in-out;
-moz-transition: height 0s 500ms, opacity 300ms ease-in-out;
-ms-transition: height 0s 500ms, opacity 300ms ease-in-out;
-o-transition: height 0s 500ms, opacity 300ms ease-in-out;
transition: height 0s 500ms, opacity 300ms ease-in-out;
}
Во-вторых, ваш видимый модальный. Предположим, что вы устанавливаете .modal-active
в body
. Теперь height
- 100%
, и мой переход также изменился. Я хочу, чтобы height
был немедленно изменен, а opacity
- 300ms
.
.modal-active #modal-overlay {
height: 100%;
opacity: 1;
z-index: 90000;
-webkit-transition: height 0s, opacity 300ms ease-in-out;
-moz-transition: height 0s, opacity 300ms ease-in-out;
-ms-transition: height 0s, opacity 300ms ease-in-out;
-o-transition: height 0s, opacity 300ms ease-in-out;
transition: height 0s, opacity 300ms ease-in-out;
}
Что он, он работает как шарм.
Ответ 12
Принимая во внимание некоторые из этих ответов и некоторые предложения в других местах, следующее прекрасно подходит для всплывающих меню (я использую это, в частности, с Bootstrap 3):
nav .dropdown-menu {
display: block;
overflow: hidden;
max-height: 0;
opacity: 0;
transition: max-height 500ms, opacity 300ms;
-webkit-transition: max-height 500ms, opacity 300ms;
}
nav .dropdown:hover .dropdown-menu {
max-height: 500px;
opacity: 1;
transition: max-height 0, opacity 300ms;
-webkit-transition: max-height 0, opacity 300ms;
}
Вы также можете использовать height
вместо max-height
, если вы указали оба значения, поскольку height:auto
недопустимо с transition
s. Значение наведения max-height
должно быть больше, чем height
меню.
Ответ 13
Измените overflow:hidden
на overflow:visible
. Он работает лучше. Я использую вот так:
#menu ul li ul {
background-color:#fe1c1c;
width:85px;
height:0px;
opacity:0;
box-shadow:1px 3px 10px #000000;
border-radius:3px;
z-index:1;
-webkit-transition:all 0.5s ease;
-moz-transition:all 0.6s ease;
}
#menu ul li:hover ul {
overflow:visible;
opacity:1;
height:140px;
}
visible
лучше, потому что overflow:hidden
действует точно так же, как a display:none
.
Ответ 14
JavaScript не требуется, и не требуется огромная максимальная высота. Вместо этого установите max-height
на свои текстовые элементы и используйте относительную единицу шрифта, такую как rem
или em
. Таким образом, вы можете установить максимальную высоту больше, чем ваш контейнер, избегая задержки или "всплывающих окон" при закрытии меню:
HTML
<nav>
<input type="checkbox" />
<ul>
<li>Link 1</li>
<li>Link 1</li>
<li>Link 1</li>
<li>Link 1</li>
</ul>
</nav>
CSS
nav input + ul li { // Notice I set max-height on li, not ul
max-height: 0;
}
nav input:checked + ul li {
max-height: 3rem; // A little bigger to allow for text-wrapping - but not outrageous
}
Смотрите пример здесь:http://codepen.io/mindfullsilence/pen/DtzjE
Ответ 15
После того, как принятый ответ от Гильермо был написан, CSS
Спецификация перехода от 2012-04-03 изменила поведение перехода видимости, и теперь можно решить эту проблему более коротким способом, без использования перехода-задержки:
.myclass > div {
transition:visibility 1s, opacity 1s;
visibility:hidden; opacity:0
}
.myclass:hover > div
{ visibility:visible; opacity:1 }
Время выполнения, указанное для обоих переходов, обычно должно быть
идентичны (хотя немного больше времени для видимости не проблема).
Работающую версию см. в моем блоге Видимость перехода CSS.
W.r.t. заголовок вопроса "Переходы на дисплее: собственность" и в ответ на комментарии Руи Маркеса и Джоша к принятому ответу:
Это решение работает в случаях , где оно не имеет значения, если дисплей или
свойство видимости используется (как, вероятно, имело место в этом вопросе).
Он не будет полностью удалять элемент как display:none
, просто сделает его невидимым, но он все равно останется в потоке документа и повлияет на положение следующих элементов.
Переходы, которые полностью удаляют элемент, подобный display:none
, могут быть выполнены с использованием высоты (как указано в других ответах и комментариях), максимальной высоты или поля сверху/снизу, но также смотрите
Как я могу высоту перехода: 0; по высоте: авто; с использованием CSS? и моего сообщения в блоге Временные решения для переходов CSS в свойствах экрана и высоты.
В ответ на комментарий от Джорджа Милло:
Требуются оба свойства и оба перехода: свойство непрозрачности
используется для создания анимации постепенного появления и исчезновения, а также видимости
свойство, чтобы элемент не реагировал на мышь
Мероприятия. Необходимы переходы на непрозрачность для визуального эффекта и на
видимость, чтобы отложить скрытие, пока не закончится исчезновение.
Ответ 16
Я несколько раз сталкивался с этой проблемой, и теперь просто пошел с:
.block {
opacity: 1;
transition: opacity 250ms ease;
}
.block--invisible {
pointer-events: none;
opacity: 0;
}
Добавив block--invisible
все элементы не будут доступны для кликов, но все элементы за ним будут связаны с pointer-events:none
них не поддерживается всеми основными браузерами (без IE <11).
Ответ 17
Я подозреваю, что любой, кто только начинает переходы CSS, быстро обнаруживает, что они не работают, если вы одновременно изменяете свойство display (block/none). Один из обходных путей, который еще не был упомянут, заключается в том, что вы можете продолжать использовать display:block/none
, чтобы скрыть/показать элемент, но установите его непрозрачность равной 0, чтобы даже когда он display:block
, он все еще невидим.
Затем, чтобы добавить его, добавьте еще один класс CSS, например "on", который устанавливает непрозрачность равной 1 и определяет переход для непрозрачности. Как вы могли себе представить, вам придется использовать JavaScript, чтобы добавить этот класс "on" к элементу, но по крайней мере вы все еще используете CSS для фактического перехода.
Постскриптум Если вы оказались в ситуации, когда вам нужно сделать и display:block
, и добавить класс "on", в то же время, отложите последнее, используя setTimeout. В противном случае браузер просто видит обе вещи как происходящие одновременно и отключает переход.
Ответ 18
Наконец-то я нашел решение для меня, объединив opacity
с position absolute
(чтобы не занимать пространство, когда скрыто).
.toggle {
opacity: 0;
position: absolute;
transition: opacity 0.8s;
}
.parent:hover .toggle {
opacity: 1;
position: static;
}
Ответ 19
Это так же просто, как следующее :)
@keyframes fadeout {
0% { opacity: 1; height: auto; }
90% { opacity: 0; height: auto; }
100% { opacity: 0; height: 0;
}
animation: fadeout linear 0.5s 1 normal forwards !important;
Получите, чтобы это исчезло, и затем сделайте это height 0;
. Также обязательно используйте форварды, чтобы они оставались в конечном состоянии.
Ответ 20
Я думаю, что у SalmanPK самый близкий ответ. Он выцветает или исчезает с помощью следующих CSS-анимаций. Однако свойство display не анимируется плавно, только непрозрачность.
@-webkit-keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@-webkit-keyframes fadeOut {
from { opacity: 1; }
to { opacity: 0; }
}
Если вы хотите анимировать элемент, перемещающийся из блока отображения, чтобы ничего не отображать, я не вижу, чтобы это было возможно в настоящее время только с помощью CSS. Вы должны получить высоту и использовать CSS-анимацию, чтобы уменьшить высоту. Это возможно с помощью CSS, как показано в примере ниже, но было бы сложно узнать точные значения высоты, которые необходимо анимировать для элемента.
jsFiddle пример
CSS
@-webkit-keyframes pushDown {
0% {
height: 10em;
}
25% {
height: 7.5em;
}
50% {
height: 5em;
}
75% {
height: 2.5em;
}
100% {
height: 0em;
}
}
.push-down {
-webkit-animation: pushDown 2s forwards linear;
}
JavaScript
var element = document.getElementById("element");
// Push item down
element.className = element.className + " push-down";
Ответ 21
Это решение имеет отличную совместимость, и я еще не видел его:
.hidden-element {
position: absolute;
z-index: -1;
pointer-events: none;
visibility: hidden;
opacity: 0;
transition: visibility 0s, opacity .5s ease-out;
}
.hidden-element.visible {
position: static;
z-index: auto;
pointer-events: auto;
visibility: visible;
opacity: 1;
}
Пояснение: он использует трюк visibility: hidden
(который совместим с "покажи и анимируй" за один шаг), но он использует комбинацию position: absolute; z-index: -1; pointer-events: none;
, чтобы убедиться, что скрытый контейнер не занимает места и не отвечает на взаимодействие с пользователем.
Ответ 22
Вместо использования display
вы можете хранить элемент "вне экрана" до тех пор, пока он вам не понадобится, а затем установить его положение в нужном вам месте и одновременно преобразовать его. Это вызывает целый ряд других проблем дизайна, поэтому ваш пробег может отличаться.
Вы, вероятно, не захотите использовать display
в любом случае, так как вы хотите, чтобы контент был доступен для программ чтения с экрана, которые по большей части стараются подчиняться правилам для наглядности - то есть, если он не должен быть видимым для глаз, он не будет отображаться как контент для агента.
Ответ 23
Самое простое универсальное решение проблемы: не стесняйтесь указывать display:none
в своем CSS, однако вам придется изменить его на block
(или что-то еще), используя JavaScript, а затем вам также нужно будет добавить класс в ваш элемент, о котором идет речь, который фактически выполняет переход с помощью setTimeout(). Это все.
Т.е.:
<style>
#el {
display: none;
opacity: 0;
}
#el.auto-fade-in {
opacity: 1;
transition: all 1s ease-out; /* Future, future, please come sooner! */
-webkit-transition: all 1s ease-out;
-moz-transition: all 1s ease-out;
-o-transition: all 1s ease-out;
}
</style>
<div id=el>Well, well, well</div>
<script>
var el = document.getElementById('el');
el.style.display = 'block';
setTimeout(function () { el.className = 'auto-fade-in' }, 0);
</script>
Это было проверено в последних нормальных браузерах. Очевидно, что это не должно работать в Internet Explorer 9 или более ранней версии.
Ответ 24
Вы можете заставить это работать так, как вы ожидали - используя отображение, - но вам нужно настроить браузер, чтобы заставить его работать, используя либо Javascript, либо, как другие предлагали причудливый трюк с одним тегом внутри другого. Мне плевать на внутренний тег, так как он еще больше усложняет CSS и размеры, поэтому вот решение Javascript:
https://jsfiddle.net/b9chris/hweyecu4/17/
Начиная с поля вроде:
<div id="box" class="hidden">Lorem</div>
Скрытая коробка.
div.hidden {
display: none;
}
#box {
transition: opacity 1s;
}
Мы собираемся использовать трюк, найденный в соответствующем вопросе, проверяя offsetHeight, чтобы мгновенно регулировать скорость браузера:
fooobar.com/questions/40393/...
Во-первых, библиотека, формализующая вышеупомянутый трюк:
$.fn.noTrnsn = function () {
return this.each(function (i, tag) {
tag.style.transition = 'none';
});
};
$.fn.resumeTrnsn = function () {
return this.each(function (i, tag) {
tag.offsetHeight;
tag.style.transition = null;
});
};
Далее, мы собираемся использовать его, чтобы раскрыть коробку, и затемнить ее:
$('#button').on('click', function() {
var tag = $('#box');
if (tag.hasClass('hidden'))
tag.noTrnsn().removeClass('hidden')
.css({ opacity: 0 })
.resumeTrnsn().css({ opacity: 1 });
else
tag.css({ opacity: 0 });
});
Это исчезает и исчезает. Итак, .noTrnsn()
отключает переходы, затем мы удаляем класс hidden
, который переворачивает display
из none
в значение по умолчанию, block
. Затем мы устанавливаем непрозрачность на 0, чтобы подготовиться к появлению. Теперь, когда мы установили сцену, мы снова включаем переходы с помощью .resumeTrnsn()
. И, наконец, начните переход, установив непрозрачность на 1.
Без библиотеки и отображение, и изменение непрозрачности могли бы привести к нежелательным результатам. Если бы мы просто удалили вызовы библиотеки, мы бы вообще не получили никаких переходов.
Обратите внимание, что вышеприведенное не устанавливает display снова в none в конце анимации затухания. Мы можем полюбоваться, хотя. Давайте сделаем это с тем, который вырастает и растет в высоту от 0.
Необычные!
https://jsfiddle.net/b9chris/hweyecu4/22/
#box {
transition: height 1s, opacity 1s;
}
Сейчас мы переносим как высоту, так и непрозрачность. Обратите внимание, что мы не устанавливаем высоту, что означает, что это значение по умолчанию, auto
. Традиционно это не может быть перенесено - переход от автоматического значения к пикселю (например, 0) не даст вам никакого перехода. Мы собираемся обойти это с библиотекой и еще одним библиотечным методом:
$.fn.wait = function (time, fn) {
if (time)
this.delay(time);
if (!fn)
return this;
var _this = this;
return this.queue(function (n) {
fn.call(_this);
n();
});
};
Это удобный метод, который позволяет нам участвовать в существующей fx/анимационной очереди jQuery, не требуя какой-либо инфраструктуры анимации, которая теперь исключена в jQuery 3.x. Я не собираюсь объяснять, как работает jQuery, но достаточно сказать, что сантехника .queue()
и .stop()
, которую предоставляет jQuery, помогает нам не допустить, чтобы наши анимации наступали друг на друга.
Позвольте анимировать эффект слайда.
$('#button').on('click', function() {
var tag = $('#box');
if (tag.hasClass('hidden')) {
// Open it
// Measure it
tag.stop().noTrnsn().removeClass('hidden').css({
opacity: 0, height: 'auto'
});
var h = tag.height();
tag.css({ height: 0 }).resumeTrnsn()
// Animate it
.css({ opacity: 1, height: h })
.wait(1000, function() {
tag.css({ height: 'auto' });
});
} else {
// Close it
// Measure it
var h = tag.noTrnsn().height();
tag.stop().css({ height: h })
.resumeTrnsn()
// Animate it
.css({ opacity: 0, height: 0 })
.wait(1000, function() {
tag.addClass('hidden');
});
}
});
Этот код начинается с проверки #box
и скрыт ли он в данный момент, путем проверки его класса. Но он выполняет больше, используя библиотечный вызов wait()
, добавляя класс hidden
в конце анимации скольжения/затухания, которую вы ожидаете найти, если она на самом деле скрыта - чего-то, что в приведенном выше простом примере не могло бы быть делать. Это также позволяет снова и снова отображать/скрывать элемент, что было ошибкой в предыдущем примере, поскольку скрытый класс никогда не восстанавливался.
Вы также можете видеть изменения CSS и класса, вызываемые после .noTrnsn()
, чтобы в целом установить сцену для анимации, включая измерение, например, измерение конечной высоты #box
, не показывая это пользователю, перед вызовом .resumeTrnsn()
и анимировать его от этого полностью установленного этапа до его целевых значений CSS.
Старый ответ
https://jsfiddle.net/b9chris/hweyecu4/1/
Вы можете переключать его по клику с помощью:
function toggleTransition() {
var el = $("div.box1");
if (el.length) {
el[0].className = "box";
el.stop().css({maxWidth: 10000}).animate({maxWidth: 10001}, 2000, function() {
el[0].className = "box hidden";
});
} else {
el = $("div.box");
el[0].className = "box";
el.stop().css({maxWidth: 10001}).animate({maxWidth: 10000}, 50, function() {
el[0].className = "box box1";
});
}
return el;
}
someTag.click(toggleTransition);
CSS - это то, что вы догадались бы:
.hidden {
display: none;
}
.box {
width: 100px;
height: 100px;
background-color: blue;
color: yellow;
font-size: 18px;
left: 20px;
top: 20px;
position: absolute;
-webkit-transform-origin: 0 50%;
transform-origin: 0 50%;
-webkit-transform: scale(.2);
transform: scale(.2);
-webkit-transition: transform 2s;
transition: transform 2s;
}
.box1{
-webkit-transform: scale(1);
transform: scale(1);
}
Клавиша регулирует свойство экрана. Удаляя скрытый класс и затем ожидая 50 мс, затем начиная переход с помощью добавленного класса, мы заставляем его появляться и затем расширяться, как мы хотели, вместо того, чтобы просто перелистывать экран без какой-либо анимации. Подобное происходит иначе, за исключением того, что мы ждем, пока анимация не закончится, прежде чем применять скрытый.
Примечание: я злоупотребляю .animate(maxWidth)
здесь, чтобы избежать условий гонки setTimeout
. setTimeout
быстро вносит скрытые ошибки, когда вы или кто-то другой обнаруживает код, не подозревая об этом. .animate()
может быть легко убит с помощью .stop()
. Я просто использую его, чтобы поместить задержку в 50 мс или 2000 мс в стандартную очередь fx, где ее легко найти/разрешить с помощью других кодеров, работающих над этим.
Ответ 25
Вы можете сделать это с событиями перехода, поэтому вы создаете два CSS-класса для перехода, один из которых содержит анимацию, а другой - отображение состояния отсутствия. И вы переключаете их после окончания анимации? В моем случае я могу снова показать div, если нажму кнопку, и удаляю оба класса.
Попробуйте фрагмент ниже...
$(document).ready(function() {
// Assign transition event
$("table").on("animationend webkitAnimationEnd", ".visibility_switch_off", function(event) {
// We check if this is the same animation we want
if (event.originalEvent.animationName == "col_hide_anim") {
// After the animation we assign this new class that basically hides the elements.
$(this).addClass("animation-helper-display-none");
}
});
$("button").click(function(event) {
$("table tr .hide-col").toggleClass(function() {
// We switch the animation class in a toggle fashion...
// and we know in that after the animation end, there
// is will the animation-helper-display-none extra
// class, that we nee to remove, when we want to
// show the elements again, depending on the toggle
// state, so we create a relation between them.
if ($(this).is(".animation-helper-display-none")) {
// I'm toggling and there is already the above class, then
// what we want it to show the elements , so we remove
// both classes...
return "visibility_switch_off animation-helper-display-none";
}
else {
// Here we just want to hide the elements, so we just
// add the animation class, the other will be added
// later be the animationend event...
return "visibility_switch_off";
}
});
});
});
table th {
background-color: grey;
}
table td {
background-color: white;
padding: 5px;
}
.animation-helper-display-none {
display: none;
}
table tr .visibility_switch_off {
animation-fill-mode: forwards;
animation-name: col_hide_anim;
animation-duration: 1s;
}
@-webkit-keyframes col_hide_anim {
0% {opacity: 1;}
100% {opacity: 0;}
}
@-moz-keyframes col_hide_anim {
0% {opacity: 1;}
100% {opacity: 0;}
}
@-o-keyframes col_hide_anim {
0% {opacity: 1;}
100% {opacity: 0;}
}
@keyframes col_hide_anim {
0% {opacity: 1;}
100% {opacity: 0;}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<theader>
<tr>
<th>Name</th>
<th class='hide-col'>Age</th>
<th>Country</th>
</tr>
</theader>
<tbody>
<tr>
<td>Name</td>
<td class='hide-col'>Age</td>
<td>Country</td>
</tr>
</tbody>
</table>
<button>Switch - Hide Age column with fadeout animation and display none after</button>
Ответ 26
У меня была похожая проблема, на которую я не мог найти ответ. Несколько поисков в Google позже привели меня сюда. Учитывая, что я не нашел простой ответ, на который надеялся, я наткнулся на решение, которое было бы элегантным и эффективным.
Оказывается, у свойства CSS visibility
есть collapse
значений, которое обычно используется для элементов таблицы. Однако, если он используется с любыми другими элементами, он эффективно отображает их как скрытые, почти так же, как display: hidden
но с добавленной возможностью, что элемент не занимает никакого пространства, и вы все равно можете анимировать рассматриваемый элемент.
Ниже приведен простой пример этого в действии.
function toggleVisibility() {
let exampleElement = document.querySelector('span');
if (exampleElement.classList.contains('visible')) {
return;
}
exampleElement.innerHTML = 'I will not take up space!';
exampleElement.classList.toggle('hidden');
exampleElement.classList.toggle('visible');
setTimeout(() => {
exampleElement.classList.toggle('visible');
exampleElement.classList.toggle('hidden');
}, 3000);
}
#main {
display: flex;
flex-direction: column;
width: 300px;
text-align: center;
}
.hidden {
visibility: collapse;
opacity: 0;
transition: visibility 2s, opacity 2s linear;
}
.visible {
visibility: visible;
opacity: 1;
transition: visibility 0.5s, opacity 0.5s linear;
}
<div id="main">
<button onclick="toggleVisibility()">Click Me!</button>
<span class="hidden"></span>
<span>I will get pushed back up...</span>
</div>
Ответ 27
Вы можете просто использовать CSS видимость: скрытый/видимый вместо отображения: нет/блок
div {
visibility:hidden;
-webkit-transition: opacity 1s ease-out;
-moz-transition: opacity 1s ease-out;
-o-transition: opacity 1s ease-out;
transition: opacity 1s ease-out;
opacity: 0;
}
parent:hover > div {
opacity: 1;
visibility: visible;
}
Ответ 28
Вы также можете использовать это:
.dropdown {
height: 0px;
width: 0px;
opacity: .0;
color: white;
}
.dropdown:hover {
height: 20px;
width: 50px;
opacity: 1;
transition: opacity 200ms;
/* Safari */
-webkit-transition: opacity 200ms;
}
Ответ 29
Я запустил скелетный проект с открытым исходным кодом под названием Toggle Display Animate.
Этот каркасный помощник позволит вам легко имитировать jQuery show/hide, но с анимацией перехода в CSS 3.
Он использует переключатели классов, так что вы можете использовать любые методы CSS для любых элементов, кроме display: none | block | table | inline и т.д., А также другие альтернативные варианты использования, которые можно придумать.
Его основное предназначение - для состояний переключения элементов, и оно поддерживает состояние возврата, при котором скрытие объекта позволяет запускать ключевой кадр в обратном порядке или воспроизводить альтернативную анимацию для скрытия элемента.
Большая часть разметки для концепции, над которой я работаю, - это CSS, и на самом деле очень мало JavaScript используется.
Здесь есть демо: http://marcnewton.co.uk/projects/toggle-display-animate/
Ответ 30
Если вы используете jQuery для установки ваших классов, это будет работать на 100%:
$(document).ready(function() {
$('button').click(function() {
var container = $('.container');
if (!container.hasClass('active')) {
container.addClass('show').outerWidth();
container.addClass('active');
}
else {
container.removeClass('active').one('transitionend', function() {
container.removeClass('show');
});
}
});
});
.container {
display: none;
opacity: 0;
transition: opacity 0.3s ease;
}
.container.show {
display: flex;
}
.container.active {
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button">Toggle</button>
<div class="container">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>