Responsive design with “switch to desktop site” option

In my latest responsive design creation, I wanted to follow Jakob Nielsen’s guidelines and allow mobile users to have easy access to the full desktop site, if desired. This is relatively straightforward to do if you have a CMS, but a static site has to be a bit more creative.

Here’s the solution I came up with. It uses JavaScript, a small browser cookie, and that magical tool no web developer should be without, Modernizr.

First, the HTML. If you’re using the HTML5 Boilerplate like I am, you’ve already got a meta tag near the top of every page that looks like this:

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

That one tag is the keystone of responsive design: it tells mobile browsers that it should view this page using a “small screen” instead of a zoomable “desktop screen.” So we’re going to give our users the chance to turn it off.

I replaced that meta tag with the following:

<!-- allow mobile users to switch to the desktop site by setting a cookie variable -->
<script src="/js/toggle-mobile.js"></script>
<noscript><meta name="viewport" content="width=device-width, initial-scale=1"></noscript>

Note the “noscript” tags, which ensures that if the user (for whatever reasons) has turned off JavaScript in his or her smartphone browser, he or she will still get the mobile design by default. Why make mobile the default? Because (a) it’s the one that’s optimized for small screens, (b) we’ll need JavaScript to toggle the desktop site anyway.

So, what’s in “toggle-mobile.js”? Just a short block of code that uses document.write to write the meta tag back out, if (and only if) the user hasn’t requested the desktop version.


First, we need some cookie reading/writing functions. (Update: but read on for an alternate approach using sessionStorage!) Choose your favorite — jQuery has an old and popular jquery.cookie plugin which you might already be using, but if you’re not, we can do this fairly easily in vanilla JS. Scott Andrew of quirksmode.org has a few quick and easy cookie functions I’ve chosen to use myself:

// below functions copied from http://www.quirksmode.org/js/cookies.html
function createCookie(name,value,days) {
  if (days) {
    var date = new Date();
    date.setTime(date.getTime()+(days*24*60*60*1000));
    var expires = "; expires="+date.toGMTString();
  } else {
    var expires = "";
  };
  document.cookie = name+"="+value+expires+"; path=/";
};

function readCookie(name) {
  var nameEQ = name + "=";
  var ca = document.cookie.split(';');
  for(var i=0;i < ca.length;i++) {
    var c = ca[i];
    while (c.charAt(0)==' ') c = c.substring(1,c.length);
    if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
  };
  return null;
};

function eraseCookie(name) {
  createCookie(name,"",-1);
};

Now, the code to toggle our desktop site:

/* IMPORTANT! Run this script inside the <head>...</head> tags near the top, 
so the <meta name="viewport"> tag is written out in the correct place. */

if (readCookie('nomobile') === 'true') {
  var docElement = document.documentElement;
  docElement.className = docElement.className + " mobile-fullsize";
} else {
  document.write('<meta name="viewport" content="width=device-width, initial-scale=1">');
};

function toggleMobileFullSite() {
  var curr = (readCookie('nomobile') === 'true');
  createCookie('nomobile',!curr,0);
  location.reload();
};

Update: Having said all that, an easier way to write this JavaScript code (as suggested by a reader in the comments below) would be to use sessionStorage instead of cookies, since we’re targeting modern mobile browsers anyway:

/* IMPORTANT! Run this script inside the <head>...</head> tags near the top, 
so the <meta name="viewport"> tag is written out in the correct place. */
/* sessionStorage version, no cookie functions needed */
if (sessionStorage.getItem('nomobile') === 'true') {
    var docElement = document.documentElement;
    docElement.className = docElement.className + " mobile-fullsize";
} else {
    document.write('');
};

function toggleMobileFullSite() {
    var curr = (sessionStorage.getItem('nomobile') === 'true');
    sessionStorage.setItem('nomobile',!curr);
    location.reload();
};

