Animate height css animation

Анимация аккордеона и свойства height (max-height) в чистом CSS

Всем привет, недавно я изучил формы и анимации, после чего мне пришлось очень долго промучаться с анимацией Аккордеона и свойства max-height не прибегая к помощи Js в вычислениях, и сейчас я поделюсь с вами оптимальным решением.

P.S.: Java-sctipt использовался только для воздействия на класс (смены класса) , что можно сделать и с помощью псевдо классов css, например: Active.

document.getElementById("discount-entry__title-1").onclick = function () < document .getElementById("drop-up-body-discount-entry") .classList.toggle("drop-up-body_state_toggled"); document .getElementById("discount-entry__title-1") .classList.toggle("title-summary_toggled"); >; document.getElementById("shipping-tax__title-1").onclick = function () < document .getElementById("drop-up-body-shipping-tax") .classList.toggle("drop-up-body_state_toggled"); document .getElementById("shipping-tax__title-1") .classList.toggle("title-summary_toggled"); document .getElementById("shipping-tax-1") .classList.toggle("shipping-tax_mb_disabled"); >; // Код js

Было перепробовано несколько вариантов с использованием отрицательного margin-top, position: absolute и transform: translate. Но во всех вариантах, обязательно, что бы контент не было видно за рамками родительского блока, добавьте его контейнеру свойство oveflow:hidden.

Код CssКод Html

Итак, Margin-top недостаточно надежен т.к берет процентный отступ, от ширины родителя, а не его высоты. Заказчик рано или поздно может захотеть изменить блок, и в лучшем случае список будет просто быстрее заезжать наверх, из-за увеличения ширины блока, и соответственно отступа наверх, а в худшем не будет скрываться полностью, если высота станет слишком большой, а ширина не изменится. Анимация выглядит также, как и анимация через max-height, которую можно увидеть ниже

Transform: translate; адаптивен и плавно анимируется, но оставляет под собой пространство, которое нужно как-то убирать. Его можно убрать с помощью анимации, в конце которой, блок становиться абсолютно позиционированным и его становиться не видно т.к для родителя задан overflow:hidden;

/* При обычном состоянии */ .drop-up-body < transition: transform 1s; transform: translate(0, 0px); margin-top: 0; >/* При нажатии на кнопку */ .drop-up-body_state_toggled < transition: transform 1s; transform: translate(0, -110%); animation: position_hidden 0.00000000000000000001s 1s forwards; >@keyframes position_hidden < 0% < position: static; >99% < position: static; >100% < position: absolute; top: -100%; >>

Оптимальным вариантом будет свойство max-height, оно куда надежнее фиксированной высоты, и может подстраиваться под меньшее количество контента. Но и оно отказывалось работать до последнего, т.к я указывал начальное значение в процентах или оставлял max-height: auto — анимация не работала. Как оказалось при указании высоты в пикселях, все начинает работать. Значение в пикселях следует указывать с запасом как минимум в 2 раза, что добавит надежности вёрстке, так как если заказчик захочет изменить сайт и добавит контента в блок, что увеличит его высоту, у нас еще будет запас по max-height.

Единственное, что вам стоит уяснить, анимируется не текущее значение высоты блока, а разность высот между max-height в начале и после анимации. В моем случае значение max-height — 3000px, а высота контента примерно 550px. Таким образом, при сворачивании этого списка анимация начнется с задержкой, а именно, тогда когда анимация дойдет до значения высоты блока (в моем случае около 550px), т.к как сначала max-height снизится до этого числа, но блок не измениться, ведь его высота меньше max-height, а уже затем когда высота max-height, станет меньше высоты блока, блок начнет уменьшаться. При разворачивании max-height растет от нуля и изменения видны мгновенно.

Update: Если указать функцию анимации cubic-bezier(0, 1, 0, 1) к свойству transition: max-height 0.5s; Анимация будет плавной почти всегда . Это происходит потому что видимой анимации подвергаются только ее начало и конец, а остальное время анимация происходит чуть ли не мгновенно. Так в нашем случае невидимая часть блока с 3000 до 550px проанимируется очень быстро, а уже затем, пойдет видимая пользователю анимация (за совет спасибо @CyberGenius )

Я надеюсь, что мне удалось вам помочь!

Читайте также:  Python dataframe append series

Если у вас остались вопросы, критика или комментарии — обязательно напишите мне, я с радостью отвечу вам.

А сейчас я прощаюсь и желаю вам хорошего дня!

Источник

CSS-переход свойства height от 0px до auto

Хочу поделиться ещё одним способом создания css-перехода ( transition ) свойства height от 0px до auto .

