← Back to 2. Initial Layout CSS
Continue to 4. UI Navigation Design
← ← Jump back to Design Demo: Medieval Scroll Index

Main Points

Here's the most interesting part of this project for me; as I said before, the primary tool of risk management is time. Trying to apply a border to a container in a fluid layout is tricky and potentially very complicated, so we're going to attack that portion of the problem now. I expect to have to use several tags (eight actually) just because CSS only permits one image to be applied to an element and I need eight images, one for each corner and side. Rest assured that I've no intention of playing fair. I've done a fair amount of research and I know going in that I've got two of Dave Shea's tricks up my sleeve. One, adding a <span> tag within another element to give you an extra element where valid, and two, using extra divs that can be absolutely positioned wherever needed.

Preparation and Testing Notes

We're going to apply border images to the page. Right now, this is just for structure, so I'm using test images that we'll replace in the image phase of design. Top left is an easy position to get so I'm not worried about that. And if you can apply an image to the top left, a simple repeat-x value will create your top border. These two are easy so I'm not worried about those. Aligning items on the right, has sometimes been tricky, though I believe this was mainly due to IE6 which is declining in usage now with the growth of IE7 and 8. And I remember having difficulty in the current template getting things to attach to the very bottom of the screen. The bottom items may cause some problems then. I'm also concerned about both the left and right sides; CSS supports the width property very well, but height is much more troublesome. While it's easy to apply a repeat-y to an element, the element itself has to extend from the top to the bottom of the webpage for the effect to work. This could also be a trouble spot.

For applying images to the border of the webpage, nothing beats the html and body style rules. Virtually every image I tried was fine when applied with either selector. If only CSS2.1 would let you use multiple images on an element, these page borders would be a snap. At first, body was misbehaving badly until I remembered that I was using body {margin: 2em 1em 0 2em;} rule to provide whitespace between the content and the edge of the page. I simply changed it to body {padding: 2em 1em 100px 2em;}. This provided me with whitespace I wanted and let the image I applied to the body tag hug the browser window. I also changed the bottom padding from 0 to 100px to adjust for the image. This turned out to be unnecessary, the spacer is doing it naturally. [chroniclemaster1, 2009/06/21] I'll probably play with this later, but for now it's just fine. If I had to place bets, I suspect the two bottom corners are the most troublesome. One of my favorite designs ever, Dave Shea's "Tranquille" - the homepage of CSS Zen Garden, uses the body tag to apply the image in the bottom right corner. However, there's an outside chance that the height issue may result in me applying the the left and right side images this way. I plan to save these selectors for the end and just see which two images are the most difficult to get working.

As expected, height is proving troublesome. Part of my problem, I think, is that it turns out I really have no container div. If I had no padding on the body but on a container div instead, I think I could swing using the container to apply at least one side, but that's untested. In theory, if it worked, I could also use a wrapper div on the container to apply the other side. However, width: 100% works beautifully. But as you'll see, margin and padding can wreak havoc on it in narrow browser windows. [chroniclemaster1, 2009/06/21] I would rather not play too much with the XHTML at this point. It is definitely something to consider, maybe when I experiment with the form tag. OK, that didn't take as long as I thought; this is pissing me off. Screw the XHTML, all my extraDivs are having extreme problems fitting into the page borders because of the body padding. After studying different options, the CSS Zen Garden XHTML seems the most robust: body tag, container div and the extraDivs follow the container (sibling elements, not nested inside the container). So I've created a much more radical test than I expected to be doing...

I added two divs which wrap everything inside the body element, ids outerContainer and innerContainer. Then I wrapped the header and mainBody sections in another pair of divs, content and contentWrapper. I also moved the forward and back links immediately before and immediately after the mainBodyWrapper div, as this is more semantically correct and should help organize things. Based on the advice of a friend of mine, I moved the form tag. Now it is only wrapped around the contact form. I had previously wrapped it immediately inside the body to grab the entire webpage on the understanding that .NET would not process parts of a .NET webform if they were outside the form tag. I also understood that it was unwise to have multiple form elements on a page, but Marc uses this technique exclusively and I have a lot of respect for his coding abilities so I've been toying with the idea of following suit for awhile.

