Responsive Design with Twitter Bootstrap and Visualforce

by Keir Bowden (aka Bob Buzzard) - January, 2015

Responsive design is an approach to building web pages that aims to provide an optimal viewing experience across a wide range of devices, with a minimum of zooming, panning, and scrolling, plus easy navigation. The term was coined by Ethan Marcotte in his 2010 A List Apart article .

Technically, responsive design is a way of designing web pages so that they respond to the device that is displaying them. The page changes its content and layout based on features like the viewport size and orientation of the device. An important point to note is that all content and functionality should still be accessible from all devices - responsive design is not about punishing readers because they accessed your site via a smartphone, it's about optimising their experience.

This article is based on the developer zone session that I presented at Dreamforce 2014. The slide deck to the original session can be found here.


Why Use Responsive Design?

In the past, the approach to sites that could be accessed via multiple devices was to build a number of different sites (commonly known as M-Dot sites) and redirect the browser to the appropriate site based on information gleaned from the HTTP headers. The sheer number of form factors for devices nowadays means that this approach doesn’t scale well, quickly leading to a proliferation of sites. The following meme sums this up nicely:


Meme.png


There are several other reasons why responsive design is preferred to multiple M-Dot sites.

Simplifying Visitor Tracking

Its much easier to track visitors to a single site as opposed to trying to determine which of the visitors to multiple sites are unique, and which are the same user accessing via different devices.

Improving Performance

Accessing a main site and then being redirected to a device-specific version adds an additional round trip to the server, which for a mobile user accessing your content via 3G can introduce a multi-second delay. As discussed in my Developerforce blog post on architecting performant mobile applications , users accessing non-performant mobile pages are also likely to believe the site difficult to use, poorly designed, and does not contain interesting content.

It’s Google’s Recommended Approach

The advice from Google is that a single site is easier for them to crawl, as they can access all of the content with a single user agent. More importantly, it provides a single URL for users to share and link to, which helps Google’s algorithms to rank your content correctly.

How Can Pages Be Made Responsive?

There are three cornerstones to responsive design.


1. The Viewport Meta Tag

Smartphones will typically assume that the user would like to see the full desktop version of a site and set their viewport size accordingly. In the case of iOS Safari, the viewport width will be set to 980px, requiring the user to zoom to read text on the page.

The format of the viewport meta tag is as follows:

<meta name="viewport” content="width=device-width, initial-scale=1.0”></meta>

The width=device-width attribute tells the device to report its actual width, which in the case of iOS is 320px. The initial-scale=1.0 attribute tells the device to display the page at 1:1 scale, i.e. without any zoom in or out. You’ll often see an additional property of user-scalable=no, which stops the user zooming in or out of the page. You should not use this property as it can cause accessibility problems - for example, if a user is partially sighted it is perfectly reasonable that they expect to be able to zoom in to read text at a larger scale.


2. Fluid Grid

A fluid grid allows you to break your content up into rows and columns - here’s an example of the BrightGen web site with the fluid grid overlaid.


Grid.png


12-column grids are currently popular, as they are divisible by 2, 3, 4, and 6, giving several options for breaking up content on different size devices. The fluid aspect of the grid means that it expands to fill the available space, rather than displaying as a fixed width, which can result in part of the page being hidden offscreen or the content in the middle of a sea of white space.

Where fluid grids become truly responsive is when they reflow based on the device screen size. To demonstrate the concept of reflow, here’s a fluid grid when viewed on a wide desktop device - each row displays the full 12 columns:


Grid2.png


When viewed on a phone, however, the grid reflows to stack the columns on top of each other, one per row:


Phone.png


This example demonstrates the default behavior that many of the frameworks provide, but you also have the option to change this through markup, to display up to 12 columns even on a phone.


3. CSS Media Queries

A media query is a CSS rule wrapped in an expression that limits its scope. Essentially, it is conditional CSS that applies based on the device capabilities.

Consider the following CSS rule:

.sidebar {
	display: none;
}

This rule states that any element with a class of ‘sidebar’ will be not be displayed to the user - the element will still exist on the page, it will simply be hidden.

Add a rule wrapped in a media query as follows:

@media (min-width: 1024px)  {
	.sidebar {
     	display: block;
	}
}

This will apply the rule only when the device has a minimum width of 1024px - making the sidebar visible when the device has enough real estate to display it.


Bootstrap

Bootstrap is a responsive front end framework and my tool of choice for building responsive web pages. It not only provides elements mentioned earlier, such as a fluid grid and media queries to detect the device size, but also the HTML, CSS, and JavaScript to build good looking, responsive pages without too much effort. It contains a library of components for dialogs, menus, alerts, progress bars, and many others.

