Greetings,
I have been developing websites in CSS for a couple years; I claim to
be no expert, but certain things could definitely be easier.
Consider the box model and it's different implementations:
http://tantek.com/CSS/Examples/boxmodelhack.html
Microsoft's way and the web standards way. Ironically, though
Microsoft implemented the box model incorrectly, I consider it
superior.
One of the biggest issues that comes about when attempting to create
CSS web designs is fitting a bunch of boxes within a containing box
where the width unit specified on inner boxes may vary. I'm sure many
of you have run into this common problem -- some inner boxes are
measured in ems, some in pixels, some in percentages, etc. I'm not
advocating that a designer use inconsistent units of width without
reason; sometimes, however, certain designs do warrant differing
units.
Microsoft's way makes the calculations for fitting boxes across the
entire width of a containing box much easier. Today, using the
correct box model, some designers will nest their <div> tags inside of
an outer containing <div> tag (having no margin, no padding) in order
to mimic Microsoft's way inside the context of a standard's compliant
browser.
This lead me in my thinking to trying to come up with a better way to
solve old problems. I was thinking about a new way of laying out
pages where designers could eliminate the headache of trying to
specify all the right calculations for getting all their boxes fitted
properly together.
Here it is:
The "pushpin" property.
Imagine the following box.
<div id='example'></div>
tl t tr
+----------------------------+
| |
| |
| 'example' |
| div |
l | | r
| |
| |
| |
+----------------------------+
bl b br
Each box has named sides and corners necessary for use with the
pushpin property.
sides: t = top, r = right, b = bottom, l = left
corners: tl = topleft, tr = topright, bl = bottom left, br =
bottomright
Now for the purpose and the implementation of the pushpin...
Take the following 3 boxes contained inside the body.
<body>
...
...
<div id='menu'></div>
<div id='content'></div>
<div id='sidebar'></div>
...
...
</body>
+--------+ +-----------------+ +--------+
| | | | | |
| | | | | |
| | | | | |
| menu | | content | | sidebar|
| | | | | |
| | | | | |
| | | | | |
| | | | | |
+--------+ +-----------------+ +--------+
....and the accompanying CSS:
#menu {
width: 150px;
}
#content {
pushpin: left right menu;
width: auto; /* shrink-to-fit */
}
#sidebar {
pushpin: left right content;
width: 150px;
}
Here's the definition of pushpin:
pushpin {[side or corner name of this element] [side or corner name of
attached element] [attached block element id] ... }
Therefore...
#content {
pushpin: left right menu;
}
.... reads ...
join the "left" side of the the "content" block to the "right" side of
the "menu" block. The shorthand reads...
#content {
pushpin: left right;
}
join the "left" side of the #content block to the "right" side of the
preceding block (regardless of its ID, if any) present in the markup.
So what? Does this solve anything?
Lots of things:
1. Consider that a common fixed-width layout uses a background image
that includes sidebar coloring so that the sidebar will have the
"appearance" of extending all the way down the page.
http://www.alistapart.com/articles/fauxcolumns/
Using a "pushpin" tells the CSS rendering logic to join two
block-level elements entirely along their opposing sides (or corners
if desired). Using a pushpin would allow the actual sidebar to extend
fully down the page (not only by appearance).
In this way, designers wouldn't have to specify special margins or
padding to prevent the actual content from spilling into the area
immediately below the sidebar. Thus markup is greatly reduced. And
the background images assigned to the parts would actually contain
only the images required by each specific element.
2. Consider tables. How difficult is it to mimic complex table
layouts with CSS only and without tables? It can be done, but there
are a host of problems.
Consider...
+-------------------------------------+
| ele1 |
+-------+--------+------------+-------+
| ele2 | ele3 | ele4 | ele5 |
| | | | |
+-------+--------+------------+ |
| ele6 | ele7 | |
| | | |
+-------+---------------------+-------+
Looks like a table right? Designating a purpose for each of the 7
elements is irrelevant. The point is it's a mock layout that somebody
somewhere might use, and as far as tables go, it's nothing that
complex. Tables can be so much more complex than this.
Imagine how difficult it would normally be to lay this out using
tableless methods. Sure it could be done. But let me add a few
restrictions. You must do it using the following markup.
<div id='ele1'></div>
<div id='ele2'></div>
<div id='ele3'></div>
<div id='ele4'></div>
<div id='ele5'></div>
<div id='ele6'></div>
<div id='ele7'></div>
Notice there is nothing more and nothing less that the semantic markup
for the elements required by our hypothetical page. (Isn't that the
goal -- to avoid unnecessary markup?) There is no need for containing
elements to group elements together. Our markup contains nothing but
what is required semantically. (We didn't even need to specify
rowspan or colspan!)
Next restriction. Do it without "absolute" positioning.
Unfortunately, we want to maintain this layout regardless of whether
or not one element stretches to fit its content. Absolute positioning
will most likely create overlaps when this happens.
Here's our CSS:
#ele1 {width: 100%}
#ele2 {pushpin: topleft bottomleft ele1;}
#ele3 {pushpin: topleft topright ele2;}
#ele4 {pushpin: topleft topright ele3;}
#ele5 {pushpin: topleft topright ele4;}
#ele6 {pushpin: top bottom ele2;}
#ele7 {pushpin: topleft bottomleft ele3 left right ele6 topright
bottomright ele4 bottomright bottomleft ele5;}
Notice that "ele7" has multiple pushpins. Think of pushpins as the
metaphor they are. You can add as many as needed to join all the
corners and edges you like.
Notice that width was only specified on the top element (ele1).
Widths could have been specified on certain elements if they had a
desired width (regarless of unit). The remaining widths will be
evenly distributed; however, the pushpins must always perform their
duty. No element may ever accidentally spill over into the region of
some other element.
Futhermore, pushpinned elements could still speficy margins in order
to create visual gaps between the boxes.
One of the best features of the pushpin metaphor is that it is easy to
define layout in a way that is much easier to get our brains to
understand (my brain anyway) than to have to constantly play with
units of measurement. The unit measurements may still be specified on
the blocks whose width must be a certain size, but they may often be
omitted. Consider the three panel layout in the first example --
specifying the width on the content area was completely unnecessary.
I can offer many more examples of the benefits of the pushpin
metaphor, but I'm hoping you can begin to envision them for yourself.
I hesitate to go on and on with examples without first receiving some
feedback. Oftentimes, it's easy to imagine better ways, only to find
that more experienced persons can offer equally valid ways for
accomplishing the same within the context of what already exists.
As I said, for me the concept of telling the browser to join things
together based on common corners and edges seems far superior to
having to calculate widths. The visions I have for page designs
almost always involve a layout that in every respect looks like a
complex table (or many creative newspaper layouts). Yet I know that
for the sake of semantic markup tables are undesirable (they are meant
to markup tabular data!). Futhermore, think about the way that our
content (contained within tables) displays in text-only browsers.
Don't get me wrong, I'll use a table if it makes sense or it makes my
job a lot easier, but I try to avoid them because of my desire to have
good semantic markup.
I haven't worked out all the syntax, just the general concept. What
do you guys think about the "pushpin" metaphor? Am I on to something?
Or am I missing something completely?
Mario T. Lanza
Clarity Information Architecture, Inc.
2004.10