How my new responsive design here works

June 25, 2014

Encouraged by the commentators (and their suggestions) on my earlier entry about responsive design here, I sat down and banged out some CSS and revised my markup. Since I went through a bunch of iterations (many of them not working) to get my current results, I want to write down everything before I forget how it all works and why I needed to do things the way I have.

Following Aristotle Pagaltzis's suggestion, the core styling is done with 'display: table...' settings on <div>s. The div tree looks like this (roughly):

<div class="wtblog">
   <div class="maintext">
      ... left column contents ...
   </div>
   <div class="sidebar">
      ... sidebar contents ...
   </div>
</div>

In the normal CSS rules, wtblog is set to display: table while the other two are set to display: table-cell with their widths set to 76% and 24% respectively. This creates an implicit table row and stacks them up side by side with most of the space given to the main content. The table-* display styles seem well supported on anything I really care about (IE 7 users are out of luck, though). This is basically exactly the structure I used to create via actual <table>, <tr>, and <td> elements. The initial rewrite to this form was pretty much easy and painless.

My first CSS attempt to transform this into a minimized version with the sidebar below the main content was too clever. In my media qualifier rules I reset each column to 'display: table-row' in order to get them to stack on top of each other, which worked but had the problem that display: table-row entities can't have borders and I wanted to set a top border on the sidebar. This caused me to go through several iterations of inventing extra <div>s so that I would have something to make into a display: table-cell <div> inside the table-row <div>.

After a while I came to my senses and realized the straightforward, obvious solution: plain 'display: block' <div>s already stack on top of each other. So now the minimized version resets all three <div>s to be 'display: block; width: auto;' (in addition to tinkering with margins, borders, and various other things). This just works.

I did go through some amount of pain finding a @media query that would work on the iPad Mini, not just in a desktop browser when it was narrowed. After some fiddling I made it work by checking against max-device-width as well as plain max-width (which is what the browsers are happy with). I also have a really iPad Mini specific rule to increase the font sizes some as well; I aimed for something that would make my content look much like the 'readability' view you can get in the iPad browser.

While I was fiddling around with my CSS I also set up a maximum width so that people with giant browsers on giant screens don't get text that sprawls all over the place. The maximum width is probably still too wide for good readability, but I don't know what the right maximum width is considered to be (casual web searches did not help answer this question).

Because I'm lazy and not crazy I specified almost all of my limits and sizes in ems so I didn't have to care about font sizes. In fact I think this works best; someone who has really increased their font size because they find it more readable doesn't magically want to read fewer words in a line than normal. Unfortunately not everything has sensible default font sizes, especially the iPad Mini.

