Get that jank outta here!

Making sections of a page span the full width and height of the screen is a pretty cool look for a website. I’m a huge fan of using the entire screen and not keeping your site stuck in a box. After all, we don’t watch TV on only part of our television screens, right? So why do the same on the internet? Any way, I digress…

Making sections of your site span the full height of the screen requires the use of the CSS3 unit of measurement called ‘viewport height’ or vh. The browser calculates the vertical height of the viewport, where 1vh equals 1/100th of the viewport height. So to make a section of a website span the full height of screen is a cinch with the use 100vh.

The one (rather large) caveat of using vh is that mobile browsers don’t really play very nicely with vh. Upon page load in most mobile devices, namely iPhone and Android phones, the viewport height is based on the device screen height. For the Samsung S6 (the device I have and use on a daily basis) the pixel height of my viewport is 640px. The viewport height in pixels for an iPhone 5 and iPhone 6 is 568px and 667px respectively. But the issue that comes up with vh in mobile devices such as these is that the viewport height is calculated using their screen pixel heights MINUS the browser bar, which is about 60px, on first page load. So once a user scrolls down on their phone, the browser bar scrolls up out of sight, and viewport height gets recalculated by the browser. Most resize and animation events only fire once the screen stops moving, which results in some quite unpleasant jank once you stop scrolling. See the gif below to view it in action.

a moving gif showing the jankyness of the vh shift that sucks so much

So basically, that sucks. If one was to want to click on a button after scrolling, the screen would jump as vh is recalculated resulting in missing the intended button and possibly clicking on something they didn’t want to click on. Not a good user experience.

One way around this is to set the min-height to something that is agreeable to most devices. In the past I have used this technique and just set my full screen sections with a min-height of 100vh to something like min-height: 600px on mobile devices. It’s a decent workaround, but not as cool being able to use vh without issue.

So I came up with a different workaround. It may seem like a bit of a hack, but I think it works pretty well. First, since this is a WordPress site, I added a mobile body class which uses the wp_is_mobile() function to detect a mobile device and adds a class of ‘mobile’ to the body tag. Paste this into your functions.php file to achieve this:

<?php
function my_body_classes($c) {
wp_is_mobile() ? $c[] = 'mobile' : null;
return $c;
}
add_filter('body_class','my_body_classes'); ?>

Next, I added the following into my footer (or add it into your custom javascript file to keep things nice a tidy):

<script type="text/javascript">
jQuery(document).ready(function($) {
$heightOnLoad = $('.vc_row.vc_row-o-full-height.welcome-message-wrapper').height();
console.log($heightOnLoad);
$(window).resize(function() {
$('body.mobile .vc_row.vc_row-o-full-height.welcome-message-wrapper').css({
'min-height':$heightOnLoad
});
});
});
</script>

The snippet above results in a smooth, jank-free scroll of the website on a mobile device. Check it!

a moving gif showing the site scrolling JANK-FREE!!!

What it does is calculate the vertical height of the viewport after the page has finished loading and stores the height value in pixels in a variable called $heightOnLoad. It then applies ‘min-height’ inline to the sections specified in the function with the value of $heightOnLoad on mobile devices only. In my case, I wanted to only target the first section of the site you see in the gifs because it is the only section of the site that will have a min-height that will fit into the vertical height of the viewport, so adjust your script accordingly to fit your specific circumstance.

So, this could be the perfect fix for some, but I’m sure I’ve missed something. Go ahead, poke holes in it, because I think this is a pretty good workaround, but I’m probably wrong.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>