Making a Website Mobile Friendly
by Fred Brack
Updated

This page documents one person's experience in making several websites mobile friendly.  "Mobile friendly" means when the site is viewed with an iPhone, Android device, or Windows Phone, the pages will be displayed in larger text with reduced line lengths mostly full-width and most likely with a minimized header and menu structure.  I do not present myself as an expert in this area, or in web design in general.  I'm just trying to help out folks trying to get started on this task by giving a detailed scenario.

What's the Problem?

The width of a mobile phone screen, whether held in portrait mode or landscape (sideways), is much smaller than any desktop or laptop screen, so displaying a full web page yields very tiny print.  When a website supports mobile devices, that means that text will be larger, line lengths will be cut way back, and to the extent possible, everything will fit on the screen without scrolling to the right.  It is not unusual today to find that 50% or more of your visitors are using mobile devices when they visit your site, so this is important.  (Note:  we don't consider "tablets" mobile devices here due to their larger screen sizes.)

What's the Solution?

The browsers are willing to help narrow the line lengths automatically if you include a certain "meta" statement.  If you are really lucky, that's all you'll need:  a one-statement addition to each web page and you're done!  Chances of that happening?  Slim.  So you have to do several other things, and they are outlined below.  OR, if you are using a content management system like Wordpress, Drupal, or Joomla, they will "automatically" take care of mobile support for you (well, mostly).

Before We Start ...

These solutions involve both CSS and JavaScript.  You really don't need to know much about JavaScript; you can take my file and modify just one line and access the file from your individual web pages with a simple one-line Script invocation.  But you DO need to know something about CSS:  Cascaded Style Sheets.  In fact, this approach works primarily via the very concept of "cascaded."  There are numerous resources for learning about CSS, but the most popular one seems to be W3Schools.  I need to "assume" you are using a style sheet for your website already (or will add one) and you already have or will add CSS IDs or classes to certain elements in your pages.  If you don't know anything about CSS, I recommend that you take a pause and learn a little about it before attempting the implementation steps below.

The Steps Involved

Here are the steps involved in modifying a website to become mobile friendly.  Consider them A START!  Your own website may be much more complicated, but this will get you started.

  1. Add the Viewport Meta Statement to every page.
  2. Add a simple JavaScript file to your website and modify one line as appropriate (I'll indicate how).
  3. Add one CSS file to your site and modify it as appropriate (I'll give you ideas).
  4. Publish a test file on your website (don't start with a live page, please!).
  5. Check the result on your desktop computer (when you make your first changes) to make sure you haven't altered the appearance of anything for the desktop.
  6. Examine the test page via a mobile device to see if you are satisfied with the results or need to make changes.
  7. After getting the test page working to your satisfaction, begin to modify other pages one by one to locate and fix any mobile problems.
  8. Make changes according to the type of problem you see:  too much space taken up by the masthead and navigation (something you'll fix on the test page, which will propagate to all other pages) versus some or all sections of the page not fitting the width.
  9. The first type of change (too much space taken up) will be solved globally; that is, you will make changes that are identical on every web page (but see my Note below).
  10. The second type of change (something doesn't fit) will involve page-by-page modification.

Note:  For purposes of our implementation discussion, we "assume" that you have some form of "global" header section (masthead and navigation) that automatically propagates to every page; that is, you will make the changes in one file, and those changes (to the header) will propagate to all pages.  I use Microsoft Essentials Web, for example, and in that product the "common code" is contained in something called the Dynamic Web Template (DWT) that can be applied page-by-page or globally.  In FrontPage (yes, some of us still use FrontPage!), it is accomplished via an Insert / Web Component / Included Content (a file, implemented via a WEBBOT statement).  I know nothing about Adobe's Dreamweaver.  If you don't have a common template or included file, then you'll have to modify each page separately to insert the one-line test for mobile and perhaps some ID or Class references, if you don't have them in place already.

Get Started

Take a simple file on your website, one without tables or pictures, for example, but definitely a full header and navigation area, and copy it over as "test.html" or something like that.  You will work with that file to make the basic changes you want to see on every page and perhaps experiment with some of the techniques below before attempting modification of "live" files on your website.  Once you are satisfied with the appearance, you can insert the Viewport statement and call to the JavaScript file detailed below on every page on your site, then begin the process of page-by-page analysis.

Add The Viewport Meta Statement

Meta statements are always added in the <head> section of a web page.  They control certain aspects of page presentation or document information about the page.  There is ONE statement which can be added to tell your browser to do whatever it can automatically to make your page fit properly on a mobile device, so you will almost always want to add the following statement anywhere in the <head> section:

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

Note that if you are writing in XHTML mode (as opposed to regular HTML), you will need to "close" the above statement by adding a SPACE and a SLASH at the end:

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

Since I personally use XHTML in my main site, you will find the trailing space-slash in my examples below.  Be sure to remove them if you aren't using XHTML.

Save your file and look at it on your mobile device.  If you are satisfied, you're done!  More likely, though, you will notice two things:

  1. The page heading and the navigation area take up too much room on the screen, something that will no doubt replicate on every page.
  2. Either the lines all extend beyond the right side of the screen, or SOME content extends there while other content does not.

You solve each of these problems separately; and, of course, just because the test file doesn't have problem #2 doesn't mean other pages won't.

Add One JavaScript File to Your Website

If you have other JavaScript files already, you probably have a "js" subdirectory, and you'll put this file there.  If you have a simple website and this is your first JavaScript file, go ahead and put it in the main directory if you like, OR create a new "js" subdirectory and use it.

This "Check4Mobile.js" JavaScript figures out if you are on a mobile device, and if so it adds a CSS file to your page (I call it mobile.css).  That CSS file controls all the aspects of your web page that you need to CHANGE DYNAMICALLY to support the mobile device.  We'll discuss its content shortly.  Here's the file content:

// Check4Mobile: Determine whether or not this is a MOBILE device.
// IF YES, set 'mobilePhone' to TRUE and cascade the mobile style sheet.
// The href MUST specify the fully qualified URL address of mobile.css.
// REMOVE THE SLASH at the end of the cssmobile line if not using XHTML!
var ua=navigator.userAgent;
var mobilePhone=false;
if (ua.indexOf("Android")!=-1) mobilePhone=true;
if (ua.indexOf("iPhone")!=-1) mobilePhone=true;
if (ua.indexOf("Windows Phone")!=-1) mobilePhone=true;
if (mobilePhone) {
    var cssmobile='<link href="FULL-PATH/mobile.css" rel="stylesheet" type="text/css" />';
    document.write(cssmobile);
}

Right-Click to DOWNLOAD a copy of the above JavaScript File

(Yes, the "var cssmobile" data could be written directly, so do that if you understand how and prefer it!  You can also experiment by including the SCRIPT shown directly in your test file, bounded by the appropriate statements.)

The lines beginning '//' are comments which you can leave in the file.  You MUST supply the full path to your CSS file as shown.  (The reason you need the full path is so that if you have HTML files in subdirectories, this statement will always access the absolute address, not the relative one.  For example, the href in Check4Mobile.js for THIS webpage is "http://www.bracksco.com/personal/css/mobile.css".)  So what this JavaScript does is look for the three types of mobile phone names in the so-called "user agent" of the browser (navigator).  While not important to your implementation, just for reference a typical "user agent" line (for an iPhone in this case) looks like this:

Mozilla/5.0 (iPhone; CPU iPhone OS 10_2_1 like Mac OS X) AppleWebKit/602.4.6 (KHTML, like Gecko) Version/10.0 Mobile/14D27 Safari/602.1

Now you need to invoke this JavaScript file in each web page, and you need to do it at the right spot!  In the true spirit of "cascading" style sheets (CSS), you MUST MUST MUST cascade this one AFTER all your other style sheets ... because the nature of cascading style sheet is:  the last one wins!  In other words, the content of THIS style sheet that you are invoking will OVERRIDE the contents of the previous one(s) and thus modify whatever is necessary for proper presentation on a mobile device.  So place the following statement AFTER the meta statement(s) which invokes any other style sheet(s):

<script src="js/Check4Mobile.js type="text/javascript"></script>

You need to adjust the "src" statement to point to wherever your JavaScript file is.  For example, remove the "js/" if you put it in the main directory.  Depending on what method you use to insert this statement, you may be better off specifying the full path to the .js file like you did for the .css file inside the .js file above.

So ... when this Script file executes, if and only if you are running on a mobile device a new Style Sheet named mobile.css will be cascaded following any other ones you have.  Speaking of mobile.css, let's discuss it.

Add One CSS File to Your Website

As above for JavaScript, you may very well have a css subdirectory on your website, and that's where this file goes.  If not, create one or just add this file to the main directory.

I can't predict the proper content for your mobile.css file; I can only show you an example and tell you how and why to add other statements.  In general, though, the purpose of the mobile.css file is to override ID and Class definitions to suppress or modify the appearance of file content on the mobile device.  So here is a brief example, followed by an explanation.  Please note that while I show a mixture of ID definitions (beginning with '#') and Class definitions (beginning with '.'), use whatever works for you -- they end up having the same results in appearance.

/* mobile.css: Style modifications to support mobile devices */
/* Everything which follows is an EXAMPLE ONLY!              */
/* YOU need to decide the exact content.                     */

/* To minimize the heading size, we will suppress logos */
#logoleft  { display: none }
#logoright { display: none }

/* Suppress the regular heading and activate a mobile one */
#header       { display: none }
#headermobile { display: run-in }

/* Eliminate two-column mode */
#left_col  { width: 100% }
#right_col { width: 100% }

/* Suppress navigation, because we will do it differently */
table.nav { display:none }

/* Override table widths to 100% */
table.width80m { width: 100% }

/* Provide a generic "don't display on a mobile device" class */
.mobileno { display: none }
/* And a "mobile-only" display option */
.mobileyes { display: run-in }

/* Define the characteristics of the mobile title line */
.sitetitlem {
    font-family: Verdana, Geneva, Tahoma, sans-serif;
    font-size: medium;
    font-weight: bold;
    color: navy;
    background-color: yellow;
    text-align: left;
}

/* Provide new class for mobile navigation page */
.mobilenav {
    font-family: Verdana, Geneva, Tahoma, sans-serif;
    letter-spacing: 2px;
    text-align: center;
    width: 100%;
    margin-top: 0px;
    margin-bottom: 0px;
    display: list-item;
}

Right-Click to DOWNLOAD a copy of the above sample MOBILE.CSS File

Whew!  What's that all about?  Here goes ...

Header

A "typical" web page has a common header consisting of a logo on the left, perhaps repeated or showing a different image on the right, and some large text in the middle naming the website or the specific page.  There may be additional text in the middle also, or text on the right instead of a second image.  Assuming you have used ids (or classes) to define these three areas, you can MODIFY those definitions via the mobile.css.  In the case shown above, the first four CSS lines (other than comments) are modifying a website with an image on the left and right and a header in the middle.  The images are SUPPRESSED via the "display: none" CSS option.  The header as defined originally is also suppressed, and an ALTERNATE HEADER for the mobile site is activated (by using "display: run-in" which is effectively the opposite of "none").  To help you understand this concept better, here is how the header might be defined with IDs which match the CSS above:

<!-- Masthead (Logos and Site Title) -->
<div id="masthead">
  <div id="logoleft">
    <img alt="Logo 1" src="images/logo1.gif" height="100" width="100" />
  </div>
  <div id="logoright">
    <img alt="Logo 2" src="images/logo2.gif" height="100" width="100" />
  </div>
  <div id="header">
    <span class="sitetitle"><strong>My Long Website Title</strong></span><br />
    My organization's motto or something like that on second line
  </div>
  <div id="headermobile">
    <a href="menumobile.html"><img src="FULL-PATH/images/menu.jpg" alt="Menu"
    height="27" width="69" style="vertical-align: middle"></a>
    &nbsp;Short Website Title
    <hr style="margin-top: 0px; margin-bottom: 0px" />
  </div>
</div>
<!-- End of Masthead, Beginning of Navigation -->

EXPLANATION:

Navigation

Moving on to navigation, typically (but not always) this is found at the top of the page right below the masthead.  And typically (but not always) it is shown as tabs or options in boxes.  If the boxes are created using a table, then they will most likely be wider than the width of a mobile device, and right away you have a problem.  Regardless, if there are more than just a few options (the main site I work on has three rows of 5, for a total of 15 navigation options), then this will take up a lot of space.  YOU must decide whether or not you need to change the navigation area for your mobile device.  The HTML example above continues like this (simplified):

<div id="navigation">
  <!-- IF MOBILE, table.nav PROPERTY WILL BE REPLACED WITH display:none -->
  <table cellpadding="2" class="nav">
    <tr>
      <td class="nav">
      <a href="index.html">Home</a></td>
      <td class="nav">
      <a href="about.html">About</a></td>
      <!-- and the navigation continues like above ... -->
    </tr>
  </table>
</div>
<!--********** End of Navigation, Beginning of Page Body **********-->

OK, CSS purists, don't beat me up for showing a table for navigation!  That's not important here.  Also note that the class="nav" in the TD is a different CSS definition from the same class at the table level.  When you suppress display at the table level, TD definitions don't matter.  In other words, we just suppressed the entire navigation block via the mobile.css entry "table.nav { display:none }".

So, you ask, where IS the MOBILE navigation?  It should be noted that some mobile menu implementations will simply redefine how the TD entries are displayed (for example, instead of putting them in an obvious table, simply display them one after the other horizontally in a simple textual listing).  Other fancier implementations will use the basic concept I show below BUT the menu will act as a pull-down instead of a new menu page.  I felt it wasn't worth the effort, and there is no standard way to do this currently -- there are lots of approaches, so this is only one idea.  If you look back under Header above, you will recall this section of code:

<div id="headermobile">
  <a href="menumobile.html"><img src="FULL-PATH/images/menu.jpg" alt="Menu"
     height="27" width="69" style="vertical-align: middle"></a>
  &nbsp;Short Website Title
  <hr style="margin-top: 0px; margin-bottom: 0px" />
</div>

In our example, mobile navigation will be moved to a SEPARATE PAGE, mobilemenu.html, accessed via a URL link under the Menu image in the mobile header, as defined above under ID (or Class) "headermobile".  In other words, the new header for our mobile devices looks like this (minus the bar underneath, which was hard to reproduce here):

 Short Website Title

... and if you click the Menu icon (which you can do here if you like), you'll get a separate web page with nothing but the site navigation options centered in a list.  The class definition for that page is shown in mobile.css above as mobilenav, and the menu page itself (menumobile.html) consists of lines that look like this:

<h2 class="pagetitle">Menu</h2>
<p class="mobilenav">
<a href="index.html" title="My Website Home Page">Home</a><br />
<a href="about.html" title="About My Website">About</a><br />
<!-- ... more of same ... -->
</p>

Feel free to "steal" my Menu image above by right-clicking on it and downloading it.  I designed it myself, so there is no copyright concern.

The Next Steps:  Full-Site Implementation

Whew again!  Once you have completed the installation and testing of the JavaScript and mobile.css files AND figured out what you are going to do about navigation, you can begin implementation sitewide.  I recommend you do this page-by-page, figuring out what techniques are necessary to get pages displaying to your satisfaction.  Some ideas for this follow.

Oops, Lines or Tables Extend Off-Screen

Inevitably, when you look at your mobile website, some pages will run their lines off-screen, and in particular, tables will extend off-screen to the right.  These are some of the situations you may find and suggestions on how to correct them.

  1. Look for LONG UNBROKEN TEXT.  If you put a long line of asterisks in your page anywhere, the browser will take that as your minimum line length and everything will be compressed.  If you put a long URL in the text, the browser will not break long lines of text like that.  (Your solution in that case is probably to bury the link in the HTML under words.  A possible "fix" for the long line of asterisks is to use the <hr> tag instead.  Another "fix" involves using <span style='word‑wrap: break‑word'>looooooooongphrase...</span>.)  SEE THE EXAMPLE BELOW.
  2. Look in your main CSS file for the styles MIN-WIDTH or WIDTH.  Percents are fine (e.g., width: 80%); large numbers are not (width: 600px).
  3. Images in tables are problematic.  The image width is fixed and will determine the width of the entire column.  See below for a way to eliminate them.
  4. Multiple table columns are problematic.  The more columns, the harder to fit in that narrow space.  Sometimes this is unavoidable.  You should warn the user though, and a method to do this is discussed below.
  5. Large images may extend off the screen.  This is often OK, but using the method below, you COULD use a smaller version of the image for mobile.

Here's an interesting example of a solution for a page in which the author happened to have many long URLs listed out in unordered lists.  This was implemented originally in a <style> section in the <head> of the page for testing, then moved to the mobile.css file to apply universally across the website:

li { word-wrap: break-word }

Note that the CSS does NOT start with a period or hash-tag.  It overrides the default system definition of the list item tag to allow breaking long words.

Suppress Text or Images on Mobile

Sometimes you may find a big hunk of text (or even tables or images) that you can do without on a mobile device.  You do this by using a class which says basically, "mobile only."  The opposite is also true:  a class which say "non-mobile only."  These classes are defined in the CSS example above as:

/* Provide a generic "don't display on a mobile device" class */
.mobileno { display: none }
/* And a "mobile-only" display option */
.mobileyes { display: run-in }

To suppress a paragraph, add "class="mobileno" to the paragraph tag.  To suppress EVERYTHING in a certain area, put it in a DIV.  Examples:

<p class="mobileno">This will not display on mobile.</p>
<div class="mobileno">
    <!-- nothing here will display on mobile -->
</div>

Another example would be suppressing an image which is too large:

<img class="mobileno" alt="Our Office" src="images/office.jpg" height="300" width="600" />

That line says, if we are on MOBILE, then NO, don't display this image.  But you MIGHT choose instead to offer a smaller image for mobile on the very next line:

<img class="mobileyes" alt="Our Office" src="images/office.jpg" height="100" width="200" />

BTW, my iPhone 7 appears to support an image of 300 pixels wide.

Another thought:  suppose you have a table which you simply can't reduce enough to fit on the screen.  You could write something similar to the following which would only display on a mobile device:

<p class="mobileyes">Attention Mobile Users: The table below is too wide for normal display,
but the third column is generally not of key interest; so either ignore it or turn your
mobile device sideways to read the full width.</p>

Eliminate a Table, Column, or Row

To understand your options, keep in mind there are three basic table tags:  <table>, <tr>, and <td>.  You can add "class="mobileno" to any of them.  If you add it to the <table> tag, the entire table will be suppressed.  If you add it to the <tr> tag, the entire row (of imbedded <td> cell definitions) will be suppressed.  If you add it to the <td> tag, the entire column will be suppressed, provided you add it to every cell in that column.  However, you may find that your web management program (e.g., MS Essentials Web) will act very strangely and not display what you will ultimately see via your browser!

Caution:  there is a "gotcha":  There is no CSS equivalent for the table colspan option.  So if you have any data in your table that spans multiple columns, you cannot eliminate one or more columns of data.  (Well, you can eliminate them, but the column-spanned row will look awful.)  Trying to add "class="mobileyes" and "class="mobileno" to two consecutive <tr> tabs with different column spans will not work.  (I have not tried this with two repeated sets of <tr> and the imbedded <td> definitions however...)

Ultimate the primary value of these options is to eliminate either an entire table (which could also be done via a DIV), or to eliminate one row (say the far right) if it has low-value data, so the table fits better on the screen.

Convert Two Non-Table Columns to One

In CSS (as opposed to using a table), the "normal" way to display text in two columns is to "float" text to the left or right; something like this:

<div id="left_col">
  <h2 class="article">First Article</h2>
  <p>Text of article 1 ... </p>
  <!-- repeat above for next article, etc. -->
</div>
<div id="right_col">
  <h2 class="article">Fifth Article</h2>
  <p>Text of article 5 ... </p>
  <!-- repeat above for next article, etc. -->
</div>

The regular CSS definitions of the columns might include:

#left_col {
  float: left;
  width: 50%;
  position: relative;
  clear: both;
}
#right_col {
  float: right;
  width: 49%;
  position: relative;
  text-align: left;
}

If you try to display a page with two columns on a mobile device, it will look awful; so you need to "defeat" the columns.  You do this simply as shown in our original mobile.css example:

/* Eliminate two-column mode */
#left_col  { width: 100% }
#right_col { width: 100% }

Now the text in the right column will simple begin after left column text has been displayed (full-width).

Make Indented Tables Full-Width

I personally like to make tables narrower than full-screen and center them.  So I would typically include the option WIDTH=80% (or some other number) as part of the table definition.  By changing that to a CSS CLASS, you can make the table full-width for mobile devices using something like "<table class="width80m" ...>".  So, for example, my main CSS file has this statement (with the "m" meaning it is different for mobile):

table.width80m { width: 80% }

... and my mobile.css file has this statement overriding it:

table.width80m { width: 100% }

Eliminate Indentation for Lists

Normally list items "<li>" are indented.  On mobile, this takes up precious space.  You can eliminate that space by creating the following class definition in your mobile CSS file.  (Credit for this idea goes to Jpsy in StackOverflow, a good place to get CSS questions answered.  He points out, though, that the exact spacing varies by browser; so this may not fully butt the bullet up against the left column for you.  This is the "safe" value.)

.justifym { padding-left: 1.2em }

... then start your list with:

<ul class="justifym">

(We didn't start the class with ul so that it could be used with ol also ...)

Eliminate Other Indents

Interestingly enough, when I tested this page, I found the fact that I indented the sample code was annoying on mobile, so I gave each affected paragraph its own class ("indentex") and specified an indent in the main CSS file (.indentex { margin-left: 20px }) and no indent in the mobile CSS file (.indentex { margin-left: 0px }).  In other words, the sample code above is coded this way:

<p class="indentex"><span class="example">.justifym { padding-left: 1.2em }</span></p>

I should also point out that CODE EXAMPLES like this don't look great on a mobile device, because line-wrapping makes it harder to tell where one line ends and another begins; but hopefully most people won't be reading this from a mobile device (although I urge you to take a look to see what it happens and how mobile presentation looks, since that's what this page is about!).

Other Resources

As I find them, I'll add sites that address issues that I don't cover above.

And in Conclusion ...

I hope this tutorial has been helpful in getting you started to support your website on mobile devices.  If you have any feedback on corrections or better implementations of the concepts above, feel free to write me as feedback@bracksco.com.  If you want to view the primary website which I modified to support mobile, please visit the Audio Description Project ... on both your desktop and mobile device!

Fred

www.bracksco.com/personal