This is something that came up in my development of Tank! which I wanted to touch upon.
Forced To Float
The horizontal menu had to be put together using floated list elements. In previous horizontal menus I stayed away from using floats. This allowed for some easier alignment management (center-aligned horizontal menus). But because of the drop-down menus, I had to switch over to floated elements.
Why? Because there were a lot of inconsistencies across all browsers with respect to how child elements are placed in relation to inline elements. This is because inline elements must follow the inline formatting spec, which is a little confusing. It says padding, borders, and margin values of inline should be respected. But if we dig deeper and look at the Computing Heights and Margins section of the spec, we see vertical values for padding, margins and borders are not included when calculating the height of an inline box. This is why in previous attempts at horizontal lists based on unordered lists I would wrap the list in a DIV block and mimic the vertical padding on each list item in that DIV block.
So the height of these line boxes is based on the font metrics for that inline element. So say a line box, with padding, is 2em tall. But the line-box is only 1em tall. Where is the top and bottom of that line-box? On some browsers, the top of the line-box begins at the top where the padding begins. Meaning the bottom of that box is somewhere in the middle of where the actual text is. Other browsers have the line box directly over the text.
So the problem becomes, how do I line up a child element (the list for the drop-down menu) with the bottom of not the line-box, but the imaginary box that includes the vertical padding and border of the element?
Short answer is you can’t.
Long answer is this: It’s difficult. If you’ve got a 1px border and .5em bottom padding, you need to move your element .5em + 1px down. Well you can’t really combine the two units. You could maybe do a top:.5em;margin-top:1px;
but now you run into issues with relative positioning. Some browsers, even with position: relative;
set on the line element (the list item), will not recognize that item as controling the location of root point (0,0 – the top-left corner) that the relative positioning will be based on. Rather, the browser will use the first parent block element (UL
). Other’s will use the line box, but set 0,0 to the top-left not of the line-box but of the imaginary box which includes padding, border and margin values. There are a few other odd interpretations/implementations that browsers emply that I won’t get into. Suffice it to say that relative positioning child elements of an inline element is not an easy thing to do.
So we go with pixels! 10px bottom padding + 1px border = 11px. So we can set a top margin of 11px to get that element down below it’s parent inline element.
Not so fast.
Where does a block element that is the child of an inline element get placed by default (without any positioning or margins or whatever)? The answer is important because we base the positioning of the drop-down menu off its initial position. Problem is, the answer varies between browsers. Some recognize the containing block (the official CSS term for that “imaginary box” I talked about earlier) while some go off the line box. Those that go off the line box can have that line box’s root (0,0) at the root of the containing block, meaning the bottom of the line box is going to be somewhere in the vertical middle of the text.
.. Okay I’m getting off-target here.
Cliff Notes To Everything Above
Long story short: dont’ do this. It sucks. You can fudge it to work with a 1-level drop-down menu. But if that drop-down has even more drop-down menus, you’re screwed.
The Point Of This Post
(This is where the fun is!)
What I want to point out here to everyone is the effect of being forced to go with floated elements and delve into some design philosophy; that’s where the fun stuff is.
I want a right-aligned horizontal menu because I’ve moved the typical vertical navigation menu to the right side of the layout. I want all navigational elements to be close together so the user doesn’t have to move the mouse far to access these elements.
The first thing I do is create a typical unordered list, placing what I think is the more relevant/importan parts of the list first. When I’m done, the top-level of this list is in this order: Layouts, Labs, Blog, Contact. This is the order I want for my horizontal list, when reading left to right.
But I can’t do that!
I’m using floated elements and I don’t know the width of each element because that value is based on font-size. I’m at the mercy of the user’s browser perferences. Because I don’t know the width of these elements I can do any positioning tricks to keep this horizontal list in the order I want.
Just reverse the list.
Indeed! Simple solution, isn’t it? But then I run into some philosophical design problems (let the fun begin).
First thing is, I have an implied priority in my list. There is nothing in the actual HTML to indicate this priority except the order in which these elements appear in the source. So your first exercise is: do you believe it is okay to assume priority of a list based on position in the source of an HTML document? If you say yes, how does that answer apply to other (non-list) elements? If I create a source-ordered layout, my left-hand nagivation menu will apear second, possibly third in the source, ahead of the middle and possibly right columns. Does that mean the content is more important than the navigation? What about “toolbar” like elements that you stick at the top of the page to provide some sort of global navigation across your site (like the horizontal lists in many of my layouts). Are they be more important than the content?
You might run into spots where your answer to one question will contradict your beliefs in design on another question. And again, this comes down to whether or not you believe order in the HTML source should affect the weight or importance of the content.
My answer is yes, position in the source does give an implied order of importance. This isn’t something documented in the HTML spec. This isn’t some design law. This is simply an assumption that we are trained to believe through everyday activities. Lists always put #1 at the top. Newspapers are read top to bottom, with the most important headlines up top. In HTML design we are taught to put the most important stuff up where a user will see it on page load and not down below where a (lazy) user might not see it because it’s below the area viewable on page load. You get the idea (and probably have a vew of your own examples).
(( I also have it in my head to re-use this drop-down menu on several different layouts, some of which will have a left-aligned menu that might be inline based and not floated. In those cases, my reversed list wouldn’t work the way I want it to. And this retains my originally intended order for non-CSS browsers like Lynx or old Netscape/IE, etc…))
So when I first put that list in as right-floated elements, I left the original order in the HTML source and sucked it up that the right-aligned menu wouldn’t read the way I thought it should (left-to-right order of importance).
But then I got to thinking about the situation.
The reversed order works for a right-aligned horizontal menu. The most important items are going to remain closer to the mouse than the less important items. If the theory is the first item in your list will be clicked the most, then the most clicked item will be closest to the focus of page nagivation, which is the right side in Tank!.
So maybe reversed order horizontal lists work better when right-aligned next to a right-sided navigation menu versus a left-to-right order for that same horizontal list.
And you’re still retaining your order of importance in the HTML source too.
And when you go for a left-aligned menu, the same HTML will work, meaning you can make that HTML a template that you pull into other pages, regardless of what side the main navigation menu is on.
Random thoughts for the day.