Adaptive Website Made Easy
A few years ago a colleague of mine and fellow developer, Craig Verrastro, invited his daughter’s music teacher to come present to my department. Why? Because he was seeing impaired, and we wanted the team to see what browsing the web (especially our own applications) was like for someone using a browser for the visually impaired. There were many very interesting moments during the exercise, but one really stuck out for me. At one point he encountered a site that detected that he was using a seeing impaired browser, and redirected him to a simplified version of the site, which was also the site’s “mobile friendly” version. This frustrated him and he immediately found the link to go to the full site. He pointed out that he disliked sites that did this. He said he noticed most people with normal eyesight often disliked these sites just as much, “who wants only a part of the site? No, I want the whole site. If it’s interesting enough to go on the full site, why wouldn’t I want to get it too?” He had a great point and I feel many mobile users feel the same way. I have not found any statistics, but I feel most mobile users do not mind a site optimized for their device, but don’t want some sort of reduced experience.
This has lead to a firm belief of mine when it comes to adaptive web applications and sites. If we follow all the best practices and coding standards, we should be able to create very clean and adaptive web applications and sites easily and without sacrificing quality regardless of what device is being used. In this article I want to show you a method of doing this which does not require any programming language at all. This is a pure CSS/HTML solution. In its basic form it doesn’t even require any JavaScript. I like this method because of how simply and easy it is. Simple and easy means it is easier to maintain and easier to scale. Before I give you the code, let me show you an example and explain how it behaves.
A Few Demonstrations
You can take a look at a very basic example here:
When you load the page you will see it layout in a way specific to your screen’s resolution and orientation. If you are opening this on a PC in a modern browser such as Chrome, IE9+*, or Firefox you will be able to change the size of the browser’s window and see this at work. When the browser window is at full size, it will be blue and the last row will be 3 blocks wide.
As you size the window down you will see the background turn green as an indicator that the page has been compressed slightly to fit the smaller visible area. You will also see the font size is reduced slightly, and block #4 disappeared completely (despite my assertion that a mobile site should not be a reduced-content version, I wanted to prove that it can be done with this solution if the need arises) . If you reduce the screen size even further you will see the background turn red to indicate it is now at maximum compression. In this state the font and company logo are even smaller and the entire page is vertical; the last row no longer has horizontal blocks.
What does this mean for mobile browsers? Well, the logic I have implemented here is:
- Full Mode (blue): screen is > 800px wide
- Compressed Mode (green): screen is < 800px wide
- Minimal Mode (red): screen is < 400px wide
This approach works well in most cases in my experience. Instead of designing around specific devices (i.e. “Here is our iPad layout, here is our iPhone layout, oh wait, now we need Android layouts because they have different aspect ratios,…”) you are designing around how much visible space there is. The page doesn’t care if the visible space is small because it’s on an iPhone or because the user shrunk their browser window down; all it needs to know is how much real estate it has. For example, using the dimensions I specified above you will enable the following for apple devices:
- Full State (blue): iPad in Landscape Mode
- Compressed Mode (green): iPad in Portrait Mode or iPhone in Landscape Mode
- Minimal Mode (red): iPhone in Portrait Mode
Also, using this method will still hold together when the user opens this page or application on their XBox, or on their web enabled refrigerator screen, or any other device that comes down the road in the future.
How well does this solution perform in browsers for the visually impaired? Perfectly. As long as the site follows HTML coding standards and common practices these browsers will receive the entire page, instead of a reduced version. The same applies to search engines for SEO.
As a more complete demonstration for how this can work I created this small calculator application:
This uses the same method as my first example, but it is far more subtle because it is an actual application. However, if you re-size your browser window you will see the font size change slightly, and the forms will layout differently. As you do this, I think you will see how these subtle changes would make the application fit better on different devices.
How (The Code)
Let’s get into the code of the solution, so you can see how easy this is to implement. The root of this solution is these lines of code in the HTML page itself:
< link rel="stylesheet" media="all"
href="main.css" type="text/css" />
< link rel="stylesheet"
media="only screen and (max-width: 800px)"
href="mid.css" type="text/css" />
< link rel="stylesheet"
media="only screen and (max-width: 400px)"
href="min.css" type="text/css" />
This will include 1 to 3 style sheets, depending on the screens width. If the screen is over 800px wide only main.css will be included. If the width is between 400px and 800px wide, then main.css and mid.css will be included. If the screen is less then 400px wide then all three will be included.
First, go ahead and take a look at the main.css. In here I have the full CSS for the site or application’s largest formatting. Next take a look at mid.css. This CSS will be added once the browser window is less then 800px wide. You will see that this file is smaller. This is because main.css is still included, and included before the mid.css. Therefore, mid.css only needs to specify what is different from the main.css. In otherwords, mid.css is overriding styles from the main.css. This avoids having to duplicate all the styles, mid.css only needs to worry about what changes once the visible area drops below 800px wide. For example, main.css gives the body tag a blue background. However, the mid.css overrides this and gives it a green background instead. This is why when the screen is over 800px wide the background is blue, but when it is less then 800px wide it is green.
The same principle applies to min.css. This CSS is included when the screen drops below 400px wide and again contains only the differences from the main.css & mid.css.
Hopefully, I have not over-explained this solution, and have been able to express how easy it is to implement. You simply start with your core CSS, likely the CSS you already have in place for your site or application. Then you create two more (mid.css & min.css) which only need to contain the differences in your site from the main style sheets. Include them in your HTML using the tags I show above, and you are done.
Wrap Up
I started this article by asserting that a mobile site should not be a reduced version of the full site; and I have provided a simple approach to implementing that ideal. The solution I have outlined here certainly can be used even if you do not adhere to my unreduced-mobile-site philosophy. However, ask yourself this, if a piece of content is unimportant enough to cut out of the mobile-version of your site, then why is it important enough to clutter up the full-version? My philosophy is as much about keeping a full-site uncluttered with unnecessary content as it is about keeping a mobile-site fully functional. When architecting and designing your site or application, try not to think in terms of different versions for different browsers and clients. Simply think about what content your site should have on it, and then how to best tailor that content into different sizes of real estate.
Either way, I hope you find this solution helpful.
* Its worth noting that this solution works in IE 6+ as well, but you need to hit the refresh between each re-size to see the change (there is a way to fix that using JavaScript, but I didn’t include it for the sake of a simpler and more pure demo).