Old webmaster's guide to mobile-friendly websites

Suppose you have a website that was designed in a past era, or with a mindset from a past era. Or it's just made to look as if it was made in a past era for aesthetic reasons. You do it because you think information you provide is useful, or because you want to have a place to share things without relying on cloud services that sell your data, or you just miss the time when everyone was making homepages.

Then someone comes to you and says: your website looks bad on my phone! You ask them if they tried to use a computer, but it turns out they think phones are the new computers.

It becomes known. Your collegues laugh at you. A popular search engine excludes your website from search results due to its “presentation over usefulness” policy. Your parliament starts discussing fines for authors of mobile-unfriendly websites. You become known as the anti-mobile person in your town and a local newpaper picks up the story. Convicted felons start reading it to feel better about themselves.

You start reading about mobile-friendly websites and see articles by professional webmasters telling you how to make a hamburger menu and degrade the UI to the level of a device with 640x480px output and 1x1 inch input resolution.

You take inspiration from Wikipedia and other websites that have a normal version for real computers and a special version for limited devices. You think making a mobile version is easy, since there's even a special CSS media query for it (@media handheld), but then you discover that all devices other than old cellphones and PDAs ignore it.

But not all is lost! As a professional non-webmaster, I have a unique expertise that I can share with you to help your website survive in the hostile world filled with phones mistaken for computers. I'll focus on techniques that do not make your website worse for desktop users.

General considerations

All advice below assumes you already define the layout in CSS and got rid of table-based layouts. If not, you should do it first. Separation of the logical and physical layout is good for you since you can change the website look by editing just the CSS, and it also makes websites more friendly to people with special needs, e.g. screen reader users.

The viewport settings

This is said everywhere, but I'll add it for the sake of completeness, and because I cannot refrain from ranting about it. The first thing to ensure your website will render properly on mobile devices is to set the viewport meta tag. The viewport is the screen area where a web page is displayed. If you don't set it, your website will look unusably small. You can read the details in MDN.

The default, widespread, world standard viewport meta tag settings that mean “do what a sensible browser would be expected to do by default” are:

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

To me, it seems absurd that not even pure markup, Prof. Dr. style websites render in a readable way on mobile devices withut it. I see no valid reason to set the initial to anything else than the device width on systems that have no resizable windows, and I haven't seen anyone do it. Moreover, the additional options such as maximum-scale and user-scalable that prevent users from zooming in are outright accessibility nightmares. But that's the way it is. We've got what we've got.

Fitting elements to the screen width

Some elements can end up wider than screen, or wider than their parent element, which causes an annoying horizontal scroll. This problem is not unique to mobile browsers, it's just more apparent on narrow screens, so I think it's an improvement for all users.

Images, and, in some browsers, tables, are common examples of such elements. Setting max-width: 100% will limit their width to the parent element. For images, you also need to set display: inline-block. Other elements may also be suspectible, for example form inputs, HTML5 video, and object/embed tags.

table {
    max-width: 100%;
}

img {
    display: inline-block;
    max-width: 100%;
}

Preformatted text can also end up wider than screen, but the solution is different and it's a bit of a compromise. Since text cannot be automatically scaled down, the only solution is to allow the lines to wrap at whitespace characters but preserve whitespace otherwise, using the white-space: pre-wrap property.

For code in whitespace-sensitive languages such as Haskell and Python this can be a visual nuisance, but copying and pasting line-wrapped text works as expected, so the problem is purely visual at least.

pre, code, sample {
    white-space: pre-wrap;
    hyphens: none;
}

Detecting mobile devices

For some websites, switching to a “responsive web design” is simply not an option. If complex positioning of elements is a part of your artistic vision and you are not going to sacrifice it, best you can do is to give a completely different layout to mobile device users so that they can get the raw information from the website at least.

In a nutshell, there's no easy way to do it without server side checks or complex JS, but there's hope. First, a word of warning:

Don't check the screen size

There are many pages around that offer ready-made CSS media queries for detecting mobile devices by their screen size. It's better to ignore them because by now mobile devices screen size in pixels often equals or exceeds the size of common desktop screens, and even the ratio may be the same, so this criterion is useless for detecting if it's a mobile device or not. It's only useful for defining breakpoints for switching layouts between wide and narrow screens.

So, what can you use instead?

Check interaction media features

While the handheld media type is not supported by anyone, there's still hope for detecting mobile devices with CSS alone.

The mantra of responsive design has always been to test for capabilities, not specific devices. The defining characteristic of modern mobile devices is lack of a pointing device other than a touchscreen, which is their biggest limitation due to low input resolution of capacitive touchscreens. The irony is that there was no media query for a high precision pointing device capability. Now there is, it's called “media features” and provides two queries with slightly different semantics: pointer and any-pointer. Possible values are coarse and fine. The difference is that the pointer checks capabilities of the primary pointing device (whatever it means) while any-pointer checks if any device with given capability is available.

@media (pointer: fine) {
  /* Desktop browser layout rules */
}

@media (pointer: coarse) {
  /* Mobile device layout rules */
}

If you want to make it work in browsers that don't support that media query, you may take advantage of the fact that CSS rules are processed top to bottom and the last ones take effect, for example:

/* Red background in all desktop browsers */
body { background-color: red; }

/* Blue background in all mobile browsers that support the pointer query */
@media (pointer: coarse) {
  body { background-color: blue; }
}

Browser support for it only got close to universal in the late 2018, but some mobile browsers still don't support it so it depends on the audience you want to serve.

Behaviour of those queries on devices that have both a proper pointing device and a touchscreen is an interesting question, and I'm not in position to test it personally. Presumably, any-pointer: coarse should return true in that case, which is problematic if you are using the second approach to support old desktop browsers. If old desktop browser support is not an issue, any-pointer: fine ought to work fine on all devices with a high presicion pointing device whether they also have a touchscreen or not.

Layout

This is the tricky part. The widely adopted solution is so-called “fluid design”, where layout changes depending on screen width. There are two approaches: either using media queries for screen width to define “breakpoints” where the layout changes, or use the CSS flexbox or grid layouts to allow elements to automatically re-flow.

Re-flowing without fixed breakpoints is the cleanest solution imposes visual design limitations, since some kids of decorations like borders and per-element backgrounds can look ugly if what supposed to be a narrow column expands to the full screen width. Depending on your visual design preferences, you may be able to get away with it. Otherwise you will need to decide how it should look on smal screens and what screen size will be considered small.

If your layout is purely vertical and doesn't involve columns at all, you may only need minimal modifications to make it work on mobile.

Get rid of width values in absolute units

It's common to see something like width: 1000px for the main block, or sometimes width of every block defined in pixels. In the time when the world standardized on 1024x768 for a while, it might have been justified, but even then it would be problematic for people stuck with 800x600 displays.

Whenever you want to limit the width of an element, you should use the max-width property instead, and the physical layout should be defined in relative units (e.g. percents).

Screen orientation

Using a completely different style for mobile devices is the most radical option, but you may also try to make it better for people who have it worst: those using smartphones in portrait mode.

/* Rules for desktop and mobile in landscape mode */

@media (orientation: portrait) {
  /* Rules for portrait mode */
}

Conclusion

I hope the suggestions I collected will be useful for making old websites accessible to the mobile audience without hurting desktop users. If you have more suggestions, please share them with me.

This page was last modified: 2019-03-16