A Cute Search Box Unhiding Animation
There's nothing particularly fancy going on here, just some simple CSS transitions, and a bit of jQuery.
Markup
The markup consists of just a few elements: the search div itself, a container inside of it that we'll move later, a couple content divisions, some icons, and the field itself:
<div id="search" role="search">
<div class="search_container">
<div id="closed_search">
<p>Search</p>
</div>
<div id="open_search">
<i class="fa fa-search"></i>
<form method="post" id="search_form">
<input type="text" id="searchq" name="searchq" />
</form>
<i class="fa fa-close"></i>
</div>
</div>
</div>
SCSS
The SCSS is a bit more complex, but mostly it's just some pieces we slide around. Here's what we have when the search field is close:
$transition_time: 700ms;
$background_color: white;
$text_color: black;
body {
background-color: $background_color;
overflow: hidden;
}
#search {
cursor: pointer;
font-family: 'Roboto', sans-serif;
position: absolute;
top: .5rem;
right: .55rem;
width: 15rem;
height: 1.75rem;
display: flex;
align-items: flex-start;
justify-content: flex-end;
overflow: visible;
z-index: 1000;
.search_container {
position: absolute;
left: 6rem;
display: flex;
align-items: center;
transition: left $transition_time;
i {
margin: 0rem .25rem;
}
p {
margin: 0 .25rem 0 0;
display: inline;
color: $text_color;
opacity: 1;
transition: opacity $transition_time;
}
#closed_search {
height: 1.5rem;
transition: all $transition_time;
right: 1.75rem;
display: flex;
align-items: center;
}
#open_search {
transition: all $transition_time;
width: 15rem;
border: solid rgba(0,0,0,0) 1px;
height: 1.75rem;
display: flex;
align-items: center;
justify-content: space-between;
}
}
}
#searchq {
height: 22px;
border: none;
font-size: .9rem;
line-height: 1rem;
opacity: 0;
transition: opacity $transition_time;
&:focus {
outline: none;
}
}
When we open the search field, the #search
element stays in place, while we move the .search_container
element inside of it. We also change the opacity of a few items, fading in the border, close icon, and input field and fading out out the word "search."
#search.open {
.search_container {
left: -7.25rem;
}
p {
opacity: 0;
}
#open_search {
border: solid rgba(0,0,0,1) 1px;
background-color: $background_color;
}
#searchq {
opacity: 1;
}
}
Javascript
Now all we need to do is actually change the class when you click on the search field. This javascript is a little squirrely, but the key thing to note is that we avoid focusing the search field until after the animation has completed. If we don't, there's a pretty obnoxious jitter as it moves. Also, we've commented out the submit on the form in favor of an alert, but it's easy to switch back!
// Open/close the search field depending on where you click
$('#closed_search, #search .fa-times').click(function() {
$('#search').toggleClass('open');
// If the search field is open, then we need to focus its field
if ($('#search').hasClass('open')) {
setTimeout(function(){
$('#searchq').focus();
},700);
} else {
$('#searchq').blur();
}
});
$('#search .fa-search').click(function(){
if ( $('#search').hasClass('open') ) {
// Normally we'd submit this form
//$('#search_form').submit();
alert('Search Submitted');
}
else {
$('#search').addClass('open');
$('#searchq').focus();
}
});
We're going to add one more little trick here before we call it quits. We'd like the search window to close when you click off of it. To do that, we attach a listener on the body with a condition that makes sure that you're not clicking in the #search#
element.
// Close the form when we click on the body
// But only if we're not clicking in the field itself
$(document).click(function(e) {
if ( $(e.target).closest('#search').length === 0 ) {
$("#search").removeClass('open');
}
});
And that's it! Check out a codepen with the transition in action.