Customizing Search Bar with VanillaJS
Tags: navigation, vanillajs, css
Published: 2020-05-29 19:11:54

This short guide is for anyone who is looking to spice up their search bar without using any plugins or packages. I was inspired to make these changes while redesigning a navigation bar to make it more minimalistic. Prior to implementing these changes, I was inlining the search input field within the navigation bar.

<h3>Before:</h3>

<img src="https://dev-to-uploads.s3.amazonaws.com/i/rxoi2cnqnk3drh0z7z1v.png">

<h3>After:</h3>

<img src="https://dev-to-uploads.s3.amazonaws.com/i/lucv11rqp5ypah2ii2ys.gif">

The old search bar is now replaced with a search icon, which displays a full page search screen when clicked. This allows for a clean navigation bar, taking up far less space than inlining an entire input field.

<b>Advantage:</b> Requires less space than inlining an entire input field.
<b>Disadvantage:</b> Adds an extra click before the user can search.

<h2>3 Simple Steps</h2><br>
<h3>1) HTML</h3>
 The HTML code will be pretty short. The <b>searchicon</b> div is where the search icon will live and the <b>pagesearch</b> div is for the full page search screen, which will appear once the search icon is clicked. The form in the <b>pagesearch</b> div is optimized for Wordpress. Please modify the form code to fit your site.

``` html
<div class="searchicon"> 
   <span class="searchbutton" onClick="showSearch()"></span> <!-- searchicon -->
</div>

<!-- Full Page Search Screen -->
<div class="pagesearch" >
   <span onClick="hideSearch()" class="xOut"></span>
   <form method="get" class="searchform" action="<?php echo home_url(); ?>/"> <!-- wordpress route -->
      <div class="search-text-div"><input type="text" name="s" class="search-text" value="" placeholder="Search..." /></div>
      <span class="search-submit-div btn"><input type="submit" class="search-submit" value="" />
      </span>
   </form>
</div>
```
<br><br>

<h3>2. CSS</h3>

The primary goal of the CSS is to add the search icon. I prefer to use SVGs instead images whenever I have the chance. Although you can hardcode SVGs directly in the HTML, I recommend adding it in the background attribute in CSS.  Check out this <a href="https://growfox.co.uk/blog/5-reasons-you-should-be-using-svgs-over-pngs">article</a> to learn more about the advantages of SVGs. Here is the <a href="https://image.flaticon.com/icons/svg/2089/2089805.svg">SVG</a> we will be using. <b>Note</b>: If you're using a white background, change the fill color to something other than white (i.e. Black).


``` CSS
  .searchbutton {
    display: inline-block;
    cursor: pointer;
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='white' width='20' height='20' viewBox='-1 0 136 136.21852' fill-rule='evenodd'%3E%3Cpath d='M 93.148438 80.832031 C 109.5 57.742188 104.03125 25.769531 80.941406 9.421875 C 57.851562 -6.925781 25.878906 -1.460938 9.53125 21.632812 C -6.816406 44.722656 -1.351562 76.691406 21.742188 93.039062 C 38.222656 104.707031 60.011719 105.605469 77.394531 95.339844 L 115.164062 132.882812 C 119.242188 137.175781 126.027344 137.347656 130.320312 133.269531 C 134.613281 129.195312 134.785156 122.410156 130.710938 118.117188 C 130.582031 117.980469 130.457031 117.855469 130.320312 117.726562 Z M 51.308594 84.332031 C 33.0625 84.335938 18.269531 69.554688 18.257812 51.308594 C 18.253906 33.0625 33.035156 18.269531 51.285156 18.261719 C 69.507812 18.253906 84.292969 33.011719 84.328125 51.234375 C 84.359375 69.484375 69.585938 84.300781 51.332031 84.332031 C 51.324219 84.332031 51.320312 84.332031 51.308594 84.332031 Z M 51.308594 84.332031'%3E%3C/path%3E%3C/svg%3E")
      center / contain no-repeat;
    width: 20px;
    height: 20px;
  }

  .pagesearch { /* full page search screen, hidden by default */
    display: none;
    background: #000000f0;
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    z-index: 2;
  }

.xout {
   cursor: pointer;
}

  .xOut:after {
    content: "X";
    color: #fff;
    font-weight: 100;
    font-size: 2.1rem;
  }

.searchform { /* form field placed in middle of screen */
    position: absolute;
    width: 50%;
    top: 39%;
    left: 25%;
    border-bottom: 2px solid #fff;
    padding-bottom: 8px;
}

.search-text { /* input field text */
  font-size: 38px;
  font-weight: 100;
  font-family: unset;
  color: #f5f5f5 !important;
  padding-left: 10px;
  background: transparent;
  border: 0;
}

  .search-submit { /* submit icon, thin to match input text */
    background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='white'  viewBox='0 0 511.999 511.999' fill-rule='evenodd'%3E%3Cpath d='M508.874,478.708L360.142,329.976c28.21-34.827,45.191-79.103,45.191-127.309c0-111.75-90.917-202.667-202.667-202.667    S0,90.917,0,202.667s90.917,202.667,202.667,202.667c48.206,0,92.482-16.982,127.309-45.191l148.732,148.732    c4.167,4.165,10.919,4.165,15.086,0l15.081-15.082C513.04,489.627,513.04,482.873,508.874,478.708z M202.667,362.667    c-88.229,0-160-71.771-160-160s71.771-160,160-160s160,71.771,160,160S290.896,362.667,202.667,362.667z'%3E%3C/path%3E%3C/svg%3E")
      center / contain no-repeat;
    width: 33px;
    height: 47px;
    padding: 0;
    border: 0;
  }
```


<h3>3. Javascript</h3>
<b>showSearch</b> is triggered when the user clicks the search button.
<b>hideSearch</b> is triggered when the user presses "esc" on their keyboard, or clicks the "x" button.

``` Javascript
function showSearch() {
  document.querySelector(".pagesearch").style.cssText = "display:block";
  document.querySelector(".xOut").style.cssText = "display:block";
  document.querySelector("html").style.cssText = "overflow:hidden";

  document.onkeydown = function (evt) {
    evt = evt || window.event;
    var isEscape = false;
    if ("key" in evt) {
      isEscape = evt.key === "Escape" || evt.key === "Esc";
    } else {
      isEscape = evt.keyCode === 27;
    }
    if (isEscape) {
      hideSearch();
      document.onkeydown = null;
    }
  };
}

function hideSearch() {
	document.querySelector(".xOut").style.cssText = "display:none";
	document.querySelector(".pagesearch").style.cssText = "display:none";
	document.querySelector("html").style.cssText = "overflow:initial";
}
```

<h3>Conclusion</h3>
The more comfortable I get with web dev, the less I try to rely on plugins and packages to execute my ideas. This was a fun feature I was able to implement pretty quickly. Enjoy!