Skip to Main Points

Fluid Image Border Layout

Here are the key changes that were necessary before the CSS for the background images was successful. Once I'd modified the XHTML and played with various options, these two style rules seemed to best take advantage of the new style rules and provide the whitespace I needed most effectively.

#innerContainer {
padding: 7em 6em 0 6em;
}

#mainBody { /* Page Width */
margin-left: 1em;
width: 85%;
max-width: 1150px;
}

I was able to move the padding on the body tag to the innerContainer div. This preserved the whitespace around the edge of the page and freed up all the extraDivs which proved key to applying the background images. The assorted tags for the page width also bit the dust and I simply applied those styles to the entire mainBody div and added a little extra left margin.

#extraDiv1 {
background: url(../Images/BottomSide.jpg) repeat-x;
position: absolute;
vertical-align: baseline;
width: 100%;
height: 100px;
left: 0;
}

#extraDiv1 span {
background: url(../Images/BottomRightCorner.jpg) no-repeat;
position: absolute;
width: 100px;
height: 100px;
right: 0;
}

#extraDiv2 {
background: url(../Images/BottomLeftCorner.jpg) no-repeat;
position: absolute;
vertical-align: baseline;
width: 100px;
height: 100px;
left: 0;
}

Here is the most difficult part of the CSS which makes the image border work. I was nervous about attempting this for fear that I wouldn't be able to get it to work. Adding a container div was the real breakthrough. If that's cheating so be it. I placed one of the extraDivs, extraDiv1, at the bottom of the webpage using position: absolute; and vertical-align: baseline; to create the bottom border. Background images aren't considered genuine content, and the extraDivs have no content of their own so they collapse and vanish without a specified width and height to force them open. Note that the width of extraDiv1 is set to 100% so that BottomSide.jpg will tile the entire width of the page with a simple repeat-x. I added the left: 0; so that the first one will align exactly under the bottom left corner. One corner is applied to the span in extraDiv1 and the other to extraDiv2 using almost the identical settings as extraDiv1. The only exception being that the corners shouldn't tile, so the background uses no-repeat and the width is 100px not 100%.

#extraDiv3 {
background: url(../Images/TopSide.jpg) repeat-x;
position: absolute;
width: 100%;
height: 100px;
top: 0;
left: 0;
}

#extraDiv3 span {
background: url(../Images/TopRightCorner.jpg) no-repeat;
position: absolute;
width: 100px;
height: 100px;
right: 0;
}

#extraDiv4 {
background: url(../Images/TopLeftCorner.jpg) no-repeat;
position: absolute;
width: 100px;
height: 100px;
top: 0;
left: 0;

}

html {
background: url(../Images/RightSide.jpg) top right repeat-y;
}

body {
background: url(../Images/LeftSide.jpg) top left repeat-y;
}

This will look pretty familiar. extraDiv3 and 4 add the border to the top of the page using almost identical CSS to how extraDiv1 and 2 add the bottom border. The only change is that the vertical-align: baseline; has been replaced with top: 0; since we're attaching the border to the top of the page. Finally, I apply the left and right side images to the html and body style rules with a repeat-y so they tile nicely down the sides. Overcoming the challenges of the CSS height property, turned out to be the most difficult problem. My attempts to use divs to apply the side borders would not extend the entire height of the page. On the other hand, the vertical-align: baseline; solved my problems with attaching images to the very bottom of the webpage, while width: 100% solved the problem with the top and bottom borders.

I should probably clean this up a bit, but I'll do that on the next page so this stage of design will be preserved. It wasn't until I got this far that I knew the design would work and could start studying it for ways to reduce CSS and make things more object oriented - after all I said on the last page, this is pretty atrocious. It's very relevant however, that you see object oriented CSS is an end; we had no idea how this would work in advance so we had to build it before we could see the semantic connections. This "mess" is how you get the design built, we'll refactor it into an object oriented fashion before we go live.

Skip to Main Points

IE6 and Other Strangeness

#extraDiv2 {
width: 100%;
padding: 1em;
position: absolute;
left: 0;
}

