CSS, <pre>, and trailing whitespace lead to browser layout weirdness
Today someone left a comment on this entry of mine about Python which consisted of a block of code.
The comment looked normal in my feed reader, but when I looked at
it in my browser (for neurotic reasons)
I got a surprise; the new comment was forcing my Firefox to display
the page really widely, with even regular text out of my viewport.
This was very surprising because I theoretically made that
impossible years ago, by forcing all <pre>
blocks in comments to have a CSS
white-space: pre-wrap setting.
At first I thought that my CSS had broken at some point, but with
Firefox's style debugging tools I could see the actual CSS being
applied and it had the proper
More experimentation showed that things were even weirder than it had initially looked. First, the behavior depended on how wide my Firefox window was; if it dropped below the critical width for my responsive design here to show the sidebar as a sidebar, the problem went away. Second, the exact behavior depended on the browser; in Chrome, the overall page gained a horizontal scrollbar but no actual content extended out the right side of the browser's viewport (ie, its visible window area).
(I've fixed how the live version of the page renders, but you can see the original version preserved here. Feel free to play around with your browser's tools to see if you can work out why this is happening, and I'd love to know what other browsers beyond Firefox and Chrome do with it.)
Eventually (and more or less by luck), I stumbled over what was causing this (although I still don't know why). The root cause is that the <pre> block has a huge area of whitespace at the end of almost every line. Although it looks like the widest <pre> line is 76 characters long, all but the last line are actually 135 characters long, padded out with completely ordinary spaces.
The MDN writeup of
contains a hint as to why this is happening, when it says that for
pre-wrap 'sequences of white space are preserved'. This is what
you need in preformatted text for many purposes, but it appears to
mean that the really long runs of trailing whitespace in these lines
are being treated as single entities that force the content width
to be very wide. Firefox doesn't visibly wrap these lines anywhere
and has the whitespace forcing the surrounding boxes to be wide,
while Chrome merely had it widen the overall page width without
expanding the content boxes. My Chrome at the right width will force
the longest line or two of the <pre> content to wrap.
My fix for now was to use magic site admin powers to edit the raw
comment to trim off the trailing whitespace. In theory one possible
CSS-level fix for this is to also set the
word-break CSS property to
break-all' for <pre> elements, which appears to make Firefox
willing to break things in the middle of this sort of whitespace.
However this also makes Firefox willing to break <pre> elements in
the middle of non-whitespace words, which I find both ugly and
unreadable. What I really want is a setting for
means 'try not to break words in the middle, but do it if you have
to in order to not run over'.
(Maybe in another ten years CSS will have support for that. Yes,
for regular text, in theory, but it doesn't seem to do anything
here. Possibly this is because Firefox doesn't feel that the large
chunk of whitespace is actually overflowing its containing box but
instead it's growing the containing box. CSS makes my head hurt.)