Boootstrap is mobile first, which means that the fluid grid cascades up, so when you define content spanning a particular number of columns for a phone, this is also the number of columns it will take up on a tablet and desktop. Note that mobile first does not mean mobile ready - it doesn’t provide any specialist behavior for building mobile applications, such as touch events or animated page transitions. Bootstrap is also the number one forked and starred project on Github.

Bootstrap isn’t without its critics, however - one of the common complaints is that all Bootstrap sites look the same, consisting of a black header with logo and menu, and all the dialogs/menus/progress bars have the same styling. Personally I don’t consider this to be that much of a problem - it allows people with no design ability (like me!) to easily create web sites that look good, are functional and responsive, which must be a good thing!

Fluid Grid

The Bootstrap fluid grid is implemented as 12 columns by default, although it is straightforward to create a custom build to change this. Bootstrap has style classes to change the grid behavior based on four device sizes (also known as breakpoints):


  • Large - greater than 1200px minimum width
  • Medium - between 992 and 1200px
  • Small - between 768 and 992px
  • Extra Small - less than 768px

Style classes are used to define how many columns a piece of content should span. The following element:

<div class=”col-md-6”>

defines that on a medium device or larger (mobile first, remember!), the content spans 6 columns, so 50% of a 12 column row. The following style class:

<div class=”col-xs-12”>

defines that on extra small devices and upwards, the content spans 12 columns, or 100% of a row. These style classes can be combined on a single piece of content:

<div class=”col-md-6 col-xs-12”>

This defines that the content spans 50% of a row on a medium and large device, but the full width of the row for extra small and small devices.

Integration with Visualforce

Much like when building mobile applications, when building responsive pages using the Bootstrap framework, Visualforce acts as a container, providing a thin wrapper around your HTML markup and a mechanism for access to your Salesforce data.

You’ll want minimal page generation tags - turn off the automatic generation of <HTML>, <HEAD> and <BODY> tags and exclude standard stylesheets, which can conflict with the Bootstrap styling.

You should expect to use very few standard components - components such as <apex:pageBlock> aren’t responsive, so they won’t reflow based on the device screen size. You could override the styling for these elements to make them responsive, but that goes against best practice as there is no guarantee that Salesforce won’t change the style class names and bypass your changes.

I typically find that I use the <apex:includeScript> and <apex:stylesheet> components to include resources, <apex:repeat> to iterate collections of data, and <apex:outputText> to format content such as dates and currency amounts.


Responsive Images

Desktop images can be large, and delivering these to a mobile device uses up costly bandwidth and consumes the limited device memory. A study in 2012 found that 86% of sites were delivering the same content to all devices - including large images that made the user experience slow and painful on mobile devices. This is because the site designers are using a technique called ‘Download and Shrink’ to deliver a single image regardless of device and use CSS media queries to resize them appropriately for the device. This is a wasteful technique, as reducing the dimensions of an image by 50% discards 75% of the data delivered to the device.

The HTML5 <picture> element will provide for responsive images without resorting to JavaScript, but as of December 2014, is only supported by Chrome and Opera.

The best option at present, in my opinion, is Picturefill by Scott Jehl, which is a JavaScript polyfill for the HTML5 <picture> element. It uses JavaScript to load the appropriate image based on device attributes, driven from HTML5 “data-” attributes on
or elements. Example markup for Picturefill is shown below:
<span data-picture="1" data-alt=”BlogImage">
  <span data-src=”large_image" data-media="(min-width: 1024px)"></span>
  <span data-src=“medium_image" data-media="(min-width: 768px)"></span>
</span>

The image source is defined by the data-src attribute, while the data-media attribute defines the media query that must be satisfied in order to use that specific image. The downside to this mechanism is that it uses JavaScript to process the element and decide which image to load, which introduces latency, as the JavaScript won’t execute until the page is loaded, and an additional round trip to the server to fetch the appropriate image.

A more in depth discussion on responsive images is available on my blog.


Demonstration Site

For my session at Dreamforce '14, I built a simple demonstration using an unauthenticated Force.com site - a blog containing a few recent posts, comments on those posts, keyword searches, and links to my twitter and facebook profiles. You can access the site via this shortlink - once you have the home page open, resize your browser to see what happens when the viewport size changes. The target page of the ‘Links’ menu item contains a list of all of the resources that I found useful when I started coming to grips with Responsive Design - hopefully you’ll find them useful.

The code behind the site is available on Github, and also as a managed package - see the Github Readme for more information.

About the Author

Keir Bowden (aka Bob Buzzard) twitter.com/bob_buzzard, is a four-time Force.com MVP, Salesforce-Certified Technical Architect, and CTO of BrightGen www.brightgen.com, a Platinum Cloud Alliance partner in the United Kingdom. He is a regular blogger on Apex, Visualforce, and Salesforce1 solutions at The Bob Buzzard Blog and author of the Visualforce Development Cookbook.