I’ve been using Google+ more and more over the course of the past few months. Although it’s not exactly the greatest of social networks, it’s really a great tool to meet and network with other developers, designers, and tech-savvy individuals. Since I started using it I fell in love with the UI. One of the UI features that I like the most is the sticky sub-header that they employ on page scroll. I decided to give recreating it a shot.
I decided to keep this tutorial simple. I don’t want to get too involved in the page’s actual markup because the magic happens in the JavaScript. In this case I’m opting for jQuery as opposed to regular old JS simply because it’s easier to use. We’ll start with some boilerplate markup:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Google Plus Styled Header</title>
<link href='http://fonts.googleapis.com/css?family=Lato' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="css/style.css" type="text/css">
</head>
<body>
<header class="header">
<h1>This is a header</h1>
</header>
<div class="sub-header">
<div class="logo">G+</div>
</div>
<section>
<article>
Insert lipsum here
</article>
<article>
Insert lipsum here
</article>
</section>
<script src="//code.jquery.com/jquery-2.1.1.min.js" type="text/javascript"></script>
</body>
</html>
Fairly straight forward so far. The idea for this post isn’t to give you a tutorial on HTML or CSS, although we will delve into that a bit. The code above simply has a basic HTML page with a section and two articles. The articles are simply there in order to cause a page scroll.
Next we’ll style the page. I use Sass because I like how clean looking it is. Plus who likes adding a semi-colon after every single line if they don’t have to? Not me! If you’d like standard CSS then I suggest viewing this link for the compiled css.
*
-moz-box-sizing: border-box
-webkit-box-sizing: border-box
box-sizing: border-box
body
font-family: 'Lato', sans-serif
background: #e5e5e5
margin: 0
border: 0
.container
width: 480px
margin: 0 auto
section
@extend .container
margin: 50px auto
article
padding: 10px
margin-bottom: 20px
font-family: 'Lato', sans-serif
background-color: #fff
box-shadow: inset 1px 1px 0 rgba(0,0,0,.1),inset 0 -1px 0 rgba(0,0,0,.07)
border-radius: 2px
/* Boilerplate CSS for the articles */
h1
font-size: 2.5em
font-family: lato
font-weight: 900
color: darken(#b5b5b5, 10)
line-height: 1.25em
margin-bottom: calc(1.25em/2)
h2
font-weight: 900
font-size: 14px
font-family: lato
color: darken(#b5b5b5, 10)
line-height: 1.14em
margin-top: 1.14em
margin-bottom: calc(1.14em/2)
p
font-family: lato
line-height: 1.66em
font-size: 14px
color: darken(#b5b5b5, 60)
a
color: #DD4B39
text-decoration: none
/* The good stuff */
.header
width: 100%
height: 88px
padding: 1em
background: #fff
.sub-header
position: relative
height: 55px
width: 100%
background: #f5f5f5
border-bottom: 1px solid darken(#f5f5f5, 10%)
transition: background 100ms ease-in
.logo
position: relative
height: 55px
width: 55px
background: #DD4B39
color: #fff
text-align: center
padding-top: .25em
font-size: 2em
transform: translateX(-100%)
transition: all 200ms ease-in
.slideIn
transition: all 200ms ease-in
transform: translateX(0)
.on
position: fixed
top: 0
left: 0
background: #fff
transition: background 200ms ease-in
The idea for this animation is to count how many pixels we’ve scrolled from the top of the page. If we’ve scrolled more than the size of the header then we will add a class to the sub-header. That class will cause the sub-header to become fixed to the top of the page and will also change the background color. You can see that specific code blow. The first class is the base class where we define the basic styles of the sub-header. After that is the class on in which we make the modifications.
.sub-header
position: relative
height: 55px
width: 100%
background: #f5f5f5
border-bottom: 1px solid darken(#f5f5f5, 10%)
transition: background 100ms ease-in
.on
position: fixed
top: 0
left: 0
background: #fff
transition: background 200ms ease-in
To summarize, we have a base style and when the page is scrolled, we add on top of that with a secondary style. We do this with both the logo and the sub-header. Lets begin writing our jQuery.
First we will define some variables. The variable distance is the amount that the .sub-header sits from the top of the window. This is a way of grabbing the height of the header without setting a fixed height on it. Everything after that is simply a way of caching the variable so jQuery does not have to search the DOM for $(window), $(“.sub-header”), and $(“.logo”) every time we need to access those objects.
var distance = $(".sub-header").offset().top,
$window = $(window),
$subHeader = $(".sub-header"),
$logo = $(".logo");
Once we’ve got our variables defined, the basic idea that we need to follow is to simply calculate the scroll distance and then add and remove classes. It’s very simple.
$window.scroll(function() {
if ( $window.scrollTop() >= distance) {
//Add classes
} else {
//Remove classes
}
});
If the window has scrolled the same as or equal to the distance that height of the header then add classes. Otherwise, remove them. All put together.
var distance = $('.sub-header').offset().top,
$window = $(window),
$subHeader = $('.sub-header'),
$logo = $(".logo"),
$ul = $("ul");
$window.scroll(function() {
if ( $window.scrollTop() >= distance) {
$subHeader.addClass("on");
$logo.addClass("slideIn");
} else {
$subHeader.removeClass("on");
$logo.removeClass("slideIn");
}
});
There you have it. The logo toggles the class slideIn and the sub-header toggles the class on. You can see a fully functioning example on this page. If you would like to offer any assistance on refactoring or have suggestions on how to make this better I’d love to read it in the comments below!