1

I've added a search bar in the header that is set to display: none by default and I used js to make it appear on a button click via assigning a .show class which contains display: block !important to the search bar element (#search). It's working fine but my only problem is the rough transition from display: none to block, so I've been looking into ways to make this transition smooth and most of the answers I found were using jQuery, which I don't really want to do since I'm still in the learning phase of js, so if there's a way I can do this using vanilla js, please help me with it.

Here's my code https://jsfiddle.net/5jxLq9ck/

In CSS line 38, I add the .show utility class

.show {
    display: block !important;
}

And I'm assuming I'll have to edit something in here (js) to get the desired effect:

function showSearch(e) {
    e.preventDefault;
    if (
        e.target.classList.contains("show-btn") ||
        e.target.classList.contains("fas")
    ) {
        const searchBar = document.querySelector("#search");
        searchBar.classList.add("show");
    }
}

Additional question: is my use of e.preventDefault correct here? The functionality didn't work until I used it.

Thanks a lot in advance.

4
  • Instead of saying also at the start of the animation make opacity: 0; in css and transition to opacity: 1 this will make it smooth Commented Aug 25, 2020 at 18:59
  • 3
    transitions only work with numeric values or values that can be interpolated. use width for this purpose Commented Aug 25, 2020 at 19:02
  • 1
    Using preventDefault() is fine here. Though usually you would want to use <a> element, or even <span> styled to look like a button in such cases, precisely to avoid it's default behavior. Commented Aug 25, 2020 at 19:04
  • 1
    Does this answer your question? JavaScript - add transition between display:none and display:block Commented Aug 25, 2020 at 19:06

2 Answers 2

1

Here is an updated snippet, I've changed the input width for the animation. You can make it even more smooth by set the input height.

const searchDiv = document.querySelector("#search-div");

// ADD EVENT LISTENERS
searchDiv.addEventListener("click", showSearch);

// FUNCTION: SHOW SEARCH BAR ON BUTTON CLICK
function showSearch(e) {
    e.preventDefault;
    if (
        e.target.classList.contains("show-btn") ||
        e.target.classList.contains("fas")
    ) {
        const searchBar = document.querySelector("#search");
        searchBar.classList.add("show");
    }
}
/* GENERAL */
:root {
    --light-color: #ccc;
    --lighter-color: #f4f4f4;
    --dark-color: #333;
    --darker-color: #222;
    --brand-color: #ff4;
    --danger: #f44;
    --danger-dark: #c00;
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    background: var(--dark-color);
    color: var(--light-color);
    font-family: "Trebuchet MS";
}

ul li {
    list-style: none;
}

button,
input {
    outline: none;
}

/* UTILITY */
.highlight {
    color: var(--brand-color);
}

.show {
    width: 300px !important;
    border: black 2px solid;
    padding: 0.6rem 1rem;
}

/* HEADER */
header {
    background: var(--darker-color);
    display: flex;
    flex-direction: row;
    align-items: center;
    text-align: center;
    justify-content: space-between;
    padding: 1.4rem 6rem;
    width: 100%;
}

#logo {
    font-size: 2.4rem;
    font-weight: 200;
}

#search-div {
    width: auto;
    height: auto;
    display: flex;
    gap: 0.4rem;
}

.show-btn {
    padding: 0.6rem 0.7rem;
    background: var(--light-color);
    border-radius: 5px;
    border: none;
    transition: ease-in 300ms;
    font-size: 1.2rem;
    cursor: pointer;
    height: 100%;
    margin-top: 2px;
}

.show-btn:hover {
    background: var(--brand-color);
    transition: ease-in 300ms;
}

#search {
    width: 0;
    background: var(--lighter-color);
    color: var(--darker-color);
    height: 100%;
    font-size: 1.2rem;
    border-radius: 2px;
    transition: ease-in 300ms;
    border: none;
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My Contact List</title>
    <link rel="stylesheet" href="css/style.css">
    <script src="https://kit.fontawesome.com/3ad7573e76.js" crossorigin="anonymous"></script>
</head>

<body>
    <header>
        <div id="logo-div">
            <h1 id="logo">
                <span class="highlight"><i class="fas fa-user-friends"></i></span> My<span
                    class="highlight">Contact</span>List
            </h1>
        </div>
        <div id="search-div">
            <button class="show-btn"><i class="fas fa-search"></i></button>
            <input id="search" type="text" placeholder="Search contacts...">
        </div>
    </header>

    <script src="js/main.js"></script>
</body>

</html>

Sign up to request clarification or add additional context in comments.

1 Comment

Yes! Thanks a lot. Just a small question, could I be able to make it transition so that the button also pushes smoothly to the left and the search bar appears kind of like straightening a rug, as in from left to right with a consistent height in contrast to appearing from the corner? I'm guessing these tweaks would be too hard for my skill level in which case I'll just go with this for now. Thanks again.
0

You can make the transition from no display to block display smooth by playing with the opacity property so that when the element is given the "show" class it animates from an opacity of 0 to an opacity of 1 like so.

function showSearch(e) {
    e.preventDefault;
    if (
        e.target.classList.contains("show-btn") ||
        e.target.classList.contains("fas")
    ) {
        const searchBar = document.querySelector("#search");
        searchBar.classList.add("show");
    }
}

document.getElementById("show").addEventListener("click", e => {
   showSearch(e);
});
@keyframes smooth {
    from {
      opacity: 0;
    }
    to {
      opacity: 1;
    }
}

.show {
    animation: smooth 1s ease;
    display: block !important;
}
.none {
  display: none;
  }
<div class="none" id="search">Example</div>
<button class="show-btn fas" id="show">Show</button>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.