Grow your CSS skills. Land your dream job.

REMux: An Experimental Approach to Responsive Web Design

Published by Chris Coyier

The following is a guest post by Dirk Lüth. Dirk had an interesting take on responsive layout. It uses media query breakpoints to shuffle things around as we are used to, but the fluid column widths are set in rem units rather than percentages, and the font-size is adjusted dynamically with JavaScript based on the screen width. The result is a bit of a "zooming" effect, up or down, until the next media query hits. I'll let him tell you more about it.

Introduction

I'm sure we all agree that responsive web design has been one of the biggest subjects in the last few years and will continue with the growth of mobile. As a senior front and backend developer with a strong interest in research and development at my company, I am responsible to evaluate techniques like RWD. Whenever I received a link to a totally new CSS grid system, I became more and more skeptical. They did not feel "right" to me, but I wasn't sure why.

Then I happened to come across a great article by Ian Yates titled "Life Beyond 960px: Designing for Large Screens" which introduced me to the term "Screen Real Estate". Prior to that, I did some deeper research using rem units in CSS which was a fortunate coincidence. Suddenly I knew what felt wrong.

When talking about RWD we mostly talk about devices below the target width of our layouts. But what about larger screens? Most of you will agree that a non RWD website with a target width of 960px looks a bit odd or lost on such a screen. Things are becoming more obvious when we talk about people accessing our websites with a 60" TV. Sure, these TV sets will most likely still only have full HD resolution. But keep in mind that whoever sits in front of them is probably at least 4m/10f away from the screen.

Current Situation

Whether we do mobile, tablet or desktop first - most of us will end up having at least 3 media query breakpoints with different layouts. Or we will use a grid system which will automagically change the composition of our sites' content elements. Or a combination of both. Both approaches have their drawbacks if we are to support more and more different resolutions and different viewing situations:

  • More breakpoints = more layouts = more work
  • Hard to balance flexibility and proportions of elements
  • Jerky looking re-stacking of elements
  • Limited by the amount of content to fill the viewport
  • The art of the grid is more than some guides in Photoshop

And whatever way we choose to be most appropriate: the actual content (including every single element) will not scale proportionally.

Proof of Concept

What came to my mind was the idea of a solely rem-driven layout based on font-size. If this idea worked, I could easily scale all content by simply changing the font-size on the <html> element. This concept would solve the biggest challenge: layouts scale almost perfectly within their boundaries.

Keep in mind that rem is only supported in IE9+ and all other current browsers. For older browsers a px based fallback is possible. See the example mixins below.

I started to do some proof-of-concept work with my own site. The static version worked out really well after I had developed some LESS mixins that convert pixel units (taken directly from the layout) to rem units based on the 14px font-size I decided to use (see example).

LESS Mixins

There are two types of mixins here: one for single parameters properties (like font-size) and another one for properties with multiple parameters (like border). Both rely on two LESS variables that must be defined.

@remuxFontsize: 14px;  // base font size
@remuxFallback: false; // switch to include px fallback

.remux(font-size, @value) {
  @processingRem: ((round((@value / @fontsize-base) * 10000000)) / 10000000);

  .result(@value, @fallback) when (@fallback = true) {
    font-size: ~"@{value}px";
    font-size: ~"@{processingRem}rem";
  }
  .result(@value, @fallback) when (@fallback = false) {
    font-size: ~"@{processingRem}rem";
  }

  .result(@value, @remuxFallback);
}

.remux(border, @value) {
  @processingRem: ~`(function() { var base = parseFloat("@{remuxFontsize}"); return "@{value}".replace(/[\[\]]/g, '').replace(/([0-9]*[.]{0,1}[0-9]*px)/gi, function() { return ((Math.round((parseFloat(arguments[0]) / base) * 10000000)) / 10000000) + 'rem'; }); }())`;

  .result(true) {
    border: @value;
    border: @processingRem;
  }
  .result(false) {
    border: @processingRem;
  }

  .result(@remuxFallback);
}

Using the mixins is quite simple:

/* Instead of this... */
font-size: 16px;
/* You use this */
.remux(font-size, 16px);

/* Instead of this... */
border: 7px solid #000;
/* You use this */
.remux(border, ~"7px solid #000");

When I switched my site's CSS to use rem I was already able to change the font-size of the <html> element via the developer tools and see the site scale almost perfectly!

