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

25. Februar 2013 Roland Studer

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 }
          redirect_to(:back)
        end
      
        def optIn
          cookies.delete(:responsive)
          redirect_to(:back)
        end
      
      end
      
    • Then add some browser detection (Source: StackOverflow)
      def mobile_device?
        if session[:mobile_param]
          session[:mobile_param] == "1"
        else
          request.user_agent =~ /Mobile|webOS|Mini|Mobi/
        end
      end
      
    • 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?
          #toggle_responsive
            - 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.