Как с помощью анимации сделать переход к height: auto? (js, css, react)

У меня есть код который запускает анимацию heightChanger, но анимировать переход к height: auto через keyframe не получается, как это сделать?

document.getElementById('firstStr'+id).style.animation = '1.5s ease 0s normal both heightChanger'
@keyframes heightChanger{
  from {
    height: 2.5em
  }
  to {
    height: auto
  }
}


Ответы (2 шт):

Автор решения: UModeL

Насколько я понял, анимированный переход к auto подразумевает высоту при которой контент виден полностью. То есть элемент должен растянуться на высоту содержимого.

Hа текущий момент (октябрь, 2024 г.) в актуальных версиях браузеров Chrome и Edge добавили функцию calc-size() , и она решила бы проблему на чистом CSS, но... остальные браузеры пока не поддерживают её :(

Поэтому желаемого эффекта пока можно достичь только с помощью JS, высчитывая высоту во временной копии элемента.

list.addEventListener('click', fOpenHide);

function fOpenHide(ev) {
  let target = ev.target;
  [...this.querySelectorAll('li')].forEach(el => {
  
    let fake = document.body.appendChild(el.cloneNode(true));
    fake.style.overflow = 'auto !important';
    fake.style.width = getComputedStyle(el).width;
    el.style.setProperty('--calc-size-auto', getComputedStyle(fake).height);
    fake.remove();
    
    el.classList.toggle('open', (el == target));
  });
}
#list {
  list-style: none;
  margin: 0;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: .5em;
  height: 2.5em;
  padding: 0;
  box-shadow: inset 0 0 10px #fc0;
}

#list > li {
  flex: 1;
  height: 2.5em;
  overflow: hidden;
  box-shadow: inset 0 0 10px #00f;
  transition: 1s ease;
}
#list > li.open {
  height: max(2.5em, var(--calc-size-auto, 0px));
}
<ul id="list">
  <li>Lorem.<br>End.</li>
  <li>Integer nibh mi, blandit at.<br>End.</li>
  <li>Nam consequat nisi faucibus dapibus cursus. Nunc a luctus lorem.<br>End.</li>
  <li>Vivamus porta neque sed viverra semper. Mauris laoreet massa quis blandit sollicitudin. Vestibulum elit magna.<br>End.</li>
  <li>Nullam fermentum hendrerit felis a imperdiet. In gravida consectetur libero vel varius. Morbi ultrices condimentum arcu, non efficitur metus rhoncus.<br>End.</li>
  <li>In pellentesque, ligula sed facilisis hendrerit, libero ex sodales tortor, ac condimentum ipsum dui et massa. Suspendisse potenti. Integer quis aliquet nibh, at efficitur turpis. Duis molestie velit a imperdiet.<br>End.</li>
  <li>Aenean faucibus porta nunc, et efficitur est consectetur non. Sed eget erat a turpis iaculis rhoncus non at dolor. Proin a auctor massa, lacinia efficitur nisl. Vestibulum ultrices turpis felis, et mattis arcu auctor eget. Pellentesque molestie ipsum ac diam posuere, in laoreet felis iaculis. Sed ultricies ex sed est.<br>End.</li>
</ul>

Скрипт максимально упрощён, дабы показать сам принцип. На самом же деле, стоило бы добавить несколько проверок перед расчётами (например, появление полосы прокрутки у документа, изменение размеров окна браузера и ширины самого элемента и т.п.).

→ Ссылка
Автор решения: Михаил Камахин

В Chrome 129 теперь работает анимация height: auto и любых других буквенных неточных выражений размеров.

Написание interpolate-size: allow-keywords для :root устанавливает новое поведение анимации для всей страницы

const id = 1;

document.getElementById('firstStr'+id).style.animation = '1.5s ease 0s normal both heightChanger';
:root {
  interpolate-size: allow-keywords
}

@keyframes heightChanger{
  from {
    height: 2.5em
  }
  to {
    height: auto
  }
}

#firstStr1 {
  background-color: tomato;
  width: 300px;
}
<div id="firstStr1">
  
</div>

→ Ссылка