Столкнулся с данной проблемой при разработке веб-компонентов TreeView и DataGrid. В TreeView решил сделать плавное развёртывание/свёртывание узлов, а в DataGrid — строки с дополнительным контентом. Почитав интернет, нашёл несколько способов реализации, основные — через свойство max-height и на javascript. Реализация на javascript была исключена — есть же css с поддержкой переходов и анимаций. Остался max-height , тем более в примерах с выпадающими меню всё работает.

В TreeView каждый узел имеет неограниченную вложенность, поэтому сразу не получится определить максимальную высоту его содержимого, да и если max-height задать очень большим, будут проблемы с анимацией перехода. Также, если развернуть дочерние узлы, высота родительского увеличится и может перекрыть max-height . Как ни крути, max-height не подходит. С DataGrid та же проблема — дополнительный контент в строке может быть любой. Нужен height:auto !

Итак, приступим к реализации перехода по свойству height от 0px до auto . Рассмотрим простой пример.

  • elBlock: HTMLDivElement — блок, который нужно развёртывать/свёртывать;
  • elToggle: HTMLButtonElement — кнопка-переключатель состояния.

Опишем обработчик события onClick для elToggle :

elToggle.addEventListener("click", () => < if (elBlock.style.height === "0px") < elBlock.style.height = `$< elBlock.scrollHeight >px` > else < elBlock.style.height = `$< elBlock.scrollHeight >px`; window.getComputedStyle(elBlock, null).getPropertyValue("height"); elBlock.style.height = "0"; > >);

Осталось добавить возврат height:auto после перехода:

elBlock.addEventListener("transitionend", () => < if (elBlock.style.height !== "0px") < elBlock.style.height = "auto" >>);

Ну вот и всё, теперь развёртывание/свёртывание блока работает как надо и не зависит от размера контента.

Рисунок 1 — Пример развёртывания/свёртывания узлов в TreeView

Стоит отметить минусы данного подхода:

  • использование javascript, хотелось бы только css;
  • во время перехода может измениться контент (его высота, scrollHeight ) и после его завершения, в случае возврата auto , высота блока резко поменяется в ту или иную сторону. Для избежания данного эффекта, необходимо отслеживать изменение scrollHeight и менять height . Как показывает практика, обычно переходы развёртывания/свёртывания занимают по 0.5 с, а за это время пользователь вряд ли успеет изменить что-то внутри, например, в случае TreeView, развернуть дочерний узел.

Источник

Using CSS Transitions on the Height Property

Little effects on our web pages can make a lot of difference on the user experience of a website. When the state of an element is changed, it’s pretty cool to have a visual effect to show that an action occurred. Thanks to CSS transitions, we have a wide range of transition effects that can be used on our HTML elements. The height of an element is one CSS property that often needs to be transitioned. Sometimes, we want a part of an element to be collapsed until it is needed. That is, when a button is clicked, the height of an element increases or decreases. See more buttons and bootstrap panels make use of this technique. Transition effects come with some frameworks like Bootstrap and JQuery. Yet, CSS transitions give you a whole lot of flexibility in transitioning the height. Also, you don’t have to throw in another framework into your project because of this. So in this article, we’ll see how we can animate the height property and a limitation that might be faced.

Читайте также:  Css position elements center

Transitioning the Height

