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

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

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

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

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

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

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

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

Ответы [ 31 ]

1 голос
/ 31 августа 2012

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

Вы можете сделать это с событиями перехода, поэтому вы создаете 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 голос
/ 29 мая 2019

Так же просто, как:)

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

заставить его исчезнуть, а затем сделать его высотой 0; Также обязательно используйте форварды, чтобы они оставались в конечном состоянии.

1 голос
/ 26 июля 2010

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

0 голосов
/ 26 октября 2018

Если вы используете 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>

Конечно, вы могли бы просто использовать функции jQuery .fadeIn() и .fadeOut(), но преимущество установки классов в том случае, если вы хотитепереход к отображаемому значению, отличному от block (как по умолчанию для .fadeIn() и .fadeOut()).

Здесь я перехожу к отображению flex с хорошим эффектом затухания.

0 голосов
/ 29 апреля 2019

У меня была похожая проблема, на которую я не мог найти ответ. Несколько поисков в Google позже привели меня сюда. Учитывая, что я не нашел простой ответ, на который надеялся, я наткнулся на решение, которое было бы элегантным и эффективным.

Оказывается, свойство CSS visibility имеет значение collapse, которое обычно используется для элементов таблицы. Однако, если он используется с любыми другими элементами, он фактически визуализирует их как hidden , почти так же, как 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 голосов
/ 23 января 2013

Вы можете просто использовать 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 голосов
/ 24 июля 2013

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

.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 голосов
/ 15 июня 2016

Вы можете заставить это работать так, как вы ожидали - используя отображение, - но вам нужно настроить браузер, чтобы заставить его работать, используя либо 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);
}

Ключ регулирует свойство display.Удаляя скрытый класс, затем ожидая 50 мс, , затем , начиная переход с помощью добавленного класса, мы получаем его, чтобы он появлялся, а затем расширялся, как мы хотели, вместо того, чтобы просто показывать на экране без какой-либо анимации.Подобное происходит и в другом направлении, за исключением того, что мы ждем, пока анимация не закончится, прежде чем применять скрытое.

Примечание: я злоупотребляю .animate(maxWidth) здесь, чтобы избежать setTimeout условий гонки.setTimeout быстро вносит скрытые ошибки, когда вы или кто-то другой обнаруживает код, не подозревая об этом..animate() можно легко убить с помощью .stop().Я просто использую его, чтобы поместить задержку в 50 мс или 2000 мс в стандартную очередь fx, где ее легко найти / решить с помощью других кодеров, работающих над этим.

0 голосов
/ 16 июля 2017

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

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

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

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

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

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

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

...