CSS-переход с видимостью не работает

104

В скрипте ниже у меня есть отдельные переходы между видимостью и непрозрачностью. Последнее работает, а первое - нет. Более того, в случае видимости время перехода интерпретируется как задержка при зависании. Происходит как в Chrome, так и в Firefox. Это ошибка?

http://jsfiddle.net/0r218mdo/3/

Случай 1:

#inner{
    visibility:hidden;
    transition:visibility 1000ms;
}
#outer:hover #inner{
    visibility:visible;
}

Случай 2:

#inner1{
    opacity:0;
    transition:opacity 1000ms;
}
#outer1:hover #inner1{
    opacity:1;
}
user4150760
источник
4
последнее работает, потому что opacityможет принимать несколько значений между 0и 1, в то время как visibilityможет быть только visibleили hidden(без промежуточных значений)
Фабрицио Кальдеран

Ответы:

151

Это не ошибка - вы можете переходить только по порядковым / вычисляемым свойствам (простой способ думать об этом - любое свойство с числовым начальным и конечным числовыми значениями ... хотя есть несколько исключений).

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

visibility в данном случае это двоичная настройка (видимый / скрытый), поэтому по истечении продолжительности перехода свойство просто переключает состояние, вы видите это как задержку, но на самом деле его можно рассматривать как последний ключевой кадр анимации перехода с промежуточные ключевые кадры не были рассчитаны (что составляет значения между скрытым / видимым? Непрозрачностью? Размерностью? Поскольку это не является явным, они не вычисляются).

opacity - это настройка значения (0–1), поэтому ключевые кадры могут быть рассчитаны по предоставленной длительности.

Список переходных (анимированных) свойств можно найти здесь

SW4
источник
7
dev.w3.org/csswg/css-transitions/#animtype-visibility указывает, что промежуточные значения отображаются на «видимые».
Бени Чернявский-Паскин
@ BeniCherniavsky-Paskin - это зависит от функции тайминга:other values of the timing function (which occur only at the start/end of the transition or as a result of cubic-bezier() functions with Y values outside of [0, 1]) map to the closer endpoint
SW4
1
Ответ SW4 вводит в заблуждение и не объясняет недоразумения относительно цели видимости.
JesseMonroy650
@ JesseMonroy650 - хотя я не решился бы опровергнуть это, это легче сделать без дополнительных доказательств для этого утверждения, было бы интересно, если бы вы могли уточнить? OP не спрашивал цель видимости (которая отличается от отображения, непрозрачности), но почему ее нельзя анимировать как свойство, а именно по указанной причине - это фактически настройка включения / выключения. Ответ заключается не в том, «что такое видимость», а в том, «почему ее нельзя анимировать»
SW4,
Мы могли бы спорить о значении OP, но я возражаю. Раздраженный постоянной (неполной) темой и невозможностью сделать эту работу, я решил исследовать ее. Во-первых, стоит отметить плохую документацию ; объяснения скудные, спецификация плохо написана (есть заметка редактора). Хотя задокументировано как animatable, на самом деле он имеет лишь несколько свойств; одно из этих свойств - время . Я скоро буду писать в блоге.
JesseMonroy650
70

Видимость можно анимировать. Проверьте это сообщение в блоге об этом: http://www.greywyvern.com/?post=337

Вы также можете увидеть это здесь: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties

Допустим, у вас есть меню, которое вы хотите плавно отображать и исчезать при наведении курсора мыши. Если вы используете opacity:0только, ваше прозрачное меню все еще будет там, и оно будет анимироваться при наведении курсора на невидимую область. Но если добавить visibility:hidden, можно устранить эту проблему:

div {
    width:100px;
    height:20px;
}
.menu {
    visibility:hidden;
    opacity:0;
    transition:visibility 0.3s linear,opacity 0.3s linear;
    
    background:#eee;
    width:100px;
    margin:0;
    padding:5px;
    list-style:none;
}
div:hover > .menu {
    visibility:visible;
    opacity:1;
}
<div>
  <a href="#">Open Menu</a>
  <ul class="menu">
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
    <li><a href="#">Item</a></li>
  </ul>
</div>

Севбан Озтюрк
источник
2
Это неправда. В статье четко показано: 1: пользователь наводит указатель мыши на элемент 2: видимость переключается на видимую 3: начинается анимация перехода непрозрачности
Бен Расико
5
И тем не менее, статья действительно достигает функционального эквивалента анимированной видимости, ловко переходя к непрозрачности. Это хорошо объясняет, почему вам все еще нужно возиться с видимостью, чтобы иметь возможность щелкать элементы «под» скрытым объектом, например, с помощью раскрывающегося меню. Но этот ответ был бы лучше, если бы он приводил пример и резюме на местном уровне . (Обрыв ссылок; я только что исправил.)
Боб Штейн
этот ответ немного вводит в заблуждение, но, тем не менее, он работал, спасибо!
JaTo
2
@ BobStein-VisiBone Я отредактировал свой ответ и привел пример. Спасибо за вашу помощь :)
Севбан Озтюрк
22

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

Это также полезное поведение, поскольку на самом деле можно представить различные визуальные эффекты, чтобы скрыть элемент. Затухание элемента - это лишь один из видов визуального эффекта, который задается с помощью непрозрачности. Другие визуальные эффекты могут перемещать элемент, например, с помощью свойства transform, также см. Http://taccgl.org/blog/css-transition-visibility.html

Часто бывает полезно комбинировать переход непрозрачности с переходом видимости! Хотя непрозрачность, кажется, работает правильно, полностью прозрачные элементы (с непрозрачностью: 0) по-прежнему получают события мыши. Так, например, ссылки на элементе, который был затемнен только с переходом непрозрачности, по-прежнему реагируют на щелчки (хотя и не видны), а ссылки за исчезнувшим элементом не работают (хотя и видны через затененный элемент). См. Http://taccgl.org/blog/css-transition-opacity-for-fade-effects.html .

Этого странного поведения можно избежать, просто используя оба перехода: переход по видимости и переход по непрозрачности. Таким образом, свойство видимости используется для отключения событий мыши для элемента, в то время как прозрачность используется для визуального эффекта. Однако следует проявлять осторожность, чтобы не скрыть элемент во время воспроизведения визуального эффекта, который в противном случае был бы невидим. Здесь становится кстати особая семантика перехода видимости. При скрытии элемента элемент остается видимым при воспроизведении визуального эффекта и впоследствии скрывается. С другой стороны, при открытии элемента переход видимости делает элемент видимым немедленно, то есть до воспроизведения визуального эффекта.

Гельмут Эммельманн
источник