What I needed next was a solution to calculate this dynamically via JavaScript on "resize" and "orientationchange" events. The basic calculation is really simple:

;(function(window, document, undefined) {
  'use strict';
  
  var targetLayoutWidth = 980,
    baseFontsize      = 14,
    htmlElement       = document.getElementsByTagName('html')[0],
    documentElement   = document.documentElement;
  
  function updateFontsize() {
    var currentFontsize = baseFontsize * (documentElement.offsetWidth / targetLayoutWidth);
      
    htmlElement.style.fontSize = currentFontsize + 'px';
  }
    
  window.addEventListener('resize', updateFontsize, false);
  window.addEventListener('orientationchange', updateFontsize, false);
  
  updateFontsize();
}(window, document));

When setting the result font-size, I realized that floating point numbers cause problems when rounded by the browser (see example). So I ended up having to floor the font-size which eliminated any rounding glitches but made the scaling less "fluid". It still feels more than sufficient for me though (see example).

Next I did some extended testing on my iPad 2 with the HTML viewport set to "device-width". I admit having been a bit surprised when not only everything worked after the initial page load but also pinch-to-zoom and changes in device orientation behaved as desired.

Implementing Layouts

Now that I was able to infinitely scale my layout I started implementing breakpoints. Breakpoints will still be required because scaling the font-size down to zero or up to infinity does not really make sense (although technically possible).

I started planning the structure of my future layout object by determining what was required. That lead to the following JavaScript object structure:

var layouts = {
  'ID': {
    width:      980,            // designs target width
    base:       14,             // designs base font-size
    min:        10,             // minimum font-size
    max:        18,             // maximum font-size
    breakpoint: 980 * (10 / 14) // minimum breakpoint
  }
}

Now that layouts could be defined I had to add them to the update function which had some more impact than I had thought (see example):

;(function(window, document, undefined) {
  'use strict';

  var htmlElement     = document.getElementsByTagName('html')[0],
    documentElement = document.documentElement,
    layouts = {
      mobile: {
        width:      420,
        base:       14,
        min:        10,
        max:        23,
        breakpoint: 420 * (10 / 14)
      },
      desktop: {
        width:      980,
        base:       14,
        min:        10,
        max:        18,
        breakpoint: 980 * (10 / 14)
      }
    },
    state = {
      size:   null,
      layout: null
    };

  function updateFontsize() {
    var width, id, layout, current, size;
  
    width = documentElement.offsetWidth;
  
    for(id in layouts) {
      if(layouts[id].breakpoint && width >= layouts[id].breakpoint) {
        layout = id;
      }
    }
  
    if(layout !== state.layout) {
      state.layout = layout;
  
      htmlElement.setAttribute('data-layout', layout);
    }
  
    current = layouts[state.layout];
  
    size = Math.max(current.min, Math.min(current.max, Math.floor(current.base * (width / current.width))));
  
    if(size !== state.size) {
      state.size = size;
  
      htmlElement.style.fontSize = size + 'px';
    }
  }
  
  window.addEventListener('resize', updateFontsize, false);
  window.addEventListener('orientationchange', updateFontsize, false);
  
  updateFontsize();
}(window, document));

I tested this prototype on Chrome, Safari, FF17+ and IE9 (where REMux should work), and it does work.

See it in Action

already mentioned that REMux is heavily (ab)used on my own website. Beside that, there are some Pens up on CodePen which were linked throughout the article. In addition there is another Pen showing what I ended up with:


I hope to get some documentation ready soon - but the code is not that hard to read as it is.

What's Next?

REMux works so well that I decided to make it part of my growing JavaScript library which can be found on GitHub. Within the last couple of weeks I also added some more features that are missing in this basic article:

  • AMD compatible (require.js)
  • addLayout() method to add layouts without altering the script
  • Ratios for pixel density, zoom level detection, font-size, total and images
  • getState() method that will return all sizes and ratios
  • emits events ratiochange and layoutchange with the current state passed as argument
  • Flood protection mechanism for repeated input events for better performance
  • Extendable by an object extension mechanism

The standalone version of REMux can be found in the "packages" folder of my GitHub repository and weighs about 4kb minified and gzipped. It does not depend on jQuery or any other bigger library. Its dependencies to other components of my library are all included in the package. All components of my JavaScript library are dual licensed under the MIT and GPL license.

