2017-01-22 7 views
0

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

HTML:

<input type="checkbox" id="switch" name="switch"> 
<label for="switch" id="switch-button">Click me!</label> 

<div id="txt"> 
<p>Menu element 1</p> 
<p>Menu element 2</p> 
<p>Menu element 3</p> 
<p>Menu element 4</p> 
</div> 

CSS:

#switch  { display: none; } 
#switch-button { display: block; } 
#txt   { max-height: 400px; } 

#switch ~ #txt { 
    transition: 1s max-height 0s; 
} 
#switch:not(:checked) ~ #txt { 
    max-height: 0px; 
    overflow: hidden; 
} 
#switch:checked ~ #txt { 
    max-height: 400px; 
} 

https://jsfiddle.net/s1237n9h/8/

Проблема возникает в: Chrome, Firefox, Android браузера, Edge.

+0

Ни код, который вы отправили, ни предоставленная ссылка [https://jsfiddle.net/s1237n9h/3/](https://jsfiddle.net/s1237n9h/3/) не вызывают описанный эффект в любом из перечисленных браузеров, кроме AB (которые я не могу проверить прямо сейчас). Пожалуйста, предоставьте [mcve] описанной проблемы. В текущей форме это не *** проверяется ***. –

+0

Выберите последнюю версию: https://jsfiddle.net/s1237n9h/8/ – SirPL

ответ

2

Задержка связана с тем, что вы переход от max-height: 400px к max-height: 0 но ваш контейнер имеет только 72px в высоту.

Поэтому вы не можете наблюдать анимацию из 400px в 72px, но только после того, как max-height анимированный ниже фактического height вашего элемента. Если вы соответствуете height элемента и max-height, вы будете наблюдать за переходом полностью, без каких-либо визуальных задержки.

+0

Как я могу избавиться от этого отставания без установки 'max-height: 72px'? Это значение может меняться в зависимости от доступных шрифтов в браузере ... – SirPL

+1

В настоящее время нет чистого решения CSS для анимации 'max-height' динамически от' 100% 'до' 0'. Или, если он существует, я не знаю об этом. Но обходные пути существуют. Один из вариантов - использовать относительно позиционную оболочку с 'overflow: hidden' и анимировать верхнее свойство единственного дочернего элемента от' 0' до '-100%'. Вы также можете анимировать 'transform: scale()' от '1' до' 0'. Но, как практическое решение, я считаю, что полагаюсь на 'speed.js' (который также обеспечивает скорость 60 кадров в секунду для всех анимаций), потому что он достаточно умен, чтобы вычислять' 100% 'в px для' max-height' и разрешать плавное переходит на «0». –

1

Добавить transition-delay: -.5s; в

#switch:not(:checked) ~ #txt { 

Результат:

#switch:not(:checked) ~ #txt { 
     max-height: 0px; 
     overflow: hidden; 
     width: 100%; 
     -webkit-transition: 1s max-height 0s; 
     -moz-transition: 1s max-height 0s; 
     transition: 1s max-height 0s; 
    transition-delay: -.5s; 
    } 
+0

Это действительно работает. Не могли бы вы объяснить с теоретической точки зрения, почему это необходимо, потому что я не вижу никакого логического объяснения. Спасибо! – SirPL

+0

Чтобы быть абсолютно честным, я понятия не имею, почему это так, кажется, что оно почему-то добавляет задержку .5 к переходу, но, как сказано, я не понимаю, почему, поскольку я сам начинаю. Я надеюсь, что кто-то с большим опытом сможет объяснить это :) – Omnitored

0

Проблема заключается в том, что вы используете max-height, чтобы попытаться контролировать высоту выпадающего списка, чтобы он был только высок, так как он должен отображаться в пунктах меню. В этом случае он отображается как 72px. Тем не менее, браузер все еще пытается сделать переход на max-height400px.

Когда меню открывается, переход не выглядит лагги, потому что он начинается сразу, но время, которое браузер рассчитывает для завершения перехода, фактически основан на max-height400px. Вот почему переход выглядит так, как будто это происходит «быстрее», чем 1 секунда, потому что он показывает главное меню 72px примерно за четверть секунды, а затем перекрывает высоту элемента, но переход продолжается после этого до 400px. Обратное выглядит лагги, потому что браузер фактически пытается «спрятать» пиксели от 400 до 72, прежде чем скрывать фактический визуализируемый элемент.

Сравните свою версию с этим ниже, где переход занимает 5 секунд. Нажмите, чтобы открыть меню, а затем подождите 5 секунд. Затем нажмите, чтобы закрыть его. Вы увидите, что переход не начинается, пока не пройдет около 4 секунд. В течение этого времени переход происходит из пикселей с 400 по 72, а затем визуализируемый элемент скрывается примерно через 1 секунду.

JS Fiddle with 5s transition

Если вы делаете это с чистой высоты (не то, что вы хотите, так как он не будет контролировать высоту <div>) вы будете видеть все работает нормально.

JS Fiddle with height transition

Так, чтобы ответить на ваш вопрос, переход не лага, но при попытке перейти только max-height таким способом делает вид, что путь.

+0

Вы ошибочно полагаете, что браузер *** пытается *** оживить 'max-height' (но не получается). На самом деле *** преуспевает ***. Значение свойства 'max-height' на элементе фактически плавно переходит полностью до 400px и обратно. Вы можете проверить это, установив 'height: 400px' на элемент. –

+0

@AndreiGheorghiu Я не утверждал, что он пытается и терпит неудачу. Я сказал точно, что вы только что сказали. Процитировать самого себя: «переход на самом деле продолжается после этого всего до 400 пикселей», а также позже «переход происходит из пикселей с 400 по 72». Где я сказал, что он пытается и терпит неудачу? – skyline3000

+0

Открытие * Тем не менее, браузер ** все еще пытается ** выполнить переход по 'max-height'' 400px' * и заканчивать * переход не отсталый, но ** попытка ** перехода только с ... * немного вводят в заблуждение, и можно сделать вывод, что вы подразумеваете анимацию *** «попробовал» *** и не удалось. По крайней мере, так я его прочитал. Вот почему я сделал комментарий. Я просто хотел уточнить, что он не пробовал, но преуспел. Надеюсь, меня не поймут. Ура! –

 Смежные вопросы

  • Нет связанных вопросов^_^