Почему происходит переход при отображении элемента после установки свойства, когда элемент скрыт? - PullRequest
4 голосов
/ 27 июня 2011

Живой пример можно увидеть здесь .

Красный квадрат (показывает) находится прямо над зеленым квадратом (скрыт как переполнение).Нажмите на квадрат, и оба цветных квадрата мгновенно станут полностью прозрачными.Кроме того, высота красного квадрата установлена ​​на 0;это запускает переход, но переход остается невидимым, потому что красный квадрат теперь прозрачен.

Прежде чем снова щелкнуть квадрат, изучите функцию toggle.Глядя на JavaScript, я ожидаю, что высота красного квадрата будет сброшена до исходного значения без запуска перехода.Переход должен быть подавлен, потому что свойство перехода временно установлено на none, а высота изменяется.

Теперь щелкните квадрат снова.Оба цветных квадрата мгновенно становятся полностью непрозрачными, но красный квадрат сдвигается вниз, когда его высота изменяется от 0 до исходного значения.Как будто высота, установленная встроенным стилем, не удалялась функцией toggle, пока элемент не был виден, и к тому времени свойство перехода также было сброшено.

Запуск перекомпоновки, кажется, вызываетизменение высоты будет применяться.(Раскомментируйте строку, содержащую offsetParent для проверки.) Это происходит во всех браузерах (по крайней мере, в Chrome и Safari, Firefox и Opera), поэтому мне интересно, не является ли это частью какой-то спецификации.Я проверил Модуль CSS-переходов , но безуспешно.Любые идеи, почему такое поведение происходит, и почему оно так согласованно между реализациями?

1 Ответ

4 голосов
/ 27 июня 2011

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

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

Я действительно копался в этом, но не могне придумали чистого решения, которое бы работало в трех основных механизмах компоновки с поддержкой переходов (WebKit, Gecko и Presto).Тем не менее, вот что я выяснил - надеюсь, кто-то умнее меня (или просто придет к этому свежим взглядом) может принять этот ответ и превратить его в истинное решение.

Геккон и Presto (но не WebKit!

1008 * Похоже (а я не инженер-браузер или не знаком со спецификацией), что любое текущее или предыдущее значение transition-property будет продолжать отображаться независимо от того,не должно быть.Таким образом, даже если вы изменили значение transition-property, браузер по-прежнему отображает изменение высоты в фоновом режиме, и когда вы изменяете высоту обратно, вы получаете задний конец этого.

Естьрешение: создайте transition в JavaScript (не помещайте его в таблицу стилей), удалите его (после чего правила transition не применяются к #upper где-либо в DOM), измените высоту, а затем снова добавьте его.Не идеально, но и не зависит от ошибок.

http://jsfiddle.net/grantheaslip/e3quW/

JavaScript

upper.style.removeProperty('transition');
upper.style.removeProperty('-o-transition');
upper.style.removeProperty('-moz-transition');
upper.style.removeProperty('-webkit-transition');
upper.style.removeProperty('height');
// force a reflow
// if (upper.offsetParent) { /* empty */ }
upper.style['transition'] = 'height 1000ms';
upper.style['-o-transition'] = 'height 1000ms';
upper.style['-moz-transition'] = 'height 1000ms';
upper.style['-webkit-transition'] = 'height 1000ms';

Таблица стилей

#upper {
    background-color: red;
}

WebKit (но не Gecko или Presto!)

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

Я предполагаю, что WebKit не имеет той же проблемы, что и Presto или Gecko, но вместо этого включает оптимизацию, которая собирает изменения стиля, примененные в одной и той же функции, и применяет их все сразу.Опять же, чистые предположения того, кто никогда не подходил к исходному коду WebKit или спецификации CSS3.

http://jsfiddle.net/grantheaslip/DFcg9/

JavaScript

window.setTimeout(function() {
    upper.style.removeProperty('transition-property');
    upper.style.removeProperty('-o-transition-property');
    upper.style.removeProperty('-moz-transition-property');
    upper.style.removeProperty('-webkit-transition-property');
    upper.style.removeProperty('opacity');
    lower.style.removeProperty('opacity');
}, 1);

Gecko, Presto и WebKit

Вот оба решения вместе взятые.Опять же, из-за тайм-аута, это действительно не должно использоваться.

http://jsfiddle.net/grantheaslip/N3NrB/

...