
How to do responsive opt-out by setting the viewport with JavaScript or Ruby on Rails
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 content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport"></meta>
Now if we want the website to be displayed as if the device had a larger width, we just set the width
accordingly.
<meta content="width=1024, initial-scale=0, maximum-scale=1.0, minimum-scale=0.25, user-scalable=yes" name="viewport"></meta>
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 themeta
-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.