Responsiveish Web Design - hacking viewports for Responsive/Fixed width hybrid designs

We all love Responsive Web Design. As I have argued before #RWD is the logical extension of progressive enhancement – it is a great way of building an inclusive web for all, designing around content and breaking out of a device-centric approach to web design.

It is not a panacea and it is not going to be suitable for everyone, especially rich media sites, data-heavy sites and complex web applications. However it can be a very compelling and cost-effective way of reaching a range of users on a range of devices.

But #RWD is more than just a technique – it is a design methodology that requires a dramatic rethink of the way we design for the web. It is a bottom up approach which makes it extremely hard to apply to existing, desktop-based designs. However it is not impossible.

I was recently charged with retro-fitting responsiveness to a desktop-based, fixed width design. The design was 960px wide and the client wanted the full width site design to be available at 768px – the portrait width of the iPad and other tablet based devices – but a responsive layout at lower viewports.

The issue we had was defining how the design should behave based on the meta viewport element – at 768 pixels and above we wanted the full page design to kick in (filling the viewport) whilst at lower resolutions we wanted the width=device-width to kick in with a responsive layout.

Loading the meta viewport at all resolutions was causing the desktop design to be truncated at smaller resolutions whilst removing it altogether caused issues with the ‘mobile’ design kicking in.

The solution? A small javascript hack. We detect the device width on page load and insert the meta viewport element if this is lower than 768 pixels. Yes, I know this isn’t responsive web design but for those in a similar situation this may provide a way to help pave the way for a better ‘mobile’ experience at smaller viewports without having to squeeze your desktop designs into considerably smaller viewports:

if(window.outerWidth < 768) {
	var ele = document.createElement("meta");
	ele.name = "viewport";
	ele.content = "width=device-width, initial-scale=1.0";
	document.head.appendChild(ele);
}

Responsive it ain’t but hopefully a good compromise if you are stuck with a fixed width design but need/want to introduce responsiveness for smaller devices. Your thoughts and suggestions much appreciated.

Comments

Please add your thoughts …

You can use Textile

Had to do this for a client the other day – they wanted native-scaling on tablet and responsive on mobile.

My solution was slightly less elegant but same principal.

I first set up the meta-viewport to the website’s fixed width:

<meta name=“viewport” content=“width=980” />

Then some JS sprinklings:

if (screen.width <= 640) {
viewport = document.querySelector(“meta[name=viewport]”);
viewport.setAttribute(‘content’, ‘width=device-width’);
}

There is a slight page reflow delay but does the trick. I like your code better though :)

Just had a the reverse need for a work project…worked like a charm!

We made a responsive site that has one breakpoint for narrow desktops or iPad, but we don’t have the time/budget set aside for fully styled, smaller mobile breakpoints.

So at 760px, I used your snippet to set the viewport width to 800px (vs “device-width”) and removed the initial scale in order to flow in a “minified” version of our 760px grid layout, instead of continuing to stack content, etc. which was leading to a broken display. Kind of an odd problem, but hopefully a one-off.

Yay, thanks so much!

I also do this whenever a client wants a responsive mobile version but to leave default scaling in place on anything bigger – there’s really not much on the web re: setting the viewport tag differently for varying screen sizes, so using JS still seems to be the best option. I run this code in the <head> as soon as possible (i.e. not wrapped by jQuery’s .ready() function or anything equivalent):

if (screen.width < 601) {
$(‘meta[name=viewport]’).attr(‘content’,‘width=device-width, initial-scale=1’);
}