2 - 4. Polishing the Layout
Main Points
- Image Borders and IE6 Changes to the extra stylesheets.
- XHTML Changes Changes to the XHTML to facilitate better CSS.
- CSS Structural Changes Now that we've revamped the underlying framework, let's get to work.
- Skip to Main Points links return to the Main Points menu.
And we're done! What do you think? That's all there is to designing a webpage.
Just kidding.
Layout is a process that progresses throughout a project. After completing the initial HTML prototype, I started on phase two (of which this page is a part). After working with the colors, and doing some initial placeholders for the image border, this is where we're at. You can see the Medieval Scroll actually taking shape! We still have three phases to go at this point so it's a work in progress. I will explain more about phase two at the appropriate time.
However, during phase two there have been some substantial changes not only to the stylesheet but to the XHTML as well. Since these are fundamentally layout issues, I'm discussing them here even though it's out of chronological order. So welcome to a preview of where we're going; let's talk about modifying our initial prototype.
If you're more interested in the 'process' of design, feel free to move on to section 2 - 1. Color Theory. You'll find it easiest to move chronologically by using the Design Demo: Medieval Scroll Index to click into and then back out of pages. Just follow the numbers in the index to guide you; this walkthrough focuses on the topics involved. Also, thanks go to Transcending CSS by Andy Clarke. This was the CSS text I had handy during my redesign and there were several ideas that proved important not only for my personal development, but specifically for this design as well. His mastery of positioning was truly enlightening and powerful.
Image Borders and IE6
These changes are fairly easy to cover so we'll start with them. I did some swapping of the image order from page 5. I had been most worried about applying the right hand corner images, with good reason. So that's what I tried first using Dave Shea's <span> trick, and it worked. However, as I've continued to build the layout it proved to be fragile compared to applying the right hand corners with a separate div. The <span> elements therefore inherited the job of applying the left hand corners. I'm guessing this is pretty obvious, but the image was swapped from a bottom right corner to a bottom left by replacing the right: 0; declaration with left: 0;
#extraDiv1 span {
background: url(../Images/BottomLeftCorner1.jpg) no-repeat;
position: absolute;
width: 100px;
height: 100px;
left: 0;
}
I also had problems with the sides of the layout, but this change was even easier, I only changed the selectors on a couple of style rules. Previously, I'd used the html selector to apply the right side and the body selector to apply the left. As I worked with achieving proper spacing around the edge of the page and getting the sides to adjust to the proper height, I achieved better results using #outerContainer to apply one side. Since the body selector's height was most stable, I'm applying the right border there and the left side with #outerContainer. An important secondary consideration is that I can now apply a stable background image for paper texture to the html selector with a background color as a backup if the image doesn't apply.
The stylesheet for IE6 and below changed much more drastically, but the summary is pretty simple. In working out and debugging a lot of the cross-browser / cross-platform issues, problems in the IE6 stylesheet cleared up and I didn't need them. It now consists of three really minor sections.
.jumpBack, .pageBack {
width: 45%;
}
#divPageBackForward1, #divPageBackForward2 {
width: 85%;
}
I increased the width of the page back and jump back links from 35% to 45%. I was able to pull this off improving the display by adding a new div wrapped around the links and applying an 85% width to that. I also have the same style rules for correcting the errors in the navbar, plus I revised the XHTML (more on that later) so I can remove the active background color on the Chronicle Subjects menu item. The last section is one style rule to reduce the top padding for the subjects bar. For some reason, in IE6 the top and bottom padding is unbalanced so I reduced the top padding to 0 and now it looks OK. I can't get it looking better than that without messing up the main stylesheet.
Everything else is gone. I was able to toss it and handle it in the main style sheet. As I started painting the layout in phase 2 - 3, I had to look at the layout and it's behavior in much more detail. As I cleared up issues, not surprisingly IE6 problems started to clear up on their own. As I worked out better control over the whitespace and margins, I was able to drop that entire section from the IE6 stylesheet, seven style rules I won't miss; the new CSS works beautifully in modern browsers and IE6 too. I also got better behavior out of the image border, and was able to drop a -1px right margin on the top and bottom corners on the right side. All in all everything is much cleaner.
Skip to Main PointsXHTML Changes
XHTML is something that I emphasize should be done in isolation. It helps you focus on the semantics and write better XHTML. It also helps you write worlds faster because you're focused, not bouncing back and forth between the demands you have to meet for semantics and those you meet for appearance. Then you can settle down and work on the CSS which goes faster because you're focusing on just that technology and using it to do what it does best. Those people who get in a rush and try to combine these steps to 'get it done fast' are kidding themselves. Breaking the process down into steps is how you 'assembly line' the process to speed development. It also helps maintain your separation of concerns (SoC) which is a critical best practice in software development. You wind up with more modular code, more reusable code, more maintainable code, and it goes faster.
That being said, there are times as you design that you will find choices about semantics that you made incorrectly, or you make some changes, or you find an alternate semantic structure that better fits your layout needs... and even - Yes, it's true - times when you just can't get the CSS to work without modifying the XHTML a little. This is a method of last resort after trying several different CSS techniques, nor should it sacrifice semantics. However, sometimes the CSS just needs an extra element to hook onto, or a modified structure to work the way you want.
There were several key changes we made to the XHTML to facilitate better function. First, we swapped the order of the clock and the main heading in code. The navbar is designed to collapse narrower when the viewport becomes too narrow to accommodate the full width of the navbar. This makes it more flexible; the navbar doesn't force a horizontal scrollbar but rather accommodates the less than optimal browser width. Given the latest browser statistics I've been seeing, the vast majority of people are browsing at 1024x768 or higher so in most cases this will never be an issue, however the ability is there even though it's designed with 1024x768+ in mind. However, the navbar varies dramatically in height. (from 2 - 10em) Since the navbar is placed using absolute positioning, it covers up the h1, page title, probably the most important piece of text on the page. I tried briefly giving it enough margin to clear a 10em navbar, but that layout looked weird at normal resolutions and wasted a lot of space. As I continued styling the page, however, I switched the clock with the <h1> heading. The clock expands elastically at narrow widths increasing in height to perfectly balance the navbar and keep the <h1> heading visible at all times.
There were also changes to several other items. The forward / back links were problematic, so I stripped them down and completely rebuilt the CSS. In order to make it work effectively I had to wrap a div around the set of links. Then I moved the spacer div which follows it from the content page to the master page. I also finagled the Chronicle Subjects text on the #siteWide navbar, more on that below, but in order to make it work, the subjectMenu class is now applied to the list item which contains the span element wrapped around the text and the links, not the span element itself. I changed the the 'authorship' section to the credits section. For the most part this simply changed some of the names to a more semantic form, but I took the opportunity to add individual classes so that each row can be targeted in CSS. (author, editor, firstPosted, etc.)
Skip to Main PointsCSS Structural Changes
Here's where the bulk of the changes are, in the Structure stylesheet, exactly where they should be. First, I've been reading a lot more about normalizing stylesheets. Stylesheets designed to remove all default styles applied by a web browser. However, I'm concerned about the lack of consistency across these stylesheets. Everyone seems to have their own custom version. The only thing that appears common is that the *, star, rule for resetting margin and padding is giving way to a new version where you cite every XHTML tags. A designer at Yahoo has recommended this though without justification. I'm going to let some rabbits go first and figure out why before I make any changes. This is a core element in my ability to provide cross-browser compatibility, and I want a pretty thorough explanation before I start rewriting it. I suspect, though I haven't confirmed this, that designers aren't agreeing on which tags to include any more than they agree about anything else in a “normalizing” stylesheet.
So for now I'm keeping my * rule. I have added a couple pet peeves to my own normalizing section. There are a couple of browsers that put quotation marks before and after <q> tags which really annoys me. This is one of Andy Clarke's rules to eliminate them by replacing them with an empty string. I'm also using a rule I saw several places that removes borders from images. I haven't really run into this, but a lot of people are using it so I assume it's a problem somewhere... and it would certainly annoy me.
q:before, q:after {
content: '';
}
img {
border: 0;
}
/* Add Page Border Whitespace */
#innerContainer {
padding: 8em 3em 4em 2.5em;
}
/* Page Width */
#mainBody {
max-width: 70em;
}
A quick aside, you'll notice that my comments appear on the line above the style rule they relate to; previously they'd appeared after the curly brace on the first line. Not only did this make for some long lines, but it's very difficult to comment out code. If you place an opening comment before the selectors, the ending comment of the note closes it. By repositioning the comment, it's much easier to comment out one or more style rules.
I spent a lot of time going back and forth trying to get whitespace to behave. What I've adopted is a relatively simple object oriented design. I'm applying padding to the innerContainer. The purpose of this padding is no more and no less than to clear space so that nothing runs over the image border and while the images themselves are 100px wide, the apparent border is about 30px on the sides. I set extra padding at top and bottom to give myself additional space. I'd originally set the padding in pixels to adjust it to the measurements of the images, my normal practice. However, at resolutions above 1024x768, the amount of whitespace shrank proportionately and em units gave me better cross-browser performance. Using this one style rule to 'clear' the image border created a space in which I then positioned everything else. This object oriented approach worked much easier than my other attempts and was much more stable; I think these are not coincidences. Using the image border stylesheet and this style rule, I can easily reuse the image border in other designs.
I also kept a max-width declaration on the #mainBody div, everything else I was able to throw out by using #innerContainer padding to define the primary whitespace for the image border. There were a couple of issues with this. One, some designers prefer not to use max-width because it is not supported cross-browser; I disagree. max-width like the other min / max properties are enhancements that don't misbehave, they either apply or they don't so they fall safely into the category of progressive enhancements.It's bad usability design to force the user to turn their head when tracking from the end of one line to the beginning of the next. While typically small, this repetitive motion quickly generates neck strain and drives users off your website. It should be easy to track from one line to the next by moving only your eyes. I've followed Andy Clarke's recommendation of using Mozilla's max-width of 70em to ensure that content doesn't strain people's eyes.
Note that I've applied this style rule to the mainBody div. I went back and forth about applying it to the entire design, but opted not to. mainBody is wrapped around the content sections so the content which is full of text passages that require lots of tracking won't overtax people. Everything else in contrast, the header, footer, and forward back links are not lines of text that people are scanning across. Since I'm not making people read long lines in these sections, the 70em limitation doesn't apply and the design looks better filling the viewport.
/* Other Elements */
a {
padding:0.2em 0.5em;
}
Here you can see I also created an "Other Elements" group, though mostly it just collected stray style rules. However, since I've applied a background color highlight to all links, the functionality works much better with a "forgiveness" zone of padding to make the highlight much more attractive, visible, and the link footprint more clickable.
#specificNavbarWrapper {
position: absolute;
top: 3em;
left: 3em;
}
#siteWideNavbarWrapper {
margin: 0 1em;
}
#siteWideNavbarWrapper, #specificNavbarWrapper {
margin-right: 3em;
}
.subjectMenu li a {
padding-left: 2em;
}
The specificNavbarWrapper is still absolutely positioned, however, I dropped trying to control it with margins. It behaves better just by placing it with positioning rules. The siteWideNavbarWrapper is still relatively positioned and just needed a little nudge. All these are defined in ems so they relate properly to the content margins set by the innerContainer div. I've also applied a right margin of 3em to both wrappers so that the navbars don't extend past the apparent border defined in the images. Finally, the modification I made to the subjectMenu class in the XHTML pays off here. It allowed me to use this style rule to indent the two subject links beneath the Chronicle Subjects text on the first menu of the site wide navbar.
I also resolved the pull up menubar at the bottom of the page after much study. I couldn't find anyone with a method that would automatically get the menu to appear on top of the menu bar. All solutions hinged on defining a height for the navbar and setting the menus with a position: absolute; declaration combined with a bottom property that was specified to whatever the height of the navbar was. I therefore adopted this practice. I set a height of 2em for the navbar buttons which I'd wanted to avoid, but compared to the mess of absolute positioning that I had before, this is world's better.
/* Adjustments for Pull Up Menu */
/* Takes position for the context of the navMenus, but rule to drop downs causes navButtons to ride over the menus regardless of the z-index */
#siteWideNavbarWrapper .navButton {
position: relative;
}
#siteWideNavbarWrapper .navMenu {
bottom: 2em;
}
The navButton class of the pull up navbar needs to take position or the positioning of the navMenus won't take effect in relation to the navButtons. Since I don't want to actually move the navButtons - they're already positioned where I want them - I applied a position: relative; declaration and did not specify an offset. Then I set the navMenus as discussed, bottom: 2em; and since the navButtons are 2em high, the menus pull up from the navbar. Success!
/* Set divs as positioning context */
#divPageBackForward1, #divPageBackForward2 {
position: relative;
}
/* Stop link text from overlapping */
.pageBack, .pageForward, .jumpBack {
width: 48%;
}
/* Position forward link div right (and align text to right of div) */
.pageForward {
position: absolute;
text-align: right;
top: 0;
right: 0;
}
As I mentioned earlier, I completely rebuilt the forward and back links. Thank Andy Clarke's advice to use positioning first; dropping the floated scheme is what got this to behave properly. First, I added two divs in the XHTML to wrap the forward and back links, then I could hook onto them and set the position: relative declaration so that I could position the links relative to those divs. I've had problems with text from the page forward link overlapping the others when the browsers become narrow, so setting the width of all elements to 48% keeps them on their half of the page. The pair of back links sit nicely left aligned and make appropriate room for each other, wrapping, etc. The pageForward link however needs a little more work. The positioning moves it to the top right corner of the containing div. However, it just sits in the middle of the page – ie left aligned against the left side of it's 48% width, so the text-align: right; declaration makes it behave properly. Done.
I've also made some other minor mods to the navigation. The right edge of the main points noticeably shied away from the page border because my lists have a 1em margin around them. This didn't look good So I inserted a margin-right: 0; declaration. Since I've applied a small padding and background highlight to all links, I was able to strip that out of the recommended page links and the accessible page links. I condensed the structure of those lists as well which eliminated separate sections for each. I also ran across the white-space: nowrap; declaration while doing some CSS research on the internet. By inserting this declaration into the style rules for the links in each section, it prevents each link from breaking - ie some words at the end of one line and some words at the beginning of the next; now either the links wrap as a unit, or they don't wrap at all. I also resolved an interesting cross-browser issue during this work. The accessible page links in Firefox were double spacing; the problem turned out to be that I was applying padding to the list items. Once I moved the padding to the links as part of increasing the clickable footprint, the double-spacing issue vanished. Good riddance.
/* Header */
#clockBox {
margin: -0.5em auto 0.5em;
padding: 0.2em;
width: 38.26%;
text-align: center;
}
All good things must come to an end. Here are the last changes to the HTML prototype. The clock at the top of the page was swapped with the <h1> heading to get better behavior out of the page header. The key change besides switching the order of the XHTML was applying a width. This allowed the clock to expand elastically lying on one line given sufficient space, and becoming narrow and tall at extremely narrow widths. The navbar displays the same behavior, so this CSS matches the clock with the navbar so the level one heading remains visible. I also adjusted the whitespace for better positioning and retained the centering on the clock text. Besides this, the only other change to the stylesheet involved adding some padding to subjects div so text didn't look so cramped inside. Now let's take a look at how our Medieval scroll got to this point...
Skip to Main Points