Implementing the “Float Up” on scroll effect on our work pages

By North Street, A Creative Studio

On our work pages, there’s a subtle yet engaging “float up” effect when you scroll down the page. (Have a look.) It uses a combination of jQuery and CSS Transitions to achieve this effect, but it’s rather simple to implement.

First off, it’s important to note that on our work pages, each row of images is wrapped in a section tag, with a class of .content-row like this:

<section class="content-row">
    [ Some_Images ]
</section>
<section class="content-row">
    [ More_Images ]
</section>
<section class="content-row">
    [ Yet_More_Images ]
</section>

The next task is knowing if a given section element is currently in view, and if so, adding the class .in-view to it.

There’s a variety of ways to do this with vanilla JavaScript, but to keep things simple we leveraged the awesome jQuery plugin, isInViewport, which does as the name implies. It simply tells you if an element is in the viewport.

Using that plugin, the relevant jQuery for the work pages looks like this:

jQuery(document).ready(function($) {

	var ns_in_viewport = function() {
		// Trigger transition on scroll for each content-row
		$('section.content-row').each(function(){
			$(this).isInViewport({ tolerance: -100 }).addClass('in-view');
		});
	}
	ns_in_viewport();

	$(window).scroll(ns_in_viewport);
});

In the function ns_in_viewport, we’ve selecting the section.content-row element, of which there are many. Then for .each() of those elements, we use .isInViewport() to detect if it’s in the viewport, and if so, add the .in-view class.

(The tolerance of -100 simply means that the element must be at least 100px above the bottom edge of the viewport for .isInViewport() to return true.)

To ensure that it runs on scroll, as opposed to simply once on document ready, we bind ns_in_viewport to $(window).scroll();

The final piece of the puzzle, is the actual transition. This is a few simple lines of CSS that is present in the .in-view class. Relevant code below:

section.content-row {
	transition: all 0.5s ease-in-out;
	opacity: 0;
	transform: translateY(20%);
}

section.content-row.in-view {
	opacity: 1;
	transform: translateY(0);
}

We start off all .content-rows with an opacity of 0, and 20% below where they would normally sit. When the .in-view class is added, those elements are reversed and the transition is triggered.

That’s basically it!

Bonus Points: 

The ns_in_viewport() function on this site is actually bit more complex than above, and serves two more functions:

var ns_in_viewport = function() {

	if ($('header').is(":in-viewport")) {
		$('body').removeClass('fixed');
	}
	else $('body').addClass('fixed');

	$('video').each(function(){
		if ($(this).is(":in-viewport")) {
			// Play this video, but only if autoplay is set 
			if ($(this).attr('autoplay') == 'autoplay')
			$(this)[0].play();
		} else {
			// Always pause it though when out of view
			$(this)[0].pause();
		}
	});

	// Trigger transition on scroll for each content-row
	$('section.content-row, .archive-notes article').each(function(){
		$(this).isInViewport({ tolerance: -100 }).addClass('in-view');
	});
}
ns_in_viewport();

$(window).scroll(ns_in_viewport);

The first part at the top, adds a .fixed class to the body, whenever the header tag is is or isn’t in view. (This is used to add that “Ready to launch your next project?” banner.)

The second part, with the video tag, turns videos on when they come into view, and off when they leave the view again.

About north street

We engineer the thoughtful transformation of great organizations. Our proven process helps us understand what your competitors are doing right — and wrong. Want to learn more? Let’s chat.

More Notes

A bowler hat with radio waves behind it

From Layoff to Leadership: Tom Conlon’s Journey to a Prosperous Business

Welcome to Your 2024 Branding Pep Talk

A bowler hat with radio waves behind it

CEO Tom Conlon talks shop on Podcast Marketing Secrets