RespBreak: Javascript Breakpoint Handler for RWD

RespBreak allows you to handle breakpoints with Javascript, so you can make necessary structural changes to the document when a responsive design changes qualitatively.

Using CSS media queries can only achieve so much when it comes to responsive web design. At least today, it is required to use Javascript to change the order of elements, and perhaps add or remove elements from the DOM.

RespBreak uses an up()-down() pattern, inspired by Ruby on Rails DB Migrator. Every state, except one nominated state (typically state 0), has up() and down() methods. On calling up(), the DOM is brought into that state. When calling down(), the DOM is moved down to the previous state.

up_down_pattern

RespBreak is a small helper class which works out which up() and down() methods to call. This allows you to create mobile-first responsive designs. On page load, and on subsequent window resizes, RespBreak works out which state the document should be in. For example, if the HTML is served for mobile first and is viewed on a desktop, RespBreak will call up() on the tablet state object, and the desktop state object. You can do anything you want in up() — changing the structure of the page, or loading additional content may be typical usages. A call to down() should reverse the changes to move the document to the previous state.

As an example, consider the following HTML document:

<!DOCTYPE html>
<html>
<head>
<title>RespBreak Example</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="text/javascript" src="RespBreak.js"></script>
</head>
<body>

<p>This page is served mobile first.</p>

<p>My state:</p>

<div id="output">mobile</div>

<script type="text/javascript">
var state_mobile = {
    "ishere": function (width) {
        return (width <= 480);
    }
};

var state_tablet = {
    "ishere": function (width) {
        return (width > 480 && width <= 976);
    },

    // up from mobile
    "up": function () {
        document.getElementById("output").innerHTML = "tablet";
    },


    // down to mobile
    "down": function () {
         document.getElementById("output").innerHTML = "mobile";
    }
};

var state_full = {
    "ishere": function (width) {
        return (width > 976);
    },

    // up from tablet
    "up": function () {
        document.getElementById("output").innerHTML = "desktop";
    },


    // down to tablet
    "down": function () {
         document.getElementById("output").innerHTML = "tablet";
    }
};

new RespBreak([state_mobile, state_tablet, state_full], 0);
</script>

</body>
</html>

The ishere() method of each state establishes whether the document should be in a particular state. The up() method moves the document from one state to another (e.g. from mobile to tablet or from tablet to full). The down() method reverses this operation.

Once you’ve created state objects, you can just initialise a new RespBreak object with the state objects. The second parameter of the constructor is the state number that the HTML is, by default, served in. (In the above example, 0 for mobile, 1 for tablet or 2 for desktop).

I’ve uploaded a first version on https://github.com/brendonboshell/RespBreak.

Any feedback would be greatly welcomed. I’m keen on developing this idea a bit further. Automatically handling common tasks — such as removing, inserting or swapping elements — will probably be next on the agenda for the class.

Serving pre-gzipped files with .htaccess

If you have your server configured to automatically gzip files as they are requested, you could go a step further and pre-gzip the files so the gzipped version doesn’t have to be recreated each time.

Using the following .htaccess file, when style.css is requested, the server will look if style.css.gz exists. If it does, that gzipped version is served instead.

<FilesMatch "\.(css\.gz)$">
	AddEncoding x-gzip .gz
	ForceType text/css
</FilesMatch>
RewriteCond %{HTTP:Accept-encoding} gzip
RewriteCond %{REQUEST_FILENAME}.gz -f
RewriteRule ^(.*)\.css$ $1.css.gz [QSA]

To gzip a file, you can use something similar to this PHP code:

<?php
$file_url = "style.css";
$name = basename($file_url);
$gz_name = $name . ".gz";
$data = file_get_contents($file_url);
$gzdata = gzencode($data, 9);
file_put_contents($gz_name, $gzdata);

Audience Support

This post defines the browsers and screen widths I should aim to support in future web projects. It is based on analytics collected for various websites I have developed. The primary constraints aim to provide 95% coverage. The secondary constraints increases this to 99%.

Browsers

Primary:

  • Safari (recent) on iOS, Mac.
  • Chrome (recent) on Windows, Mac, Android
  • Internet Explorer 7.0-10.0 on Windows
  • Android Browser (recent)
  • Firefox 16.0 – 21.0 on Windows, Mac

Secondary:

  • Internet Explorer 6.0
  • Firefox 3.0 – 16.0 on Windows, Mac
  • Opera (recent) on Windows, Linux, Android
  • Opera Mini (recent) on Android, iOS, Blackberry
  • Blackberry (recent)
  • Amazon SIlk (recent)

Screen Resolutions

Primary:

  • Screen widths from 320px to 2560px