While updating my website build process over the past week (part 1, part 2), I decided I should also revisit my page layouts. Last year, I started learning about responsive design, studied the theory, and implemented it on my site. I converted 514 out of around 600 pages, and said “The rest are either unimportant or impractical to convert.” Of the ones I didn't convert, some were in a 450px width and most in a 600px width. I wanted to see if I could convert the 450px pages to 600px at least.

Although I had abandoned Python lxml for building my website, it turned out to be useful for analyzing my website. I had 12 pages using width=450, 80 pages with width=600, and 183 pages with width=flex. (This is not counting 439 blog posts that use width=flex but in a "compatibility" mode.) I went through the 450px pages, intending to convert them to 600px if reasonable, and … it turned out all of them could be converted to a responsive layout relatively easily. Hooray! That means I no longer need to support the 450px layout. I removed it from my CSS and XHTML build script.

I was feeling optimistic, so I decided to visit some of those 600px pages to see if I could convert them. One after another, I was able to convert them without too much effort. I was feeling pretty good! There were some pages that had complex layouts that I wasn't able to convert easily, so I left them in 600px format.

The next step was a little more tricky. I wanted to unify two of my CSS styles. Let me explain visually. For the first 23 years of my web site, I used a container with a fixed width (450px or 600px) to enclose the content (paragraphs, diagrams, etc.):

section { width: 600px; }

For the flexible layout I designed last year, in large part because of articles on distill.pub, I changed to a system where the container would be full width, and each individual paragraph/diagram/etc. would have a width:

section > * { width: 600px; }

This allows me to make some diagrams wider:

I wanted to convert all of my pages to have this flexibility. I was feeling overly confident and optimistic so I decided to just do it. It turns out this broke a lot of my pages. The reason? The CSS rule

section { width: 600px; }

only applies to block elements. Over the years, I had been careless, putting inline elements on the page without putting them inside a block. The main offenders: img, canvas, svg, but I also had places where I had text without a container.

This is where Python's lxml came in handy. I read every page in, parsed it, and found all children of the container. Then I printed out all the places where I had inline elements:

children = bxml.xpath('//section/*')
for child in children:
    if child.tag not in ('figure', 'p', 'div', 'ul', 'ol', 'dl', 'pre',
                         'blockquote', 'address', 'hr', 'h2', 'h3', 'h4',
                         'table', 'style', 'script', 'noscript', 'footer'):
        print(bxml_filename, '   ', str(child)[:40])

Very handy! Once I had the list, I was able to go through each of these pages and fix the layout on each of the 80 pages. That took a while but it simplified the CSS I have to support going forwards, and it also gives me more flexibility in the layout.

Since I was going through all these pages anyway, I looked to see how much work they would be to convert to the responsive layout. Surprisingly, a lot of them were easy to convert! So I converted 73 of the 80 pages.

Now I had only 7 pages left that were using the fixed width layout. And I was feeling optimistic and productive. So I decided to try converting them.

The last few pages took a lot longer. They had tricky layouts, often involving overlapping elements, absolute positioning, iframes, etc. But I felt like I was so close to being able to drop the legacy layout that I spent the time to convert these pages. So I did!

I've converted the entire site to be responsive. Hooray!

Now I can remove all the old CSS rules, and only have a single set of CSS rules for all the pages.

Well, kind of. Some of my templates still insert an extra <div> under <section> as a "compatibility mode". These pages work with the new CSS, and have variable width, but they don't allow for the flexible layouts. That's ok. There's always more to do! I'm happy with how much I got done this week.

Update [2019-03-08] I had nearly 500 pages using the "compatibility mode", mostly blog posts, but also output from emacs org mode. Over the past week I went through them and converted them to not require it. I think I am finished with this major update!

Labels: ,