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.

Youssef
  • 96
  • 2
  • 7

2 Answers2

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>
Asaf
  • 1,446
  • 9
  • 17
  • 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. – Youssef Aug 25 '20 at 19:27
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>
Ameer
  • 1,980
  • 1
  • 12
  • 24