Removing Colorbox, beautytips and other Javascript effects for mobile in Drupal 7

Responsive Layout is my new favourite field of specialization. Given how many pages are still not optimized for mobile (including the one you are just reading, but not for much longer), there is a lot to do. And since responsive has not been around so very long, it often feels quite exploratory. I like to fool myself into believing I just solved an problem unsolved before. That is not true of course, but at least you have not read about the solutions so often.

Making a design responsive can be done on multiple levels. Until now I have done mostly basic stuff. To really rock the socks one surely should do a seperate layout for mobile instead of creating a beautiful desktop layout and just make it "not-too-ugly" on mobile. This is in my plans for future sites I build and design for sure. For now, I am quite happy doing the not-too-ugly thing.

Javascript is not CSS

Once you feel you got a foothold in mediaqueries and mobile-first responsive layout (which is the way to go, I think), other things pop up. Your average slideshow on the frontpage can be just hidden for mobile, which sure is not ideal. Building a touch-enabled slideshow is on TODO list. Slideshows are hard anyway, since often the div-container and image size properties are intertwined. I did not manage yet to make my favourite weapon Views Slideshow smoothly scale the image with the screen-size, so I won't touch upon that.

A word on screen resolutions

Your fancy new smartphone may have a ridiculously high resolution, even full HD (which would be 1080px width and 1920px height) is not uncommon in modern flagship devices. But you do not need to care too much about that, else "retina" displays or every average modern high-res display would blow everything apart in your breakpont strategy. To my knowledge, an Iphone still reports the screen to be 320px wide, regardless of the physical resolution is much higher (actually double, with 640px width in portrait mode). My Galaxy Nexus reports a width of 360px with a physical resolution of 720px width in portrait mode. Of the devices I checked, manufacturers typically stick to a multiplication by 2 or other straight numbers to keep things straightforward. I guess else you would get strange subpixel blur, but I have not investigated this in full depth.

This way of presenting a resolution rather relative to the size of the device than relative to the resolution makes perfect sense. For example the Iphone 5 screen has still the exact same physical width as the very first iphone. So if the iphone would report back 640 px, everthing would be tiny and unusable at least on webpages, and we website-builders would not be able to target the actual size of a device properly. Keep in mind you usually disable zooming for a mobile website, so users would be fixed to the font and layout size you give them.

This device width / physical resolution mismatch is often a stumbling block when starting out with responsive webiste layouts and keeps you wondering why it all does not work as expected.

Plain disabling

There are things that are much easier to solve than slideshows. Since hover-effects, lightboxes and tooltips are almost always unwanted on a small, touch-operated device, let's look at two of those.

On this site, I use Colorbox for Lightboxes and beautytips in some places, namely on the projects detail page. If you go to one, which happens to be the Drupalcon Munich site (shameless plug intended), you have beautytips on the small square project screenshots at the bottom above the footer, and a colorbox effect on the biggest project image at the top.

Now we don't want these on the mobile version of the site, especially for smartphone, right?
Turns out, Jquery has a nice handy method for detecting your device width, which is window.matchMedia()

It is supported only on newer versions of mobile browsers http://caniuse.com/matchmedia but it was o.k. for me now. If you want to make sure you target also older versions especially of iOs and Android browsers, you can use the jquery width() function, a comparision of support for the two methods here http://jsperf.com/matchmedia-vs-jquery-width

Whichever method you use, this touches only on the core device width detection, but not the jquery functions to disable beautytips and colorbox.

Creating a module for your scripts

Even while being hardly a coder at all, I have stopped including custom scripts in the theme. They are better kept in a module, I think. Sure if you would change your theme, you would have to check back if the scripts still apply. Still stuff like colorbox is very probable to be used also in your next theme or client project, so you got a nice handy and portable module.

No need to talk about the .info file, it looks the same as any other drupal 7 module info file.
So here is how the .module file looks:

<?php
/**
 * Implements hook_preprocess_page
 */
function rufzeichen_custom_preprocess_page(&$variables) {
 
// define base path for our module
 
$base = drupal_get_path('module', 'rufzeichen_custom');
 
// add multi-purpose Javascript
 
drupal_add_js($base . '/js/multipurpose.js');
}
?>

We add a hook_preprocess_page and use good old drupal_add_js to add our Javascript file. The Javascript file I put in a folder /js in my module directory. The contents of this file should be the interesting part:

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

    // disable colorbox if the window is smaller than 700px
    if (window.matchMedia) {
      // Establishing media check
        width700Check = window.matchMedia("(max-width: 700px)");
        if (width700Check.matches){
        $.colorbox.remove();
        $(".colorbox").click(function(e){
          e.preventDefault();
        });
        $(".overview-thumb-wrapper").removeAttr("bt-xtitle");       
      }
    }
  }); //document.ready

})(jQuery); 

Analyzing the script

So what do we do here? First we use window.matchMedia() to do a media-check and set it to check for every device width up to 700 px. This leaves colorbox and beautytips enabled on an Ipad or large tablet. One may not want this, and in this case you would enter 768px instead of 700. To my knowledge, 768px is the width Ipads and other 10-inch tablets report back in to you in landscape mode.

Colorbox has a handy function colorbox.remove() that disables colorbox, very nice. Our script runs after colorbox is run, so this works. I also don't want the image to be a link at all, because else someone touching it in the mobile version would still go to the linked image. Colorbox only accounts for the image being loaded in a lightbox, but there always is a plain link involved to the image that appears in the lightbox.

So here preventDefault() comes into play, which prevents the default action of an element. For an anchor, this is the link, so it stops the link from being a link.

With beautytips I did not find a similar function like colorbox.remove() (and was a bit impatient) so I took a pragmatic approach. There are two things that happen to an element, when you add the class "beautytips" to it: it gets another class "beautytips-module-processed" and a property "bt-xtitle" that holds the html of the beautytip. The deciding element is the "bt-xtitle", which is a custom attribute created by beautytips.

To remove this kind of non-standard attribute (non-standard in not being a class or other attribute which are targeted by specific Jquery functions) you can use the removeAttr() function and use it like you would use removeClass(). It removes the "bt-xtitle"-Element and voilá, on 700px and below, no beautytips.

The script is only executed on document.ready, which is once the page is loaded. This is fine for colorbox and beautytips, since they also are just run once and before our custom script. But if you test the code and just resize your browser window on your desktop, you need to reload the page for the script to take effect.

Effects only when wanted

Javascript and Jquery can target specific screen resolutions, so we got rid of some unwanted effects quite easily in our mobile website. Anybody who has ever been completely blocked from browsing a regular desktop version of a website on his smartphone by a giant lightbox knows how annoying this can be. So despite of the process being very simple, we have made our website much more usable on a mobile device.

Kommentare

Marc

Responsive layouts since 2005, nothing new. :-)