In both versions, toggleMobileFullSite() is a self-contained function we’ll trigger using JavaScript to switch the “nomobile” cookie (rename it if you like) between “true” and not-true. There are actually a couple different things going on here. First, we check if the “nomobile” cookie is set to “true”. (Remember, cookie values are always strings.) If it’s not “true”, it writes out the meta tag that enables small-screen mobile browsing, and we’re done.


If the “nomobile” variable is “true”, however, we add a class called mobile-fullsize to the HTML element, in the same way that Modernizr does — we’ll use that class to show or hide elements on the page.

What elements, I hear you ask? Well, how about a link to switch back to the mobile design? It would be rude to send our mobile users one a one-way trip to the desktop site (especially if they clicked it by accident), but at the same time, we don’t want our actual desktop users to see a link to switch to the mobile design — if we’re using CSS media queries to style our page responsively, then such a link won’t do anything in a desktop browser anyway. (Desktop browsers who want the mobile design can see it just by narrowing their browser window.)

So, now we’re on to phase two: actually empowering mobile users to switch between mobile and desktop sites. We’re heading back to the HTML with a hearty assist from CSS media queries.

Somewhere in the header navigation, your page footer, or both, we’ll stick a couple of hyperlinks that look something like this:

<a class="mobile-only" href="javascript:toggleMobileFullSite()">Desktop site</a>
<a class="mobile-only fullsize-only" href="javascript:toggleMobileFullSite()">Mobile site</a>

Both links trigger the toggleMobileFullSite() function, and both have a “mobile-only” class which we’ll hide from desktop users. But since that includes mobile users who’ve switched to the desktop site, we add a “fullsize-only” class to the second link.


Now we’ll need a little responsive CSS. Modernizr gives us .js and .no-js classes on the HTML tag, which we’ll exploit here. In keeping with the design of the HTML5 Boilerplate, this CSS is “mobile-first”:

/* mobile-first styles */
.no-js .mobile-only,
.lt-ie9 .mobile-only, /* IE7-8 doesn't support media queries */
.no-js a[href^="javascript:"] {
  display: none !important;
}
.js .mobile-only.fullsize-only {
  display: none;
}

@media only screen and (min-width: 560px) { /* desktop */
  .mobile-only {
    display: none !important;
  }
  .mobile-fullsize .mobile-only.fullsize-only {
    display: inline-block !important;
  }
}

If a mobile user has JavaScript disabled, the “switch to desktop” link is hidden, because it calls a JavaScript function and won’t work anyway. However, if a mobile user has switched to desktop mode, then the mobile-only class has been added to the HTML element and we can exploit that in our stylesheet. In this case, and only this case, the mobile-only link is hidden and the fullsize-only link is shown. For actual desktop users, the mobile-only links are hidden away completely.

The only time this breaks down is if a desktop user narrows his or her browser window to view the mobile responsive design. This user will see the “switch to desktop site” link, but it won’t do anything. I consider this enough of an unusual edge case that we can safely ignore it.


We now have a complete solution, using a minimum of code. Mobile users with JavaScript disabled get the mobile design and nothing else; mobile users with JavaScript enabled will be able to toggle back and forth between the two; modern desktop browsers will get the full responsive desktop experience, without the toggle links; and older IE browsers get the mobile design, but without the toggle links.

4 Replies to “Responsive design with “switch to desktop site” option”

  1. This is interesting. We’ve had a few requests for a feature like this from university clients. My initial instinct was to first write this using localStorage, to avoid extra needless cookies being sent across the wires on each request.

    From http://caniuse.com/namevalue-storage it appears that localStorage does have fairly wide support in mobile browsers, the exception being Opera Mini, so writing fallback cookies support might not even be necessary depending on your use case.

  2. Excuse my ignorance… I have a shopify store but don’t know much about coding. Do I just add these codes to my code and it will work, or am I missing something huge and embarrassingly obvious?

Leave a Reply

Your email address will not be published. Required fields are marked *

*