1

Is there a way to manipulate a CSS class with plain JavaScript?

I am creating a dropdown-menu and I want to transition it from height: 0 to the computed height of the element when height: auto.

By default, the CSS class that I'm trying to manipulate does not have an element.


HTML:
<ul class="dropdown-parent">
  <li><a>Link</a></li>
  <li>
    <a>Link</a>
    <ul class="dropdown">
      <li>Link</li>
      <li>Link</li>
      <li>Link</li>
    </ul>
  </li>
</ul>

CSS:

.dropdown-parent {
    position: relative;
}

.dropdown {
    position: absolute;
    left: 0;
    top: 100%;
    height: 0;
    overflow: hidden;
    transition: height 1s ease-in-out;
}

.expand {}

JavaScript:

const dropdown = document.querySelector('.dropdown-parent');
const dropdownList = document.querySelector('.dropdown');

dropdownList.style.height = 'auto';
const dropdownHeight = dropdownList.offsetHeight;
dropdownList.style.height = '0';

dropdown.addEventListener('click', () => {
    -- TRYING TO ADD CALCULATED HEIGHT TO THE CLASS '.expand' --

    dropdown.classList.toggle('expand');
});

I want to:

1) Fetch the element in the DOM.

2) Set the element's height to auto.

3) Calculate it's height and store it in a variable.

4) Set it's height back to 0.

5) Add the calculated height to the class .expand.

6) Add an event listener to the parent to toggle the class .expand.

The only thing I cannot do is the step (5).

Some help on this topic?

Thomas Darvik
  • 748
  • 7
  • 22
  • You can't modify the .expand class without a) modifying the .css stylesheet or b) adding another – Michael Sorensen May 11 '18 at 21:43

2 Answers2

1

You can probably solve this by using CSS custom properties to change the value itself.

CSS:

:root {
  --expanded-height: auto;
}

.expand {
  height: var(--expanded-height);
}

Javascript:

dropdown.addEventListener('click', () => {
    document.documentElement.style.setProperty('--expanded-height', dropdownHeight);
    dropdown.classList.toggle('expand');
});

Source: CSS Custom Properties—Dynamic Changes With And Without Javascript

haugsand
  • 400
  • 1
  • 5
0

You can create new element style in the DOM and declare .expand {} class

const dropdown = document.querySelector('.dropdown-parent');
const dropdownList = document.querySelector('.dropdown');

dropdownList.style.height = 'auto';
const dropdownHeight = dropdownList.offsetHeight;
dropdownList.style.height = '0';

let sheet = document.createElement('style');
document.body.appendChild(sheet);

dropdown.addEventListener('click', () => {
    sheet.innerHTML = ".expand {height: " + dropdownHeight + "px;}";
    dropdown.classList.toggle('expand');
});

Even if predefined class .expand exists, this statement will just append or redefine property height of class .expand. Depending on context you should avoid of duplicate creating the element sheet.

Banzay
  • 9,310
  • 2
  • 27
  • 46