(In writing this entry I've discovered that CSS has added all sorts of exciting new sizing units since I last looked at it quite a lot of years ago. Possibly I will use some of them in my CSS at some point, once I understand things like rem and vw better.)

The whole experience has been a lot less painful than I expected it to be. Dealing with the iPad Mini's peculiarities was annoying and involved a lot of experimentation with things that didn't work, but apart from that things went pretty smoothly. I ran into one CSS quirk but it's documented, more or less, and I think it existed even in the <table> version of my layout.

(The quirk is that almost all of the ways you might think of to move the first line of one table cell down relative to the first line of the other table cell don't work. They either don't do anything or they move both columns down at once. The solution is to explicitly set 'vertical-align: top;' in the table cell you want to offset; then things like padding will start working.)


Comments on this page:

By Alan at 2014-06-25 03:49:14:

I'm not getting any sidebar :(. 1366px laptop.

At least not until I zoom out, to an unreadable 20%.

When zoomed out, it doesn't look like the max-width is working either.

Firefox 30, Fedora 20. NoScript blocks all your scripts. (Not that that sounds very different to what your environment is).

By cks at 2014-06-25 08:15:50:

You may need to force-refresh to get your browser to pick up the new CSS file. If that doesn't work, I don't know what's going on; in basically the same environment everything works for me. If a force refresh doesn't fix it, what's your default font size set to?

(There isn't any JavaScript here, so NoScript isn't an issue.)

I bet I need to change the URL to the CSS to force browsers to refresh it any time soon. Changing things can be a pain.

By liam at unc edu at 2014-06-25 09:39:58:

iPhone 4, iOS 7.1.1

No sidebar, text is about 20 chars wider than the screen - so have to scroll to see the last few words on a line.

I quit Safari to force a reload.

Cheers, Liam

By cks at 2014-06-25 11:45:10:

I've done yet more tuneups that will hopefully make iPhones and other small devices happy about life, specifically adding this to the pages here:

<meta name="viewport" content="width=device-width">

This apparently tells device browsers to not simulate a bigger virtual browser display than they actually have. Hopefully it doesn't have other side effects.

By Alan at 2014-06-25 14:20:37:

Ok, it's fixed for me now! (No forced refresh on my end).

"width=device-width" should work as you expect. It's a simple & useful idea, widely used and supported.

There's one quirk, but I don't think you need to care. Layout changes can potentially confuse users. Apple recommend that apps preserve layout on rotation, so that's what they implemented. Other browsers omitted that detail.

I get white space on the sides where there didn’t used to be any, but that just seems to be the max-width. The sidebar used to be wider too, naturally, and this new narrower one feels more crowded, but that may just be force of habit.

Both of these are probably as intended, though. Modulo these it looks just as before for me.

It also seems to look as you intended on the iPad I have access to.

One wart is that with the sidebar dropping down in the mobile layout, it now separates the entry from the “Add comment” link (whereas the rest of the stuff in the page footer seems correctly placed below the sidebar). If it’s possible to integrate that link into the <div class="commenttools"> instead of showing it in the “Page tools” line, that would make sense. Or it might make sense to pull up all the page tools into a <div> below the comment tools. I have no idea whether any of that is doable, of course.

By cks at 2014-06-25 15:59:48:

If you're browsing with a browser area over (currently) 60 ems wide, there will now be white space on either side when there didn't used to be. This affects the sidebar too because what I'm limiting is the total size of the wtblog top level <div>. This is all 'as intended' although I don't know if this is a fully good idea or if 60em is the right size. And you're right in that maybe I could let the sidebar sprawl out some more rather than clamping it to (currently) 14.4 em.

(Possibly this means that I should actually be limiting not the wtblog <div> but the two sub-divs, each to some appropriate amount.)

The point about the 'Add Comment' link is a good one. I hadn't noticed that and I'm going to have to think about the best way to fix it.

By cks at 2014-06-25 17:44:16:

Since other people might as well share my CSS pain (or at least annoyance), I tried setting max-width on the maintext and sidebar <div>s instead of on the overall wtblog <div>. Of course CSS laughed at me and they did nothing. I suspect that maximum widths are ineffective on table cells because table cells are supposed to expand as wide as the table lets them.

(In theory I could read the CSS tables specification to find out for sure, but I don't care anywhere near that much about this right now.)

Tables dynamically auto-recalculate the dimensions of everything to fit the content, so they are hard to coerce to do specific things. You can set table-layout: fixed for more control – maybe too much of it, depending.

Apologies for leaving this comment here, in case there was a more fitting entry; it is the best I could find. I just wanted to point out that it would helpful to commenters on mobile devices to use type="url" for the URL field in the comment form.

By cks at 2015-03-19 13:04:22:

I've updated things here to use type="url" on the URL field as you suggest. Hopefully it won't break any pre HTML5 browsers (and I have the luxury of not caring too much about them if it does). Ah, HTML, so many things to try to keep up with on the modern web.

That is the coolest part of these new input types: browsers have always fallen back to type="text" when encountering a type they don’t understand. So this change is a no-op in browsers that don’t support it.

It’s neat.

Written on 25 June 2014.
« Python 3 has already succeeded in the long run
A retrospective on our Solaris ZFS-based NFS fileservers (part 1) »

Page tools: View Source, View Normal, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Wed Jun 25 01:09:16 2014
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.