We’ll be using a simple example to explain this. We have an article that we will collapse at first. Clicking on a see more button will increase the height of the element to show all the contents of the article. We will create a CSS class for this. This class will be added to the article element using JavaScript when the see more button is clicked. So first, we’ll add an article element to an HTML file.

  id="article"> Why You Should Care about the Ipsum Tart jelly beans croissant toffee oat cake soufflé gingerbread. Toffee powder cheesecake soufflé bonbon tiramisu toffee powder gummi bears. Toffee tootsie roll powder soufflé apple pie. Fruitcake fruitcake soufflé sweet oat cake cotton candy lemon drops biscuit. Chupa chups fruitcake dessert icing halvah oat cake. Lollipop candy canes halvah bonbon marshmallow croissant. Wafer chupa chups cotton candy tart pudding pie cupcake. Candy canes gummies macaroon pudding cupcake cupcake pudding jujubes. Donut halvah pie chocolate. Sugar plum dessert pudding icing jelly-o cake. Gingerbread macaroon wafer. Caramels muffin jelly wafer carrot cake. Marshmallow candy cookie danish cake. Cupcake croissant gummi bears pastry wafer. Macaroon croissant bonbon wafer. Topping fruitcake topping biscuit. Tiramisu powder sesame snaps candy. Dessert donut cookie carrot cake dragée muffin. Lollipop oat cake cookie candy canes fruitcake. Candy croissant candy canes croissant bear claw cake brownie biscuit pie. Liquorice wafer wafer cookie lollipop gingerbread chocolate cake oat cake dessert. Pudding gingerbread croissant cheesecake soufflé. Muffin gummies chocolate chocolate cupcake pastry. Sweet roll fruitcake bear claw sweet caramels lemon drops lemon drops. Pie sesame snaps cupcake macaroon bonbon oat cake ice cream oat cake topping. Brownie dessert toffee brownie jelly-o chocolate jujubes halvah chocolate bar. Pudding gingerbread dessert. Bear claw tiramisu gummies pudding. Toffee marshmallow jelly beans pie marzipan caramels ice cream lollipop powder. Dragée sesame snaps sugar plum. Marshmallow sweet roll croissant tootsie roll icing. Dragée chocolate marzipan jelly cotton candy. Jujubes sweet chocolate bar candy sweet roll lollipop biscuit dessert. Danish lollipop caramels toffee pastry. Wafer candy canes cupcake chupa chups gummies lemon drops jujubes powder. Caramels danish marshmallow gummies. Jujubes muffin danish pie icing brownie. Toffee sweet tiramisu topping. Cookie fruitcake icing jelly-o sesame snaps. Caramels gingerbread ice cream pastry donut. Gummies liquorice carrot cake sesame snaps muffin toffee dragée marzipan oat cake. Chocolate bar lemon drops dessert. Sweet cupcake sesame snaps carrot cake dessert candy canes halvah tart ice cream. Jelly donut chocolate bar chupa chups tootsie roll soufflé carrot cake tootsie roll gummi bears. Pastry jujubes soufflé marshmallow toffee. Macaroon marshmallow oat cake jujubes caramels topping marzipan cupcake icing. Brownie jelly sweet tootsie roll brownie jujubes cupcake pie. Cookie lollipop ice cream tiramisu jelly-o chocolate gummies. Tart biscuit tiramisu biscuit cake tart danish topping cookie. Liquorice donut dragée tart. Dragée soufflé pudding halvah cookie marshmallow jujubes sweet roll. Pastry chocolate tiramisu bonbon jelly beans lollipop marshmallow chocolate cake. Icing carrot cake gummies cheesecake dragée. Cake fruitcake gummies. Halvah jujubes toffee pudding bonbon soufflé brownie cupcake candy. Icing biscuit cake jujubes. Chocolate bar candy canes caramels cupcake.   id="seeMoreBtn">See More  
 article  max-width: 800px; height: 300px; overflow-y: hidden; > /* This class is added when button is clicked */ article.expanded  height: 628px; > button  height: 41px; padding: 0 2rem; > 
 const seeMore = document.getElementById("seeMoreBtn"); const article = document.getElementById("article"); seeMore.addEventListener("click", () =>  article.classList.toggle("expanded"); const expanded = article.classList.contains("expanded"); if (expanded)  seeMore.innerHTML = "See Less"; > else  seeMore.innerHTML = "See More"; > >); 

Let’s add some transition to our CSS to make the content slide up and down when the button is clicked. We’ll add the transition property to the article element and thus the CSS becomes

 article  max-width: 800px; height: 300px; overflow-y: hidden; transition: height 0.4s linear; > 

And now the article slides up and down. You might think this is the part I say thank you for reading this article. No, it’s not. There is a limitation that arises with this method. Let’s consider it.

The Limitation

What we did above works well when the height of the article is known. What happens though when the height of the element is unknown? For instance, when dealing with dynamic content? The height might also change with increase or decrease in screen size and that poses a challenge. For dynamic content, the height of an element should be set to auto . This way, any increase or decrease in the height of the element will be accomodated. Here’s the challenge: CSS transition does not work when the height of an element is set to auto. Here’s what you’ll get. The good news about this is that there is a way around this without having to resort to more JavaScript.

The Solution

The hack is to transition the max-height property instead of the height property. First, we have to estimate the greatest height our element can ever get. We then set the element to have max-height greater than our estimate when the element is expanded. So let’s revisit our CSS again. This time we’ll change our height properties to max-height .

 article  max-width: 800px; max-height: 300px; overflow-y: hidden; /*Transition time is increased to accomodate the height */ transition: max-height 0.7s linear; > article.expanded  max-height: 1500px; > 

This way the animation works and we still get the effect we want. The transition time might have to be adjusted depending on the effect you want. Got any question or addition? Please leave a comment. Thank you for reading 🙂

Источник

Оцените статью