it-swarm.com.ru

Переходы на дисплее: свойство

В настоящее время я разрабатываю "мега раскрывающееся" меню CSS - в основном обычное выпадающее меню только для CSS, но содержащее различные типы контента.

На данный момент кажется, что переходы CSS3 не применяются к свойству display, т. Е. Вы не можете выполнить какой-либо переход от display: none к display: block (или к любой комбинации).

Может ли кто-нибудь придумать, как меню второго уровня из приведенного выше примера может "исчезнуть", когда кто-то наводит курсор на один из пунктов меню верхнего уровня?

Я знаю, что вы можете использовать переходы в свойстве visibility:, но я не могу придумать, как это эффективно использовать.

Я также пытался использовать высоту, но это с треском провалилось.

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

Все и любые предложения приветствуются.

1243
RichardTape

Вы можете объединить два или более переходов, и 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>

(Не забудьте префиксы поставщика к свойству transition)

Более подробная информация в эта статья

1188
Guillermo

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

Я достиг этого эффекта, поместив оба <div>s абсолютно и установив скрытый opacity: 0.

Если вы даже переключите свойство display с none на block, ваш переход на другие элементы не произойдет.

Чтобы обойти это, всегда разрешайте элементу быть display: block, но скрывайте элемент, настраивая любое из этих средств:

  1. Установите height в 0.
  2. Установите opacity в 0.
  3. Расположите элемент за пределами фрейма другого элемента, который имеет 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;
}
731
Jim Jeffers

На момент написания этой статьи все основные браузеры отключали переходы 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 - метод, который также поддерживает затухание:

(Некоторые JS требуется)

// 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>
240
Salman Abbas

Я подозреваю, что причина, что переходы отключены, если "дисплей" изменен, из-за того, что фактически делает дисплей. Он не меняет все, что можно плавно анимировать.

"Display: none;" и "visibility: hidden;" - это две полностью разные вещи. И то и другое делает элемент невидимым, но с "видимостью: скрытым", он по-прежнему отображается в макете, но только не явно так. Скрытый элемент по-прежнему занимает место и по-прежнему отображается как встроенный, либо как блок, либо как inline-блок, либо как таблица, или как там говорится в элементе "display", и соответственно занимает пространство. Другие элементы не автоматически перемещаются, чтобы занять это пространство. Скрытый элемент просто не отображает свои фактические пиксели на выходе.

"Display: none", с другой стороны, на самом деле предотвращает элемент отрисовки полностью. Он не занимает любой пространство макета. Другие элементы, которые занимали бы часть или все пространство, занимаемое этим элементом, теперь корректируются, чтобы занимать это пространство, как если бы элемент просто вообще не существовал.

"Дисплей" - это не просто еще один визуальный атрибут. Он устанавливает весь режим рендеринга элемента, например, блок, встроенный блок, встроенный блок, таблица, строка таблицы, ячейка таблицы, элемент списка или любой другой! Каждый из них имеет очень разные разметки, и не было бы разумного способа анимировать или плавно переводить их (например, попытайтесь представить плавный переход от "блока" к "встроенному" или наоборот!).

Вот почему переходы отключаются, если изменяется отображение (даже если изменение "или нет" - "нет" - это не просто невидимость, это собственный режим рендеринга элементов, который вообще не означает рендеринг!),

63
Joel_MMCC

display не является одним из свойств, с которыми работает переход.

Смотрите https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties список свойств CSS, к которым могут быть применены переходы. Смотрите https://drafts.csswg.org/css-values-4/#combining-values чтобы узнать, как они интерполируются.

До CSS3 было указано в https://www.w3.org/TR/2017/WD-css-transitions-1-20171130/#animatable-css (просто закройте всплывающее окно с предупреждением)

Я также пытался использовать высоту, но это с треском провалилось.

В прошлый раз, когда мне пришлось это сделать, я использовал max-height вместо этого, что является анимируемым свойством (хотя это было немного хаком, оно работало), но остерегайтесь, что это может быть очень неудобно для сложных страниц или пользователей с низким Конечные мобильные устройства.

46
robocat

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

@keyframes showNav {
  from {opacity: 0;}
  to {opacity: 1;}
}
.subnav-is-opened .main-nav__secondary-nav {
  display: block;
  animation: showNav 250ms ease-in-out both;
}

Демо

В этой демонстрации подменю изменяется с display:none на display:block и все еще удается исчезнуть.

35
Manish Pradhan

Вместо обратных вызовов, которых нет в 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: 100%; opacity: 1;
    transition: height 0ms 0ms, opacity 600ms 0ms;
}