Here's one really strange error that cropped up while I was trying to apply images. I've removed all property / value pairs which had no effect. This CSS caused an approx. 2em gap to appear on the right side of the page - beyond the screen causing a horizontal scrollbar to appear. Removing the padding: 1em; or the width: 100%; corrects the problem. Removing left: 0; actually increases the gap an additional 2em. I believe this is because the left property smashes the extraDiv2 against the left side of the screen, so without it, the div respects the 2em left padding on the body. Removing position: absolute; decreases the gap to 1em, but you are still left with a horizontal scrollbar. This is interesting behavior because a horizontal scrollbar is one of the cardinal sins of user interface (UI) development. It's relatively easy for users to scroll up and down, while by comparison, scrolling horizontally is a bitch. Eliminating these kinds of errors therefore is key. This problem seems to be the combination of forcing the width to 100% and then applying non-zero padding. The padding forces the 100% width to push outside the frame of the browser... except ironically IE6. To let you recover from the shock, let's look at the things IE6 can't handle.

/* Jump Back Links which flatten against the left margin */
.jumpBack, .pageBack {
width: 35%;
}

Ignoring the stylesheet header which looks basically like all the others, this is the top of the IE6 stylesheet. This style rule was necessary because only at 800px width and larger did the jumpBack link look right. Once the browser window shrank below that, the words rapidly peeled off, until by around 500px they were all stacked up against the left hand margin each above the other. Pretty tacky looking. Before, I started to redo the border whitespace for IE6, this was a simple .jumpBack {width: 55%}. However, as I got the whitespace issue below under control, I had to reduce the width and include the pageBack class as well to prevent the text from the pageForward link from riding over the top of them.

/* The top (extraDiv3) and bottom (extraDiv1) divs don't stretch all the way */
#innerContainer { /* innerContainer padding for page elements is the problem; removing it */
padding: 0;
}

.computerCode { /* When browser becomes narrow, the 3em left and right margins kill the design; removing them */
margin: 0.5em 0;
}

The padding I'd applied to the inside of the innerContainer div caused the top and bottom borders (extraDiv1 & 3) to stop 12em short of the right side of the screen. I played with various settings, but couldn't get divs to size properly so I finally had to remove the padding from the innerContainer div completely. As the browser window gets narrower, the long path names won't wrap in IE and cause problems; I decided to remove the left and right padding from the computerCode blocks for the same reason. Once I did that, you can break the design, but it has to be "really" narrow. I think I've covered that well and I don't think I can fine tune anymore in this file without tweaking my main stylesheet. And to be honest that's what I created this one for, dealing with IE6 squirreliness as best as we can without ruining code for compliant browsers.

/* Redo Page Whitespace: Top */

h1 {
margin-top: 3.5em; /* It seems to be doubling and I'm not sure why, but that's why the top page margin is 3.5 instead of 7em */
}

/* Redo Page Whitespace: Left */

.pageBack, .jumpBack { /* Doubling error */
margin-left: 1em;
}

/* Redo Page Whitespace: Right */

.pageForward { /* Doubling error */
margin-right: 1em;
}

/* Other */

#extraDiv3 span, #extraDiv1 span {
margin-right: -1px;
}

It was easy to restore whitespace at the top of the page, and none was required for the bottom. But there is a 6em margin I wanted to apply to each side. Any margins I applied to the mainBody div or its containers caused the computerCode blocks to stick out and create a horizontal scrollbar. It pretty quickly became apparent that this would be a tough sell, especially on the right. A horizontal scrollbar is a major UI failure at anytime, but everytime I get one in this design it causes a second major collapse. The top and bottom borders stop at the edge of the browser window. Therefore the right hand corners don't match up with the right side, so I took a couple hours to try to resolve this. So I threw out a couple hundred attempts because they resulted in a horizontal scrollbar in the design. For some reason I don't yet fathom, a 2em margin is fine, so that's what I've set both sides to; all efforts to get anything larger than that collapsed. My solution for the IE6 stylesheet was to accept a lot less whitespace around the border, because the collateral damage was unacceptable. Now we need to finish positioning for the navigation elements to complete our initial layout.

Skip to Main Points
← Back to 2. Initial Layout CSS
Continue to 4. UI Navigation Design
← ← Jump back to Design Demo: Medieval Scroll Index