What I’ve learned

Intro

Having nearly completed this project, I’ve learned some rather hard lessons about web development in general, and “responsive” development in particular. Recently, I received a new Motorola G Pure cell phone. It’s official screen specs are 408px x 773px (W x H). So, as per my usual practice, I added the device to the list in Firefox responsive design mode, and tested every page. It all looked good. Then I uploaded everything to my main site, and checked it on the actual phone. This is when it all fell apart.

Viewports and Responsive design mode discrepancy with actual devices

Mind you, it wasn’t a total disaster. Indeed, most of it looked fine. But there’s one page where I need to dynamically align some elements, both vertically and horizontally. A little research on MDN, beginning with the “Viewport concepts” page, which briefly discusses various relevant DOM interface values such as window.innerWidth and Element.clientWidth, along with briefly touching on the fact of two different kinds of viewports: the Visual Viewport, and the Layout Viewport

For the sake of brevity, if it’s not already too late to achieve, suffice it to say that MDN had nothing that helped my cause. It did however thoughtfully include a link to a discussion of viewports on one of my longtime favorite resources: Quirksmode. Here, Peter-Paul Koch discusses in depth the problem with how viewports are implemented in both devices and browsers, and most importantly, the fact that both devices and browsers intentionally deliver inaccurate dimensions and resolutions to both the DOM and to CSS media queries, in the name of user security.

Now, don’t get me wrong here, I’m totally in favor of protecting user security. Indeed, when it comes to web security, nobody is more paranoid than I am. Unfortunately, this breaks all but the most basic, simplistic designs. Even using grid layout with relative units like fr, vw and vh, not to mention plain vanilla “%”, and for that matter min/max-content, doesn’t work quite the way it should.

Using multi-line mode in the Firefox dev tools console, I checked the computed heights of the grid rows on both the desktop responsive design mode and the phone (which I connected with USB debugging). The first row was identical, but the remaining two rows were off to the tune of 15.6 pixels.

User selected font sizes

Interestingly, in the course of writing this post, it dawned on me that the second grid row contains a date and timestamp widget using a relative font size, 1.2em to be specific, and I have the fonts on my phone scaled to “extra large”, which turns out to be 16.9px when the <body> font size is set to 13px – a 130% increase. Queue up Homer Simpson blurting out “ Doooooohhhhhh!!!

Accessibility

At this stage, naturally, I’m thinking “how can I force the phone to use my specified font size?” Well, with more scouring the web for a good answer, I came to the realization that I shouldn’t. To do so would render the site non-accessible. I then realized that the real problem was using em‘s and rem‘s as a size unit for non-text elements. The solution was to use viewport percentages, in the form of the vw (viewport width) and vh (viewport height) css units. As long as the design is oriented to scroll vertically, as any mobile first design should be, this works beautifully.

The device toolbar problem and the new dynamic viewport units

Just when I thought I had solved the remaining issues, I discovered one last remaining, daunting issue. Devices display toolbars independent of the browser window, and don’t bother figuring the heights into the viewport heights reported to the DOM and CSS media queries. Again scouring the web for a solution, I came across a few newly available viewport units. There are three of them: small, large and dynamic. They’re essentially the same as the existing viewport based units, but with an s, l or d prefix: svw, svh, lvw, lvh, dvw and dvh. A more detailed explanation can be found on MDN here . As an aside, technology is advancing so rapidly, it feels impossible to keep up with. Even as I write this I’m learning new things. Apparently, in 2023, an @container query was introduced into CSS. Similar to an @media query, but targeting the identified container element. More information can be found on MDN here and here .

If you’re still reading this, you might be wondering by now why I’m blathering ad infinitum, ad nauseam about this little adventure that left me pulling out what’s left of my hair. I’m posting this to share the wisdom that I acquired the hard way so you don’t have to. Enjoy.