Итак, что здесь происходит?

  1. Когда класс visible добавляется, и height, и opacity запускают анимацию без задержки (0 мс), хотя height занимает 0 мс для завершения анимации (эквивалент display: block), а opacity занимает 600 мс.

  2. Когда класс visible удаляется, opacity запускает анимацию (задержка 0 мс, продолжительность 400 мс), а высота ожидает 400 мс, и только затем мгновенно (0 мс) восстанавливает начальное значение (эквивалент display: none в обратном вызове анимации).

Обратите внимание, что этот подход лучше, чем те, которые используют visibility. В таком случае элемент все еще занимает место на странице, и это не всегда подходит.

Для большего количества примеров, пожалуйста, смотрите это статья .

25
Webars

Согласно W3C Working Draft 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, тогда она останется кликабельной.

20
feklee

Мой хитрый трюк с 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;
}

Это работает, пока!

13
Sasa Milenkovic

Правка: не отображать ни один не применяется в этом примере.

@keyframes hide {
  0% {
    display: block;
    opacity: 1;
  }
  99% {
    display: block;
  }
  100% {
    display: none;
    opacity: 0;
  }
}

Что происходит выше, так это то, что на 99% анимации дисплей блокируется, а прозрачность исчезает. В последний момент свойство display установлено в none.

И самый важный бит - сохранить последний кадр после завершения анимации с использованием animation-fill-mode: forwards

.hide {
   animation: hide 1s linear;
   animation-fill-mode: forwards;
}

Вот два примера: https://jsfiddle.net/qwnz9tqg/3/

12
Pawel

Я столкнулся с этим сегодня, с модальным position: fixed, который я использовал повторно. Я не мог сохранить его display: none, а затем анимировать его, так как он просто появился, и z-index (отрицательные значения и т.д.) Также делал странные вещи.

Я также использовал от height: 0 до height: 100%, но он работал только тогда, когда появился модал. Это так же, как если бы вы использовали left: -100% или что-то еще.

Тогда меня поразило, что был простой ответ. И вуаля:

Во-первых, ваш скрытый модал. Обратите внимание, что 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;
}

Вот и все, это работает как шарм.

10
hotmeteor

