Переходы на дисплее: свойство - PullRequest
1256 голосов
/ 26 июля 2010

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

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

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

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

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

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

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

Ответы [ 31 ]

10 голосов
/ 19 апреля 2012

Я столкнулся с этим сегодня, с модальностью position: fixed, которую я использовал повторно.Я не смог сохранить display: none, а затем оживить его, так как он только что появился, и z-index (отрицательные значения и т. Д.) Тоже делали странные вещи.От 1006 * до 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;
}

Second, ваш видимый модальный режим.Скажем, вы устанавливаете .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;
}

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

8 голосов
/ 23 октября 2013

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

6 голосов
/ 09 сентября 2012

Измените 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.

5 голосов
/ 13 мая 2014

Не требуется 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

5 голосов
/ 16 августа 2014

После того, как принятый ответ от Гильермо был написан, 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.

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

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

4 голосов
/ 07 августа 2017

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

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

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

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

4 голосов
/ 26 февраля 2012

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

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

3 голосов
/ 16 октября 2017

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

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

.parent:hover .toggle {
  opacity: 1;
  position: static;
}
2 голосов
/ 04 мая 2016

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

.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;, чтобы убедиться, что скрытый контейнер не занимает места и не отвечает на взаимодействие с пользователем .

2 голосов
/ 05 мая 2015

Я думаю, что у 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";
...