dropdown

by Aleksey Shukilovich

HTML

<div class="dropdown" aria-expanded="false" data-height="100">
  <div class="dropdown__content">
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rem voluptas fugit adipisci quaerat, quam, quo laudantium dolorem! Cum repudiandae, animi architecto quas distinctio autem excepturi laboriosam impedit, nisi nemo nihil.</p>
    <p>Aperiam tempora minus et accusantium consectetur recusandae, incidunt, similique enim quibusdam magnam laborum natus, libero id veritatis? Porro aliquam, obcaecati omnis pariatur, recusandae, qui delectus nulla perspiciatis quae, nesciunt nisi.</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minus a minima dicta impedit non sapiente facilis corrupti recusandae atque laudantium possimus doloremque amet ut praesentium quod, porro, veritatis error architecto.</p>
  </div>
  <button class="dropdown__button">Развернуть/Свернуть</button>
</div>

SCSS

.dropdown {
  padding: 50px;
  
  &[aria-expanded="false"] {
    &__content {
      max-height: 100px;
    }
  }

  &__content {
    transition: 0.4s;
    border: 1px solid #333;
    max-height: 92px;
    overflow: hidden;
    
    p {
      margin: 0;
      line-height: 1.3;
      
      &:not(:last-child) {
        margin-bottom: 10px;
      }
    }
  }
}

JavaScript

document.addEventListener('click', e => {
	if( !e.target.closest('.dropdown__button') ) return;
  
  const dropdown = e.target.closest('.dropdown');
  const dropdownContent = dropdown.querySelector('.dropdown__content');
  const dropdownButton = e.target.closest('.dropdown__button');
  const opened = (dropdown.getAttribute('aria-expanded') === 'true');
  
  
  if(opened) {
  	dropdown.setAttribute('aria-expanded', false);
  	dropdownContent.style.maxHeight = dropdown.dataset.height + 'px';
  } else {
  	dropdown.setAttribute('aria-expanded', true);
  	dropdownContent.style.maxHeight = calcHeightContent(dropdownContent) + 'px';  
  }
})


function calcHeightContent(element) {
		const containerClone = element.cloneNode(true);
    let naturalHeight = 0;

		containerClone.style.position = 'absolute';
		containerClone.style.visibility = 'hidden';
		containerClone.style.opacity = 0;
		containerClone.style.maxHeight = '100%';
		containerClone.style.zIndex = -1;

		element.parentNode.append(containerClone);

		naturalHeight = containerClone.clientHeight;
	
		containerClone.remove();
    
    return naturalHeight;
	}