Go to homepage

Projects /

Advanced Search Form

A search form with advanced filtering options and quick link suggestions.

Advanced Search Form
Check our new component library →

Getting the search experience right is never an easy task. The starting point is always the search form, which, in most cases, consists only of an input field plus a submit button. The search results page can be tricky to design, in particular if you have different content categories.

For big websites and online stores, what is crucial though is to try to anticipate a user’s move. We have to take into account that often our users are not clear about where to find specific information on our website. In those cases they tend to turn to the search form. Providing filtering options and quick links upfront is a way to narrow the search experience to what the user is really interested in, as well as a way to build simpler, more focused search result pages.

Here is a quick animation that shows our advanced search form in action:

advanced-search-animation

Creating the structure

The HTML structure is composed by three main elements: a <header> element, wrapping the main navigation, a div.cd-main-search for the search form and a main.cd-main-content for the page main content.

<header class="cd-main-header animate-search">
   <div class="cd-logo"><a href="#0"><img src="img/cd-logo.svg" alt="Logo"></a></div>

   <nav class="cd-main-nav-wrapper">
      <a href="#search" class="cd-search-trigger cd-text-replace">Search</a>
    
      <ul class="cd-main-nav">
         <li><a href="#0">Products</a></li>
         <!-- additional navigation items -->
      </ul>
   </nav>

   <a href="#0" class="cd-nav-trigger cd-text-replace">Menu<span></span></a>
</header>

<main class="cd-main-content">
   <!-- your content here -->
</main>

<div id="search" class="cd-main-search">
   <form>
      <input type="search" placeholder="Search...">

      <div class="cd-select">
         <span>in</span>
         <select name="select-category">
            <option value="all-categories">all Categories</option>
            <!-- additional options here -->
         </select>
         <span class="selected-value">all Categories</span>
      </div>
   </form>

   <div class="cd-search-suggestions">
      <div class="news">
         <h3>News</h3>
         <ul>
            <li>
               <a class="image-wrapper" href="#0"><img src="img/placeholder.png" alt="News image"></a>
               <h4><a class="cd-nowrap" href="#0">Lorem ipsum dolor sit amet, consectetur adipisicing elit.</a></h4>
               <time datetime="2016-01-12">Feb 03, 2016</time>
            </li>

            <!-- additional news here -->
         </ul>
      </div> <!-- .news -->

      <div class="quick-links">
         <h3>Quick Links</h3>
         <ul>
            <li><a href="#0">Find a store</a></li>
            <!-- additional quick links here -->
         </ul>
      </div>
   </div> <!-- .cd-search-suggestions -->

   <a href="#0" class="close cd-text-replace">Close Form</a>
</div> <!-- .cd-main-search -->

Adding style

On small devices (viewport width smaller than 1024px), the main navigation and the search form are on the right side, hidden by default; when a user clicks the menu icon, the <main> and <header> elements translate to the left (nav-is-visible class is applied) to reveal the navigation.

.cd-main-header, .cd-main-content {
  position: relative;
  transition: transform 0.3s;
}
.cd-main-header.nav-is-visible, .cd-main-content.nav-is-visible {
  transform: translateX(-260px);
}

On bigger devices, the search form is on top of the main navigation, hidden by default. When a user clicks the .cd-search-trigger element, the .is-visible class is used to reveal the form.

@media only screen and (min-width: 1024px) {
  .cd-main-search {
    position: absolute;
    z-index: 2;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.3s, visibility 0.3s;
  }
  .cd-main-search.is-visible {
    /* search form open */
    opacity: 1;
    visibility: visible;
  }
}

To trigger the search form animation, we use the .animate-search class added to the <header> element. This class triggers two different CSS3 Animations: cd-slide-in (for the search form) and cd-3d-rotation (for the suggestions dropdown).

@media only screen and (min-width: 1024px) {
  .animate-search .cd-main-search.is-visible {
    /* trigger search form animation if <header> has the .animate-search class */
    animation: cd-slide-in 0.3s;
  }
  .animate-search .is-visible .cd-search-suggestions {
    /* trigger the dropdown animation if <header> has the .animate-search class */
    transform-origin: center top;
    animation: cd-3d-rotation 0.5s 0.3s;
    animation-fill-mode: backwards;
  }
}
@keyframes cd-slide-in {
  0% {
    transform: translateY(-100%);
  }
  100% {
    transform: translateY(0);
  }
}

@keyframes cd-3d-rotation {
  0% {
    transform: perspective(1000px) rotateX(-90deg);
  }
  100% {
    transform: perspective(1000px) translateY(0);
  }
}

If you prefer a basic fade-in effect (rather than animating the search form), you can remove the .animate-search class from the <header> element.

About the category selection: to make sure the div.cd-select width changes according to the option the user chooses, the <select> element is in absolute position (so it doesn't take space), while a span.selected-value is used to show the option selected (its text is changed  when the user selects a new option using jQuery).

@media only screen and (min-width: 1024px) {
  .cd-main-search .cd-select {
    position: absolute;
    right: 0;
    overflow: hidden;
  }
  .cd-main-search select {
    /* the <select> element is not visible - it is covered by the .selected-value element */
    position: absolute;
    right: 0;
    opacity: 0;
    color: transparent;
  }
  .cd-main-search .selected-value {
    color: #ffffff;
    pointer-events: none;
  }
  .cd-main-search select, .cd-main-search .selected-value {
    padding: 0.5em 1.7em 0.5em .3em;
    font-size: 1.4rem;
    border-radius: 3px;
  }
}

Events handling

In the starting HTML structure, the navigation is inside the <header>. On small devices, we wanted the navigation to be on the side, hidden by default, and it was easier for us to have it outside the <header>. So we use jQuery to do that.
We do the same for the div.cd-main-search: by default, it's outside the main navigation, while on small devices we move it inside the nav.cd-main-nav-wrapper element.

var navigationWrapper = $('.cd-main-nav-wrapper'),
    navigation = navigationWrapper.children('.cd-main-nav'),
    searchForm = $('.cd-main-search'),
    navigationTrigger = $('.cd-nav-trigger'),
    mainHeader = $('.cd-main-header');

function moveNavigation(){
   var screenSize = checkWindowWidth(); //returns 'mobile' or 'desktop'
   if ( screenSize == 'desktop' && (navigationTrigger.siblings('.cd-main-search').length == 0) ) {
      //desktop screen - insert navigation and search form inside <header>
      searchForm.detach().insertBefore(navigationTrigger);
      navigationWrapper.detach().insertBefore(searchForm).find('.cd-serch-wrapper').remove();
   } else if( screenSize == 'mobile' && !(mainHeader.children('.cd-main-nav-wrapper').length == 0)) {
      //mobile screen - move navigation and search form after .cd-main-content element
      navigationWrapper.detach().insertAfter('.cd-main-content');
      var newListItem = $('<li class="cd-serch-wrapper"></li>');
      searchForm.detach().appendTo(newListItem);
      newListItem.appendTo(navigation);
   }
}

Besides, we used jQuery to detect click events and add/remove classes accordingly and to change the span.selected-value text when user selects a different option from the <select> dropdown.

Project duplicated

Project created

Globals imported

There was an error while trying to export your project. Please try again or contact us.