If web pages were made out of wood, the grain would be running up and
down. Vertical is the natural flow of web layout. When page elements
reach the right edge of the browser window and go over, the flow
defaults to “wrapping” that element down onto the next line.
How To Create a Horizontally Scrolling Site
If
web pages were made out of wood, the grain would be running up and
down. Vertical is the natural flow of web layout. When page elements
reach the right edge of the browser window and go over, the flow
defaults to “wrapping” that element down onto the next line. The more
content on the page, the taller it gets, not the wider. Why is this?
Because it just makes sense. Our eyes are used to reading fairly short
lines of text, so if we were to see a paragraph of text in one long
straight line, it would be painful to read. Paragraphs need to have
line breaks in them to be readable (hence the term “blocks” of text).
We sure as heck don’t want to hard-code line breaks into the markup
ourselves. Obviously, we don’t have to, the browser does this wrapping
for us. Thus the vertical expansion.
This natural flow has lead
to conventions in web page layout and even into hardware itself. Notice
how many computer mice (mouses?) have a special scroller exclusively
for vertical scrolling. But web pages are equipped with both vertical
AND horizontal scrollbars right? If we are responsible with our web
layout, we can go “against the grain” and create web pages that use
primarily horizontal scrolling and can even expand horizontally as we
add more content. Perhaps a slight blow to “useability”, but it sure
can be a cool creative touch!
The best way to do it
I’m
going to go out on a limb here and say that I think a table is the best
layout technique for a horizontally scrolling site. Before I explain
why, let’s look at a couple of other possible techniques:
- Set a really wide static width.
Perhaps the “quick and dirtiest” way to get a horizontal layout started
is just to set a really wide static width on the body element itself.
Say, 10000px. Go ahead and try it, you’ll surely get a horizontal
scrollbar. While this works, it’s a bit inflexible. Web pages are
dynamic places and we should be prepared for expandability, not
limiting ourselves with static widths. Think about regular vertical
scrolling sites. You don’t go around setting static heights on your
pages do you?
- Floats + Whitespace. I spent
some time playing with the float property and the whitespace property
to see if I could find a way to fight browser auto-wrapping, but I
didn’t have much luck. Page elements which are floated but do not have
a width exhibit a property where they expand to the width of the
content inside them. I thought perhaps if I put a bunch of float
elements inside of that, it might just keep expanding beyond the width
of the browser window. No dice. There is also a whitespace: nowrap;
property in CSS which I thought might be able to be exploited to fight
the auto-wrapping, but it only works for text elements, not blocks or
just any old thing you set to inline. Oh well.
- Use JavaScript to set a width.
JavaScript clearly has the ability to manipulate page elements and do
calculations on-the-fly. We could use this to create an environment
which behaves extensibly. However, it considered bad mo-jo to handle
page layout with JavaScript. I agree with this in general, but I do
believe you can use JavaScript in this way as long you do so
unobtrusively and take care to ensure the page will fall back to a
usable layout with JavaScript disabled.
The table method
What
we need is a page element which can expand horizontally as needed and
never “wrap”. A row of table cells fit the bill perfectly here. Table
cells will expand to fit whatever content is inside them by their
nature, and the will never wrap until a new row is started. Perfect.
Let’s
assume we are trying to lay out a series of blog posts one after
another horizontally. We would need to use a page structure like this:
<table>
<tr>
<td>
.. blog post #1
</td>
<td>
.. blog post #2
</td>
<td>
.. blog post #3
</td>
</tr>
</table>
Yuck,
right? It never feels good to use markup like that, not just because
it’s a table, but also because of how non-semantic it is. We are using
a bunch of tags here which are exclusively for presentation and have
nothing to do with content.
Ideally, our page structure would be like this:
<div class="post">
.. blog post #1 ..
</div>
<div class="post">
.. blog post #2 ..
</div>
<div class="post">
.. blog post #3 ..
</div>
Using jQuery, we can easily have the best of both worlds!
Write the markup we want, get the markup we need
We
are going to use jQuery to allow us to the markup we want (the div
structure) and manipulate it to get the markup we need for horizontally
scrolling (the table structure). You should have little alarms going
off in your head here about using JavaScript for layout, but rest easy,
we will ensure that without JavaScript enabled the layout will be
perfectly useable. As an added bonus, the layout will be useable with
or without CSS enabled as well, and any combination.
Let’s first think through what we want to happen:
- Wrap ALL of the posts in a single table tag and single row tag
- Wrap EACH post in a table cell tag
Now let’s include jQuery on our page in the head section, and write the jQuery we need to get this done.
<script src="js/jquery-1.2.6.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
$(function(){
$("#page-wrap").wrapInner("<table cellspacing='30'><tr>");
$(".post").wrap("<td>");
});
</script>
That
should do it! Notice how the cellspacing is added as an inline
attribute to the table element. We might normally apply padding to
cells with CSS, but we want to make sure that each blog post block is
as readable as possible even with CSS turned off. Without this, the
blocks would butt right up against each other making them tough to read.
The entire CSS file for this example is very very simple:
/*
RESET & BASIC SETUP
*/
* { margin: 0; padding: 0; }
body { font-size: 62.5%;
font-family: 'Lucida Grande', Helvetica, sans-serif;
background: #121212; padding: 20px; color: #999; }
table tr { vertical-align: top; }
/*
STRUCTURE
*/
.post { width: 500px; }
/*
TYPOGRAPHY
*/
p { font-size: 1.2em; margin: 0 0 15px 0; }
h1 { font-family: Helvetica, sans-serif; font-size: 4.0em;
letter-spacing: -1px; color: #ccc; }
h2 { font-family: Helvetica, sans-serif; font-size: 3.0em;
letter-spacing: -1px; color: #ccc; }
a { color: #0066cc; }
a:hover { color: #ccc; }
Only
a few things worth noting. The static width on the .post div controls
the width of each block. The vertical-align property on the table row
keeps each of the blocks aligned to the top of their table cells. This
defaults to middle, so this is necessary.
The Results
With
CSS and JavaScript both on (99% of users), we’ll have a nicely executed
horizontally scrolling site. With CSS and JavaScript both off (screen
readers), the structure of the individual blog posts rule the page,
assuming they are semantically marked up, the page will look great. The
only quirk here is if JavaScript is on and CSS is off (RARE), the page
looks a little bizarre.
Other techniques for horizontal scrollingLiterally
expanding the width of your page and using scrollbars to navigate it is
only one way to achieve the horizontally scrolling effect. Javascript sliders
are another route you could take, which simulate the effect. Flash
would be another possibility. When it comes to web design, there is
always many ways!
|