CSS transitions aren't working for me when I try to execute them through JavaScript.
let isSearchBarOpen = false;
function toggleSearchBar() {
if (isSearchBarOpen) {
searchBar.style.display = "none";
} else {
searchBar.style.display = "flex";
searchBar.classList.add("search-bar-open")
}
isSearchBarOpen = !isSearchBarOpen;
toggleSearchIcon();
}
.search-bar {
display: none;
background-color: #000;
color: #fff;
position: absolute;
top: 0;
left: 0;
right: 0;
padding: 10px 5px;
z-index: 1000;
margin: 0 auto;
transition: top 2s ease-in;
}
.search-bar-open {
top: 90px;
}
<div class="search-icon">
<i class="fas fa-search search-icon-header"></i>
<img src="images/close-icon.svg" alt="close-icon-search" class="close-icon-search">
</div>
<div class="search-bar" id="search-bar">
<div class="search-container">
<form class="search-form">
<input type="text" placeholder="Search...">
<button type="submit"><i class="fas fa-search search-icon-action"></i></button>
</form>
</div>
</div>
When the search button is clicked, the following things happen (or should happen if I am not wrong):
- The function checks if
isSearchBarOpenistrueorfalse. - If
true—that is, if the search bar is open—, an inline style is added (display:none) hiding the bar. - If it is
false— that is, if the search bar is closed — an inline style is added (display:flex) so that it show up. And, in addition, a class is added (.search-bar-open).
From there, if we look at the CSS…
The search bar, when opened (when it shows up), loads the
.search-bar-openclass and thedisplay:flexinline style. On the one hand, said inline style overrides thedisplay:noneCSS property applied through the.search-barclass by specificity.And, in addition, the
.search-bar-openclass is added.Now, I assume that, when the
.search-bar-openclass is applied, the transition stipulated within.search-barshould occur, that is:
a. I'm in top:0;…
b. And in 2 seconds with ease-in…
c. I am set top:90px;.
Something I must've misunderstood, since it is not working :-(
If you use JS to make an element visible AND add a class to trigger a transition, it will not work because JS does both those actions at the same time. A transition will trigger if a property is changed on an element, but done like this, the
topproperty is never changed, it was already there when the element was made visible.You can add a JS action in between to trigger a browser 'reflow'. That way the browser makes the element visible first, draws that element on the page, and then adds the class to trigger the transition.