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
isSearchBarOpen
istrue
orfalse
. - 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-open
class and thedisplay:flex
inline style. On the one hand, said inline style overrides thedisplay:none
CSS property applied through the.search-bar
class by specificity. -
And, in addition, the
.search-bar-open
class is added. -
Now, I assume that, when the
.search-bar-open
class is applied, the transition stipulated within.search-bar
should 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 🙁
3
Answers
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
top
property 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.
the problem is that transitions does not work for
display: none
properties,instead of doing display none to flex, just do something to hide search bar without doing display: none;
one possible solution is to give negative top value to remove from visible window
like
top: -50px
(or you can give exact value as the height of your searchbar)The transition not work for
display:none
. So, instead of transition use animation.example code:
CSS:
Javascript:
HTML:
Here, I used animation instead of transition. Hope you undertand 🙂