A horizontal layout
This is a pure
CSS challenge:
no javascript,
no extra HTML
Webpages, mostly for historical reasons, are assumed to develop vertically: they have a natural horizontal extent that is limited by the viewport (screen, page) width, and an indefinite vertical extent realized through scrolling or pagination.
These assumptions on the natural development of the page are perfectly natural when dealing with standard, classic text layouts (for most modern scripts), where the lines develop horizontally, legibility is improved by limiting the line length and stacking of multiple, shorter lines is preferred to single long lines. In a context where it isn't easy to flow long texts into columns, the vertical development with constrained width is the optimal one.
However, these assumptions become instead an artificial constraint when columns with automatic text flow are possible, and this is exactly what this challenge is about: is it possible to achieve, purely with CSS, a layout that is vertically constrained to the viewport height, but can expand horizontally to fit its content?
The solution that doesn't work
Let's say, for example, that we have the following situation: there's a
#page holding a #pageheader, #pagebody and #pagefooter ; the
#pagebody itself normally contains simply a #content div that
holds the actual page content. We want the #pageheader to sit on top,
the #pagefooter to sit at the bottom, and the #pagebody to sit in
the middle, with a fixed height, and extending horizontally to
arbitrary lengths.
In principle, this should be achievable with the following approach: set
the #content to use columns with a fixed width (e.g., columns: 30em)
and to have a fixed height (e.g., height: 100%), which lets the
#content grow with as many columns as needed, without a vertical
overflow: by not constraining the width of any of the #content parents,
I would expect it to grow indefinitely. The CSS would look something
like this:
html, body, #page {
height: 100%;
width: auto;
max-width: none;
}
#content {
width: auto;
max-width: none;
height: 100%;
columns: 30em;
}
#pagebody {
width: auto;
max-width: none;
height: 100%;
padding-top: 4em;
padding-bottom: 8em;
}
#pageheader {
position: fixed;
top: 0;
width: 100%;
height: 4em;
}
#pagefooter {
position: fixed;
bottom: 0;
height: 8em;
}
Why (and how) doesn't this work? Because there is an implicit assumption
that the content will always be limited by the viewport. By setting
the html, body, #page and #pagebody heights to 100%, we do
manage to tell the layout engine that we don't want the layout to extend
arbitrarily in the vertical direction, but even by specifying width:
auto and max-width: none, we cannot prevent the width from being
limited by the viewport.
What happens with this solution is that the #content overflows its
containers, instead of stretching their width arbitrarily (which is what
would happen instead in the vertical direction): this is clearly visible
when setting up ornaments (e.g. borders) for #page and/or #pagebody.
While this results in a readable page, the aesthetics are seriously
hindered.
The challenge proper
How do you ‘unclamp’ the HTML width from the viewport width, with pure CSS? How do you allow elements to stretch indefinitely in the horizontal direction?
A potential alternative
In fact, there is a potential alternative to the unclamped width,
which relies on the experimental ‘paged’ media proposed by
Opera achievable, in the experimental builds of Opera
supporting this feature, by setting #content { overflow-x:
-o-paged-x} or #content { overflow-x: -o-paged-x-controls}.
In this case, the page would still be clamped to the viewport width (and in this sense this cannot be considered an actual solution to the challenge), but the content would be browsable with ease, and the aesthetics would not be spoiled by the mismanagement of the overflow.