Комментарии 42
Два forced layout на операцию — ну такое… Хотя сильно лучше тут, кажется, не выйдет, да (сам с подобной задачей возился полгода назад).
Реализация на javascript была исключена
Опишем обработчик события onClick для elToggle:

Лайфхак — можно просто анимировать max-height с ease-in/out в зависимости от направления.
Достаточно знать приблизительную высоту для настройки скорости.
Ничего подобного. Делаете max-height 10000px и будет плавная анимация с 0 до высоты блока и обратно. Никаких рывков и прочего. 10к конечно выглядит не супер масштабируемо но вряд ли будет меню с такой высотой.
Работу с element.style.height === '0px'
я б заменил на работу с каким-нибудь классом, например,
.is-collapsed {
height: 0;
}
А layout-триггеры можно заменить на requestAnimationFrame
(но с небольшим кроссбраузерным хаком):
function onSchedule(fn) {
/* да, здесь два requestAnimationFrame */
requestAnimationFrame(function() {
requestAnimationFrame(function() {
fn();
});
});
}
Полный пример — https://jsfiddle.net/95tnmdyr/
Jake Acrhibald показывает пример, почему нужно 2-а requestAnimationFrame
.
Конечно, в 90% случаев, думаю, обычного `max-height: 5000px` вполне хватит. Но когда Вы разрабатываете переиспользуемые компоненты с четко описаными требованиями и динамическим контентом — не факт, что Вы не будете в числе 10%.
Конечно, в 90% случаев, думаю, обычного `max-height: 5000px` вполне хватитИ какое время анимации задавать для такого max-height? Более того, при возвращении max-height:5000 => max-height:0 — будет страшный лаг во время клика. То есть у нашего списка высота, допустим, 250 пикселей. Нажимаем кнопку, оно начинает анимироваться 0.9 секунд з max-height:5000 до max-height:250, а для пользователя это выглядит как тормоза, а потом за 0.1 секунды резко скрывается. Халтура, а не решение
Вы зря проигнорировали мою ремарку про анимационные функции.
Во многих случаях достаточно уменьшают.
Да всё норм потому что: https://jsbin.com/johobicego/edit?html,css,output
Такое сырое решение подойдёт разве что в качестве заглушки: «смотрите, тут потом будет нормальная анимация закрытия, но пока и так сойдёт»
И что тут нормового?
Можете провести опрос у пользователей и спросить норм или не норм.
Они все открываются за разное, неконтролируемое время.
Время появления любого элемента напрямую зависит от его позиции. Если вы будете открывать огромный список за то же время, что и маленький, то либо на маленьком будет слишком меееедленная анимация, либо на большом она будет еле заметная.
ease-out нету ни на открытии, ни на закрытии (конечно, в коде есть, а визуально — нету).
Оно там и не надо. Или вы считаете, что все анимации должны быть ease-in-out?
Такое сырое решение подойдёт разве что в качестве заглушки: «смотрите, тут потом будет нормальная анимация закрытия, но пока и так сойдёт»
На самом деле единственная реальная, а не вымученная проблема тут — это синхронизация нескольких анимаций соседних элементов. Но она в принципе плохо решается с нелинейными анимациями.
Время появления любого элемента напрямую зависит от его позицииХуже, что оно неконтролируемое.
Оно там и не надо. Или вы считаете, что все анимации должны быть ease-in-out?Я считаю, что это должен решать разработчик, а не плохой технический костыль.
Я понимаю, притягивать за уши бизнес-требования к самому технически простому решению — это весело, но такая халтура подойдёт для продукта, которым пользуются три маргинала и большего от него уже не ожидается.
Вы преувеличиваете масштаб трагедии. Из-за чего для реализации простой вещи потратите куда больше времени на написание кода и вылавливание в нём багов. Но никто ваши старания не оценит.
Вот так звездолёты и получаются, которые то и дело ломаются, которые очень сложно поддерживать, и которые свою основную функцию выполняют абы как, потому, что разработчик большую часть времени разработки потратил не на её проработку, а на вылизывание вещей, на которые пользователю плевать — он ваше приложение открывает не на физически точные анимации любоваться.
Хорошо, что у меня нет таких проблем с качеством.
1. «Пользователям это не нужно»
2. «Этого пользователь точно не заметит»
3. «Никогда не будет такого флоу у пользователя»
4. «Такие данные никогда не придут»
5. «На этот баг никто не обратит внимание»
Вместо акцента на качестве разработчик выбирает Lazy Driven Development, а все замечания списывает на «вы просто неправильный пользователь», «и вы неправильный пользователь», пока не остаются только три правильных пользователя
На самом же деле, пользователям это оказывается нужно, пользователи всё замечает, они выбирают не те флоу, которые кажутся программисту правильными и вводят совершенно неожиданные данные, а баги оказываются критикалами.
Нормально работает. Выбирая между выкатить новую бизнес-функцию или "идеально разворачивающееся меню" почти во всех реальных бизнес случаях бизнес выберет функцию. Если это не какое-то критически важное место в системе, без которого ну совсем никак. Кода 10 строк, ломаться нечему, работает более менее — норм же. Не идеально, а приемлемо.
https://easings.net/en можно еще функцию подобрать более подходящую
window.getComputedStyle(elBlock, null).getPropertyValue("height");
Было бы очень полезно если бы вы это описали. Кстати эту строку можно заменить на эту:
elBlock.clientHeight;
height=auto
, а для перехода необходимо конкретное значение, которое получаем через scrollHeight
. Затем нужно пересчитать («применить») height
, для этого используется getComputedStyle()
(MDN: getComputedStyle).Да, действительно, можно использовать
clientHeight
, его вызов «применяет» текущее значение height
. Благодарю за совет!
Рисунок — Отличия между offsetHeight, clientHeight и scrollHeight
Никогда не понимал зачем писать рядом с нулём единицы измерения. Если скалярная величина 0, то какая нам разница чего 0. 0px? А если не указывать px, то всё пропало?
CSS-переход свойства height от 0px до auto