Feel free to download and use it in your projects but remember to give feedback and report bugs so I can make it even better!

Comments

  1. Even if I am not a big fan of using JavaScript for layout concerns, I have to say your approach is pretty impressive.

    It seems not only to work like a charm but also to give solutions to complex issues.

    Very well done Dirk. Awesome job.

  2. Permalink to comment#

    Me neither Hugo, but as an experiment it just worked out so exceptionally well that I could not resist temptation :)

    In fact, I am not exactly sure if I should show it to our art department – most certainly they would argue that our usual moaning as developers is always totally exaggerated…. And in the end REMux more or less solves more of their problems than ours as developers.

    Dirk

    • Juanjo
      Permalink to comment#

      Hi Dirk,

      They’ve probably told you already, but your site is a bit broken on Firefox for Mac on retina devices (don’t know about other configurations, but in that one it certainly doesn’t work)

      Here’s a screenshot I took from the link you posted.

      Nice article, by the way!

    • suprsidr
      Permalink to comment#

      I actually get a similar result to Juanjo on my netbook 1024×768 win7 FF 18

    • @Juanjo

      I now also have a 15″ Retina MBP and tested the new version, REMux 2.0, on it. It should look OK but zooming in will still cause troubles because of the totally bizarre implementation of zoom in Firefox.

      Up to now I only knew that Unlike every other browser FF 18+ includes the current zoom-level into window.devicePixelRatio which is accessible via JS. Now I learnt, in addition, that that browser zoom-level is also reflected in “min-resolution” within media-queries. So where you would expect a media-query for a retina device like @media (min-resolution: 192dpi) {} to always match on FF 18 it will not if the browser is zoomed in (but will than match something above 210dpi).

      Beside that I learnt that with FF 18.1 devicePixelRatio will always be 1 by default on retina Macs if there is a second monitor connected.

      Overall I gain the impression that the implementation of Firefox makes it absolutely unusable in its current state. The team is well aware of the issues but seems to be unwilling to change the current (absolutely buggy) behaviour :(

  3. Permalink to comment#

    As a person that worries about mobile/responsive design as part of my daily job, I’m definitely interested in learning more about this.

  4. This is the nice approach. Java script play important role.

  5. Permalink to comment#

    Nice solution :)

    I did a proto site layout for a client a while ago with a similar idea to this, but kept it simple without the JS.

    Reset html font-size to 10px in you style sheet, and then you can use rems for any dimensions you want to scale with the display. Then set media break points to reset the base font-size.

    The good thing about this is that it keeps the layout code in css, and is nice and easy to maintain/adjust/customise sizes for different breakpoints (or responsively restructure). Certain elements (usually js components) may need a little tweaking with JS, but for the most part, it worked nicely cross-browser.

    • Permalink to comment#

      Can you post an article on this?
      Thank you

    • Nathan
      Permalink to comment#

      Would love to! But a little stuck on time right now.

      Dirk did most of the things I did, but I think my approach differed because:

      To keep things easy (e.g. use it to keep aspect ratios on scaling, ) I set the base font size to 10px. This makes settings all widths and heights easy to calculate, and then things will scale proportionally (ish!) – but maybe not the best approach for scaling webfonts (some fonts get messy at some sizes)

      I stuck to media queries (which Dirk does optionally in v2 of remux) and used far fewer than he does in v2. To smooth out the ‘jumping’ I used transitions (transition: 0.5s all;) to animate the changes in size. WARNING – I don’t recommend this for all solutions, complex pages could get clunky.

      There were some JS driven features which had real problems with scaling – the sliding carousel that I used was a nightmare cross browser, and I only ‘just’ got it working in the major latest browsers.

      I think that this is a useful technique, but used in the right situations. A blanket scaling approach (drop in the code and forget about it) is a bad idea especially for small devices.

      Where this technique really shines is when the display gets bigger than your ‘standard’ screen size. Bellow this size use standard responsive design, above it use the font scaling technique.

      Websites can look GREAT on big screens if scaled up, but careful of pixelation – similar as when supporting retina displays. Maybe if you go past the standard threshold, you could load in (using JS) higher res images…?

  6. Permalink to comment#

    @Juanjo and @suprsidr

    Would you mind opening the following link with your debug console opened in FF18 and send me the console logs you should see?

    http://www.qoopido.com/404/

    Sadly I do not have access to a retina Mac, but I have an idea what might be the cause…

    Thanks in advance!

    Dirk

  7. Chris Bowes
    Permalink to comment#

    I’ve experimented with similar techniques and use REM as a matter of course for dimensions and font-sizes as it cuts down the amount of CSS required when writing media queries. One thing stands out though, the consensus of this post seems to be around scaling layouts down proportionally. My own experiments with this have been all about scaling font sizes up on smaller devices, so the scaling works inversely. Or scaling font-sizes up for mobile devices with a large CSS pixel size (but not so large physical size – e.g. Galaxy s3 or HTC 1x) and then scaling the font sizes back down again for 320px devices like iphones. The result is somethign that looks crazy when resized on a desktop but gives the best possible optimisation of layout on various devices. I can’t see why there is an argument for scaling font sizes down on mobiles

  8. Permalink to comment#

    @Chris Bowes

    It scales in both directions. You just define a layout based on px measurements converted to REMs and define font min/max limitations within which the layout will be scaled larger or smaller. Your base font-size will most likely be somewhere in the middle between min and max limitations for a certain layout.

    • Chris Bowes
      Permalink to comment#

      Thanks Dirk, I understand it can scale both ways. I guess I’m just wondering what the general consensus is on whether fonts should scale up or down for mobile devices. Scaling font sizes up on smaller screens can make them more readable – links easier to click etc (especially on 720px wide mobile handsets) – But this then feels obtuse on a desktop site, where you expect the design to scale down when you adjust the screen size. I haven’t had time to properly play with your scripts yet (will look forward to it later) but am thinking I will probably try and use it in conjunction with checking device pixel density to determine whether the device is desktop or mobile and then switch the way the font scales for each. Hope that makes sense, and if I have failed to completely understand REMux forgive me, I am in Monday morning ‘quick scan’ mode

  9. Permalink to comment#

    No offense taken @Chris Bowes – I know very well what you mean by “Monday morning quick scan mode” :)

    If you ask me I would say that, in general, mobile devices do their very best to give the best results possible.

    If you plan on further investigating devicePixelRatio keep in mind that e.g. an iPhone 4s with retina display still gives you 320px when the viewport is set to device-width. The phone itself scales the site to fit its physical resolution of 640px afterwards. So text that has 10px as font-size will effectively have 20px than.

    There are some great sources of information regarding how viewing distance, physical size of a screen and font-sizes correlate – If you are interested I could look those links up…

    • Chris Bowes
      Permalink to comment#

      Hey Dirk. All good, I’m pretty well versed in understanding the differences between retina screens and pixel densities, the point about using pixel densities in CSS media queries is that desktop devices do not return a CSS pixel density, thereby making it a pretty easy way to distinguish between desktop and mobile devices without resorting to UA sniffing.

      My concern is more about giving users of large handheld devices a comparable UX to people using Iphones . I see a lot of responsive designs that work great on iphones (retina or otherwise) but on 720px wide android devices, the copy text is too small and often they pick up larger two column layouts intended for tablets etc. The css pixel size of these devices is more than twice that of the iphone CSS width (320px as you stated) but the physical size in your hand, is barely half an inch bigger and so text and layouts appear a lot smaller and links become much harder to hit. These are the devices I’m referring to when talking about using larger font sizes than the desktop versions and this is where using REM techniques for scaling really come into their own.

      Still every day brings a fresh challenge and that’s why we’re all here. :) Looking forward to trying out REMux later.

  10. Permalink to comment#

    @Chris Bowes

    All good, I’m pretty well versed in understanding the differences between retina screens and pixel densities, the point about using pixel densities in CSS media queries is that desktop devices do not return a CSS pixel density, thereby making it a pretty easy way to distinguish between desktop and mobile devices without resorting to UA sniffing.

    Be careful about that one though:

    Retina Macbooks have a devicePixelRatio > 1
    Mozilla decided with FF18 (for some obscure reason) to include browser zoom level into devicePixelRatio meaning you can have quite a big number there

    I suspect the second point to be the reason for the bug that Juanjo reported above.

    • Chris Bowes
      Permalink to comment#

      Good point. Thanks for the heads-up. I certainly wasn’t aware of the FF18 issue..Ouch.

  11. Do we need JS for this? If you’ve used relative units (ems, rems, whatever) for everything, then can’with each say 10% increase in viewport size could we not bump the font-size 10% (up/down to some sensible minimum/maximum). Personally I start mobile-first, and scale up from there:

    body {
        font-size: 16px;
    }
    
    @media screen and (min-width: 30em) {
        body {
            font-size: 110%;
        }
    }
    
    @media screen and (min-width: 33em) {
        body {
            font-size: 120%;
        }
    }
    
    @media screen and (min-width: 36.3em) {
        body {
            font-size: 130%;
        }
    }
    @media screen and (min-width: 39.93em) {
        body {
            font-size: 140%;
        }
    }
    

    Everything would then scale as expected in relation to the width of the viewport. This should even preserve where text wraps multiple lines etc! I got this tip this BBC presentation on responsive design

    • Second sentence failure! It should read:

      then with each say 10% increase in viewport size could we not bump the font-size 10%

    • Permalink to comment#

      @Nick Williams

      Careful, REM is not a relative unit, but absolute and it always relates to the font-size of the HTML element itself, not body.

      If you solely use EMs what you propose will work. But EMs make things really complicated because of the necessary parent/child calculations. So if you have to change any font-sizes things will start to get really complicated.

      So, for myself I decided to prefer the least amount of mediaqueries possible :)

    • I don’t think that’s quite correct. A value is relative because it’s value is defined in terms of something else. And rem is indeed defined in relation to another value, in this case the root font-size. You even said it yourself “it always relates to the font-size of the HTML element” ;-) Providing you defined everything in rems then the technique above would work perfectly well, just bump the font-size on html, instead of body and use rems in the queries instead of ems.

      As for em’s, how often do you wholesale bump the font-size on a container element? I’ve never needed to say something like .sidebar { font-size: 2em;} (where .sidebar is a <div> or <aside> or something), instead you’d just resize font on the text nodes themselves (<h1>, <p> etc). At least this is how I’ve come to work after much thought and refinement.

      Don’t worry about multiple media queries either, I try to make each one very granular and have a specific purpose rather than a small handful of queries that deal with everything. It’s one of those things that feels wrong, but there is no problem – performance or otherwise – with it. I liken it to switching to using very granular, single purpose/responsibility classes, meaning you apply multiple classes to each tag. It feels wrong but there’s no problem with it.

      Great article which gave me lots of think about: http://trentwalton.com/2013/01/07/flexible-foundations/

    • Permalink to comment#

      Sorry for having sound a bit harsh eventually, did not mean to do so :) As long as anybody can gain something from it I am totally satisfied! It is, as I already stated in the article, a two-sided story. One is about using REM solely for CSS and the other is having some JS fun with it…

      I will put your link in my pocket reading list, promised!

    • Don’t apologise, you didn’t sound harsh at all, only courteous and polite :) I’m just enjoying an interesting discussion.

      Really don’t hold back on Trent’s article, it’s pretty short (5 minutes to read through) but massively insightful! For me it was one of those epiphany moments that strikes you like a bolt of lightning

    • Permalink to comment#

      Just gave it a read and totally agree and – funny enough – exactly what I had in mind, even though not having read this article before. I really had problems summing up what is so “different” about the REMux approach, but the article really describes it very very well!

      The essence is the same: Why make parts of a website responsive in numerous ways when there already is a solution that perfectly covers all your needs?

      I might very well give a pure CSS version a try in the near future!

    • Haha, believe me, there’s barely a day gone by since the article was published that I’ve not forwarded to someone as a point of interest! The article enlightened me, like an angel had whispered the meaning of life into my ear! Ok maybe not that much, but it completely changed my thinking and pulled together some nebulous ideas I had floating around my brain.

      I’m (slowly) building my personal site on this principle and it’s great to see everything scale proportionally (margins, widths, font-sizes etc) with a simple bump of the body’s font-size!

    • Ryan Wheale
      Permalink to comment#

      I’d like to chime in on this one, as I completely agree with Nick. You have a 4Kb javascript file which essentially does what Nick suggests (except the font-size should be applied the the HTML element as you have already pointed out). This technique works beautifully using pure CSS. And I see no problem having a block of media queries to achieve this… especially if it means I don’t have to use javascript for layout.

      html { font-size: 100%; }
      
      @media screen and (min-width: 72em) {
          html { font-size: 110%; }
      }
      @media screen and (min-width: 80em) {
          html { font-size: 120%; }
      }
      @media screen and (min-width: 85.375em) {
          html { font-size: 130%; }
      }
      @media screen and (min-width: 100em) {
          html { font-size: 140%; }
      }
      @media screen and (min-width: 120em) {
          html { font-size: 150%; }
      }
      

      And then my layout styles:

      @media screen and (min-width: 30em) {
          .container { .width(480); }
      }
      @media screen and (min-width: 48em) {
          .container { .width(768); }
      }
      @media screen and (min-width: 60em) {
          .container { .width(960); }
      }
      

      And some LESS:

      .width (@val) {
          @remval: (@val / 16);
          width : @val * 1px;
          width : ~"@{remval}rem";
      }
      

      Note: the 16 can be replaced with a @variable, however I make the assumption that most users have not mucked with the browser’s default font size – which is almost always 16px. I apply aesthetic font sizes to the body tag and leave the root in tact so that I can always rely on REM calculations from a base of 16.

    • Permalink to comment#

      Had some sparetime today and so started experimenting:

      The static part was easy:

      Just calculated all the breakpoints for a switch in fontsize and implemented them as media queries. I already had breakpoints for the layout switches as media queries before – so no change there.

      Pixelated headphone on homepage:

      It is just scaling with the fontsize which was coupled to the JS part of REMux – decoupling was easy…

      Responsive images in slideshow and single images:

      This one is giving me a hard time because these are not only related to devicePixelRatio but also on the fontsize factor and (which is the most problematic part) also the current layout. For having lost the layout class on the html element I left it out for the moment. So now images in the former “mobile” layout are loaded with a much higher fontsize factor without considering the size factor caused by the narrower layout. Not sure how to solve this – but will keep thinking about it…

      Modal overlay for contact form

      Needed a switch in positioning between mobile/desktop layout which is now done when the overlay is opened. Still have to implement a check for this on “resize” and “orientationchange” events but than it will be fine.

      I will most likely overhaul REMux to reflect the reduced requirements (will only deliver some common ratios afterwards) which will make it much lighter – and it will not be required to have a purely static site become responsive.

      Dirk

    • Thanks for feeding back Dirk, interesting to see how you got on with that approach.

      I suspect that stuff like slideshows will always be very implementation specific because there are too many variables.

      As for the modal, unless I’m misunderstanding what you mean, do you still need JS? For mobile could you not just set it to full-screen (or almost full-screen, with some margin around the edge), which would allow it to adapt to all screen sizes. Then for larger screens a media query to make it smaller (in relation to screen size)?

      P.S. If you’d like to discuss further should the comments be closed, hit me up on twitter @WickyNilliams

    • Derryl
      Permalink to comment#

      This idea has been discussed before, and I’ve used it in a couple of my projects.

      Trent Walton wrote about so-called “flexible foundations” about a month ago, and I’m sure he’s not the first to discover it.

      The basic idea is what Nick Williams just mentioned. That you use @media queries to change the font-size at certain breakpoints (several of them, if you like). No JavaScript required.

  12. Henrik Hjerppe
    Permalink to comment#

    Interesting bug on win phone 7.x/IE9: the website scale is HUGE. When i zoom out as far as it goes, i can barely fit the letter ‘Q’ from your logo on the screen. When scaling in, i can easily fill the screen white with just the dot on the ‘i’. Well, all the cool stuff always breaks in this browser anyway, and WP8 brandishes IE10. Wish they would update to IE10 on WP7…

    • Permalink to comment#

      I admit that I did not test it on Windows Phone 7 with IE9, there could be numerous causes that might or might not be related to REMux itself but could also be related to the site itself :(

  13. Permalink to comment#

    Hat’s off to you Dirk, the idea of a rem-driven layout just based on font-size would never have crossed my tiny mind :)

  14. Interesting idea, however, unless I’m missing something this presents some big accessibility issues – essentially you are preventing the user from zooming your site.

    I tried zooming and it resets itself back to the default size – which is the intended functionality of your script – zoom again – it shrinks again. Couple more ctrl+ and it suddenly goes enormous (but has no horizontal scroll bar so I can’t move it around to see all the content).

    Which makes me think it is best to let the user decide how they want to view your site and let go of the idea we can every control the view-port.

    It’s a shame because there are so many plusses to this approach, and I imagine it would work fantastically well on a huge device – i.e. TV.

    • Permalink to comment#

      I tried zooming and it resets itself back to the default size – which is the intended functionality of your script – zoom again – it shrinks again. Couple more ctrl+ and it suddenly goes enormous (but has no horizontal scroll bar so I can’t move it around to see all the content).

      Did you try to zoom in/out on any of the demos or my site directly and on which browser/OS? I implemented zoom-detection into the final JS used on my site but it might be buggy because the detection is totally different or even impossible for every single browser.

    • It was on your actual website.

      Win XP / Chrome.

    • Permalink to comment#

      You are right, could reproduce it and already found the bug. I will have to think about how to best implement the fix but it will be only a minor change. Hope to have some time this evening…

      Anyway, many thanks for reporting it!

    • Great – if the zooming isuue is reliably fixed across browsers / OS / Devices I can see this being a very useful script for some designs.

    • Permalink to comment#

      Should be fixed – but keep in mind that zoom detection will always be a bit “hacky” :(

  15. Merne
    Permalink to comment#

    I’m not impressed with the performance of the site. Granted, people don’t usually resize once the site is loaded, but very buggy.

    • Permalink to comment#

      Did you read that it states “experimental” in the title? Did you even bother to have a detailed look at it? Did anybody say it was the holy, unfailable grail? Did you even bother to give any constructive feedback beside saying “very buggy” and leaving out what exactly does not work and on which OS/browser?

      Simple answer: No, you did not…

      …at least not as far as I can judge from your comment.

      Sorry for being a bit harsh, but this kind of comment is annoying – which most people here will most likely agree.

    • Merne
      Permalink to comment#

      @Dirk For something so experimental you seem awfully upset at my comment. “Jerky looking re-stacking of elements” was a reason you traveled down this path. This is why I made the comment that its buggy. Resize and watch in any (supported) browser [I am on Mac OS 10.8.2]. I don’t see how this is better, other than to be lazy and let a javascript library do your work for you.

      I understand that this is caused by having to floor the font-sizes. I still am not impressed by the performance. In all modern browsers. That’s my opinion. You don’t have to pay attention to it.

      Is this study interesting? Definitely. Does it make a developer’s job easier? Probably in very specific circumstances, and probably more and more into the future.

      I wouldn’t use it today (yes I read that its “experimental”, but it still must be functionally relevant to today), because someone just might be resizing the browser window on the fly, and I don’t want them to see that. Additionally if for whatever reason someone did not have javascript enabled, I would still have to create the media queries with font-size changes for them (as well as any legacy IE browser). Why do it both ways?

    • Permalink to comment#

      Hi Merne :) I was not really upset but simply missed any kind of details on the problems you mentioned. That lead me to the (apparently wrong) conclusion that you did not even take a more detailed look.

      If you would have written what you did with your answer now it would have been perfectly fine. Constructive criticism is always a good thing and I also know that this solution, although working out quite well for me is not perfect at all.

      But my main aim is to make it better and usable so that eventually it is suited for a productive application one day or the other!

  16. This will make life easier when preparing responsive design to cater mobile and tablets

  17. ChuckBerry
    Permalink to comment#

    Great aricle Dirk, it will be fun to experiment with this.

    I have messed around with a method similar to that which Nick Williams describes where I just set the font size on the html element and scale it at various breakpoints. The way the proportions of stuff like paddings, margins and borders scale is truly a beautiful thing to behold. I’ve traditionally used percentage measures for my containers, ems for paddings, borders and margins and rems for font-sizes.

    As an experiment I’m going to look at using percentages for containers and rems for mostly everything else. I still feel a bit uneasy with the javascript usage though.

    Bravo!

  18. Here are the console reports using FF20.0a2 on a Retina Macbook

    [01:06:46.391] Layout: desktop

    [01:06:46.392] Width: 2470

    [01:06:46.392] Ratio – device: 1

    [01:06:46.392] Ratio – image: 1.5

    [01:06:46.392] Ratio – size: 1.2857142857142858

    [01:06:46.392] Ratio – total: 1.2857142857142858

    [01:06:46.392] Ratio – zoom: 2

    [01:06:46.392] Many thanks for your help!

    • Permalink to comment#

      Thanks for the report, that helped a lot. Problem is, as expected, that FF18+ window.devicePixelRatio unlike any other browser includes browser zoom level and the temporary “fix” for this behaviour causes a problem when devicePixelRatio is > 1 by default.

      Would you mind opening http://www.qoopido.com/404/ again with an open firebug console and post the results? I changed some debug output to check if there is any possibility to bypass window.devicePixelRatio…

      Regards
      Dirk

  19. The good thing about this is that it keeps the layout code in css, and is nice and easy to maintain or adjust or customise sizes for different breakpoints.

  20. Permalink to comment#

    Impressive! I can totally say that mobile graphics are developing greatly to its best. I can also tell that JaveScript has a very significant role on this process. Thank you for this post! I absolutely want to learn more about responsive web design.

  21. The web design process isn’t that difficult with the right understanding of concepts and procedures. Especially when it comes to responsive design (and in the future, context design).

    It’s why the industry continues to hum along. New concepts, ideas and processes like this make it fun to work every day.

  22. Permalink to comment#

    Thanks for all the great comments and feedback to all of you! As mentioned in one of the comments above I already started to revamp REMux to be more versatile in general and to make the JS part optional (so you can still use it for e.g. responsive images if you need to).

    My current plan is to move REMux to its own GitHub repo and publish my LESS mixin-library completely as well as the new JS part (which will most likely only be half the size of the current version at max).

    Stay tuned and keep commenting here or contact me directly if you like!

  23. Permalink to comment#

    This is a very interesting technique. I think working in this way might greatly the workflow of people that do not design in the browser since the site just zooms for most resolutions.

    I think I’ll experiment with something like this (probably in a css only solution) in a future project.

  24. Martynas
    Permalink to comment#

    This is great! Though trying to make it work without LESS and using ems instead of rems would be really frusrating. I will have to try out LESS, thanks for the “kick” and the article :)

  25. I think all this will be possible one day using “CSS device adapt” and the new @viewport rule (assuming Desktop browsers will implement viewport support one day). You could do something like this:

     @media (min-device-width: 980px) {
        @viewport {
            width: 980px;
        }
     }
    

    The ideia is to fixate the viewport in 980px for big screens. This should scale everything automatically. And, of course, you could do something similar for other breakpoints too.

  26. I should leave a note here that vw/vh units in CSS are very related to these ideas and would be yet another non-JS way to handle it in the future: http://css-tricks.com/viewport-sized-typography/

  27. Permalink to comment#

    I had a similar approach in implementing this landing page: http://educa.tive.pro it plays mostly with images and divs but I also experimented the concept font-size (see the “soon available…” div, anyway font size can’t scale really proportionally because it’s only height)

    my concept tries to keep the golden ratio divs when you resize the viewport.

    @Chris Yes i think CSS absolutley needs viewport related units, thank you chris I was waiting this! So we can write a javascript polyfilll now!! Awesome!

  28. Permalink to comment#

    This is great! I am also trying to do same.

  29. Daniel
    Permalink to comment#

    Hm Funny. Start a project in January with nearly the same approach Nick starts. But I ve got influenced by the wordpress twentytwelfe wordpress theme. I use rem something like:
    default font size 16px;

    .class {

    width: 10px;
    width: .625rem;

    }

    Width px as fallback and adjusting the media queries via html > font-size.
    Cheers.

  30. Permalink to comment#

    Just to let you all know:

    The new version of REMux I have been working on is now online on my site

    http://www.qoopido.com

    I will adapt the article about REMux there to reflect the changes as soon as possible!

  31. Tom
    Permalink to comment#

    We can just “drop this in” and it will “just work” for most use cases as opposed to the specific issues people found??

    Thank you, Tom

    • Permalink to comment#

      The new version which is already in use on my personal site should be as much of a drop-in as is possible. And it does not have the specific issues the one from this article still had…

      I will publish the new version in its own GitHub repo within the next couple of days including the unminified sources (of course) and the mixin file I use…

  32. This is an impressive solution! For those interested in a tool without any coding, would be great to hear your opinion on Froont, a responsive design tool we are developing! We are launching a private beta to signed up users and you can sign up at http://www.froont.com, or ask me for an invite directly.

  33. Permalink to comment#

    Thank you so much for great article. This article opened my mind for the possibilities.The concept of a responsive design really got me, I had to play around with it on my recent work.I think Responsive website design might turn out as a great way to progressively enhance even small budget projects for mobile devices.

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".