Roland Studer

How to do responsive opt-out by setting the viewport with JavaScript or Ruby on Rails

Roland Studer 25. Februar 2013

A client recently asked us to provide a possiblity to opt-out of the responsive behaviour of his website. While we believe that a well done responsive site does not need an opt-out button, we wanted to see how we could achieve this.

Setting the viewport

Usually we set the viewport to the device-width for a responsive site:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />

Now if we want the website to be displayed as if the device had a larger width, we just set the width accordingly.

<meta name="viewport" content="width=1024, initial-scale=0, maximum-scale=1.0, minimum-scale=0.25, user-scalable=yes" />

Source: CSS-Tricks

Javascript approach

You can easily change the meta-tags content with javascript by doing something like this:

document.getElementById("viewport").setAttribute("content", "width=1024, initial-scale=0, maximum-scale=1.0, minimum-scale=0.25, user-scalable=yes");

Looks quite simple, but you run into some problems with this approach.

  • Some mobile browsers (Opera on Android, Firefox on Android) do not update the actual viewport when the meta-tag gets changed after the page is loaded.
  • If you zoom, Safari on iOS ignores the new value for initial-scale and keeps the current zoom level. So if you switch back to the responsive version, it does not use the full width of the screen anymore. You have to reload the page, to display it correclty. This of course diminishes the advantage of changing the meta-Tag on the client-side.
  • Implementation with Ruby on Rails

    Now if we’ll look at a server-side implmentation for an opt-out possibility with Rails:

    • You need a responsive_controller.rb
      class ResponsiveController < ApplicationController  
        def optOut
          cookies[:responsive] = { :value => "no", :expires => 30.days.from_now }
        def optIn
    • Then add some browser detection (Source: StackOverflow)
      def mobile_device?
        if session[:mobile_param]
          session[:mobile_param] == "1"
          request.user_agent =~ /Mobile|webOS|Mini|Mobi/
    • Add some conditionals for the meta-tags in your application.html.slim (using SLIM here)
      - if cookies[:responsive] == "no"
        meta name="viewport" content="width=1024, initial-scale=0, maximum-scale=1.0, minimum-scale=0.25, user-scalable=yes"
      - else
        meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"

      Add a toggle button

        - if mobile_device?
            - if cookies[:responsive] == "no"
              a href="/responsive/optIn" mobile Version
            - else
              a href="/responsive/optOut" Full version
    • Do not forget to add the needed routes to your routes.rb
      match 'responsive/:action', :controller => :responsive

    Recommendation: If you need responsive opt-out, do it server-side.

    Again: We do not recommened offering an opt-out possiblity for a responsive design. But if you really need it, go for the server-side solution, because toggling the responsive behaviour often requires a reload anyway.

    If you really want to use Javascript, ReView.js solves some problems you will run into.