Принимая во внимание некоторые из этих ответов и некоторые предложения в других местах, следующее отлично подходит для всплывающих меню (я использую это с 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 недопустимо с transitions. Значение при наведении курсора max-height должно быть больше, чем height меню.

8
Edyn

Измените 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 действует точно так же, как display:none.

6
jesus

После того, как принятый от Гильермо ответ был написан, CSS-переход Spec от 3 апреля 2012 года изменил поведение перехода видимости и теперь можно решить эту проблему более коротким способом , без использования перехода-задержки:

.myclass > div { 
                   transition:visibility 1s, opacity 1s; 
                   visibility:hidden;  opacity:0
               }
.myclass:hover > div 
               {   visibility:visible; opacity:1 }

Время выполнения, указанное для обоих переходов, обычно должно быть идентичным (хотя немного более длительное время для видимости не является проблемой). Работающую версию смотрите в моем блоге http://www.taccgl.org/blog/css-transition-visibility.html#visibility-opacity .

W.r.t. заголовок вопроса "Переходы на дисплее: свойство" и в ответ на комментарии Руи Маркеса и Джоша к принятому ответу: Это решение работает в случаях где это не имеет значения, если используется свойство display или visibility (как это, вероятно, имело место в этом вопросе). Он не будет полностью удалять элемент как отображаемый: ничего, просто сделает его невидимым, но он все равно останется в потоке документа и повлияет на положение следующих элементов. Переходы, которые полностью удаляют элемент, аналогичный отображаемому: ни один не может быть выполнен с использованием высоты (как указано в других ответах и ​​комментариях), max-height или margin-top/bottom, но также смотрите Как я могу изменить высоту: 0; в высоту: авто; с помощью CSS? и мой блог http://www.taccgl.org/blog/css_transition_display.html .

В ответ на комментарий от GeorgeMillo: необходимы оба свойства и оба перехода: свойство opacity используется для создания анимации постепенного появления и исчезновения, а также свойства видимости, чтобы элемент не реагировал на события мыши. Необходимы переходы по непрозрачности для визуального эффекта и по видимости, чтобы отложить скрытие до завершения затухания.

5
Helmut Emmelmann

Никакого JavaScript не требуется, и не нужно невероятно огромной максимальной высоты. Вместо этого установите максимальную высоту для ваших текстовых элементов и используйте относительную единицу шрифта, такую ​​как 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

4
mindfullsilence

Я сталкивался с этой проблемой несколько раз, и теперь просто пошел с:

.block {
  opacity: 1;
  transition: opacity 250ms ease;
}

.block--invisible {
  pointer-events: none;
  opacity: 0;
}

При добавлении класса block--invisible все элементы не будут активными, но все элементы, стоящие за ним, будут из-за pointer-events:none, который поддерживается всеми основными браузерами (нет IE <11).

4
DominikAngerer

Я подозреваю, что любой, кто только начинает переходы CSS, быстро обнаруживает, что они не работают, если вы одновременно изменяете свойство display (block/none). Одним из обходных путей, который еще не был упомянут, является то, что вы можете продолжать использовать display: block/none, чтобы скрыть/показать элемент, но установите его непрозрачность равной 0, чтобы, даже когда он отображался: block, он все еще был невидимым. Затем, чтобы добавить его, добавьте еще один класс CSS, например "on", который устанавливает непрозрачность равной 1 и определяет переход для непрозрачности. Как вы могли себе представить, вам придется использовать JavaScript, чтобы добавить этот класс "on" к элементу, но по крайней мере вы все еще используете CSS для фактического перехода.

Постскриптум Если вы оказались в ситуации, когда вам нужно одновременно выполнить display: block и добавить класс "on", одновременно отложите его, используя setTimeout. В противном случае браузер просто видит обе вещи как происходящие одновременно и отключает переход.

4
Larry Gerndt

Я наконец нашел решение для меня, комбинируя opacity с position absolute (чтобы не занимать место, когда скрыто).

.toggle {
  opacity: 0;
  position: absolute;
  transition: opacity 0.8s;
}

.parent:hover .toggle {
  opacity: 1;
  position: static;
}
3
Damjan Pavlica

Я думаю, у 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";
2
svnm

Я чувствую себя почти плохо, отвечая на вопрос с таким количеством ответов, но это решение имеет отличную совместимость, и я еще не видел его:

.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 (который совместим с "show-and-animate" за один шаг), но использует комбинацию position: absolute; z-index: -1; pointer-events: none;, чтобы убедиться, что скрытый контейнер не занимает место и не отвечает на взаимодействие с пользователем.

2
Christophe Marois

Вместо использования отображения вы можете хранить элемент "вне экрана" до тех пор, пока он вам не понадобится, а затем установить его положение в том месте, где вы хотите, и одновременно преобразовать его. Это поднимает целый ряд других проблем дизайна, так что ymmv. Вы, вероятно, не захотите использовать отображение в любом случае, так как вы хотите, чтобы контент был доступен для программ чтения с экрана, которые по большей части стараются подчиняться правилам для наглядности - то есть, если он не должен быть видимым для глаз, он не будет отображаться как контент для агента.

1
user164226

Вы можете сделать это с событиями перехода, поэтому вы создаете 2 класса CSS для перехода, один с анимацией, другой с состоянием отображения "Нет". а вы их переключаете после окончания анимации? В моем случае я могу отобразить div снова, если я нажму btn, и удаляю оба класса.

Попробуйте разрезать ниже ...

$(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")) {
        //im toggleing and there is already the above classe, 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>
1
Miguel

Самое простое универсальное решение этой проблемы: не стесняйтесь указывать 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>

Проверено в последних вменяемых браузерах. Очевидно, не должно работать в IE9 или ранее.

1
mojuba

вы также можете использовать это:

.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;
}
0
user2615031

Вы можете заставить это работать так, как вы ожидали - используя отображение, - но вам нужно настроить браузер, чтобы заставить его работать, используя либо JS, либо, как другие предлагали причудливый трюк с одним тегом внутри другого. Мне плевать на внутренний тег, так как он еще больше усложняет CSS и размеры, поэтому вот решение JS:

https://jsfiddle.net/b9chris/hweyecu4/1/

Начиная с коробки вроде:

<div class="box hidden">Lorem</div>

Скрытая коробка. Вы можете сделать это при клике:

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, где легко найти/решить другие кодеры, основанные на этом.

0
Chris Moschini

Я запустил скелетный проект с открытым исходным кодом под названием Toggle Display Animate

https://marcnewton.github.io/Toggle-Display-Animate/

Этот каркасный помощник позволит вам легко имитировать jQuery show/hide, но с помощью анимации переходов CSS3.

Он использует переключатели классов, так что вы можете использовать любые методы css, которые вы хотите для элементов, кроме display: none | block | table | inline и т.д., А также другие альтернативные варианты использования, которые можно придумать.

Его основное предназначение - для состояний переключения элементов, оно поддерживает состояние возврата, при котором скрытие объекта позволяет запускать ключевой кадр в обратном порядке или воспроизводить альтернативную анимацию для скрытия элемента.

Большая часть разметки для концепции, над которой я работаю, - это CSS, на самом деле очень мало используется JavaScript.

Здесь есть демонстрация: http://marcnewton.co.uk/projects/toggle-display-animate/

0
Marc Newton

У меня была похожая проблема, на которую я не мог найти ответ. Несколько поисков в 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>
0
Deadmano

Вы можете просто использовать css visibility: скрытый/видимый вместо display: none/block

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