Continued from Part 1
That being said, it’s one thing to think you know how you’re going to accomplish something, and quite another to actually accomplish it.
And, of course, I was horribly wrong. The piece that actually caused me the most head scratching and teeth gnashing and hair pulling was that little window of open space above the nav element. See, I thought it would be cool to see content slipping underneath the fixed navigation and reappear on the other side. Practical? No. No practical use there, not as far as the interface was concerned. But I wanted it to work that way. It’s how I designed and envisioned it.
It seemed simple enough. If I Absolutely positioned some elements at the top of the page from the bottom of the code, and stacked them in the correct order, than the Title graphic would always be on top, the Tray Opener would always be beneath it (so that its drop shadow would visually effect the Opener) the Tray would slide open over the Opener but beneath the Title, and everything else would slide underneath the whole shebang without ever touching any of it.
Okay, first problem: An Absolutely positioned element (or a Fixed position element) will absolutely refuse to center itself on the page because, as I’ve said ad nauseum, it is not part of the page itself so it doesn’t follow its directions. So, what I had to do was Absolutely position one element at 100% wide and text centered, Relatively position another element inside it so that it would float center screen, then position another element inside the relative element as Fixed so the whole thing wouldn’t scroll. Don’t try to envision that in your head because you’ll only start crying.
If I did that three times, I had my stacked pieces all ready for content. What I forgot, however, was that I would need a fourth piece to serve as a clickable element because by sticking the Opener under the drop shadow of the Title, I had also turned off the ability to reach it with a mouse. Now, sure, I could have just redesigned the piece to look like it was under the Title but it really wasn’t, but that would defeat the purpose of what I was doing! Don’t you see?!? Can’t you understand?!? That drop shadow was fucking important!
So I added another element that would float above the title but would be otherwise invisible, but it would be placed exactly in the same position as the Opener so when a visitor clicked on it, the fucking thing would fucking open.
So, now we have Content, Opener, Tray, Title and Clicker stacked up on the page, all so’s the stupid Blog posts would slide underneath the Title a reappear on the other side even if the Tray was open. Still sounds cool and simple.
Now comes the next sticky part. While the Tray is opening or closing, I did not want it to appear in that open space above the Title. It looks bad and weird and awkward. I could have just said, “It’ll appear and disappear, fuck the stupid moving animation,” and that would have saved me hours and hours of time, but c’mon! If I’m going to spend any amount of time worrying about a stupid drop shadow, do you really think I’m going to just throw up my hands and give in to the Tray animation?
Clipping Your Overflow
I had two options; One was to stick some other layer up there temporarily masking the open section so that as the Tray slid up the browser window, it wouldn’t actually appear, or use Overflow (which describes how a positioned element should handle content that appears outside its dimensions) and Clipping (which defines what portion of the content of a positioned element is visible within its dimensions).
This is going to get really messy, so just hang in there with me and hold my hand really tightly.
The first option sounded good but didn’t work under any circumstances other than when the page was first opened. Once you scroll the content up the page, what that space looks like changes and there’s no way to capture it and try to fool the browser into using some kind of magical layer to mask the disappearing Tray, at least none that I’m aware of. And why would there be? Again, it’s just stupid of me to try this.
That left Overflow and Clipping. Thankfully, Overflow is very straightforward and easy to implement. Sadly, Clipping is an outright nightmare from one browser to the next. With Overflow, you just tell the element what to do and it does it.
overflow: hidden; means “hide anything outside your borders.” Simple, clean, effective. Clipping, on the other hand, should work something like positioning, but from the inside out.
First I’ll explain how it’s designed to work, then I’ll explain why it doesn’t (short answer: it’s Microsoft’s fault).
Clipping is another one of those things that sounds simple but is hard to implement because it’s crazy. Remember that to position something, you tell it where to start from (i.e. top) and how far to go away from it (i.e. 20px). To Clip something, you define a rectangle within the housing element as distances solely from its top-left corner, using four distance measurements in a clockwide direction from the top.
Say you want to clip a region within an Absolutely positioned element (because clipping can only be applied to Absolute positioning) to a 100px wide by 50px high box. And that box should appear 20px below the top and 30px to the left of the top-left corner of the containing element. Here’s the CSS to define that box:
clip: rect(20px, 130px, 70px, 30px);
That says, “Start 20px from the top, go 130px right (100px wide + 30px from the left), go 70px down (50px tall + 20px from the top), and stop 30px before the left edge.”
Simple, huh? So I’ll design you up a Relatively positioned blue box, 300px wide and 200px tall. I’ll place an Absolutely positioned green box 250px wide by 150px high inside that, and I’ll place a non-positioned (Static) red box 200px by 200px with some text inside that. Here’s the result:
margin: 10px auto;
clip: rect(20px, 130px, 70px, 30px);
And the same box without Clipping:
As you can see, Clipping an Absolutely positioned box prevents you from see anything except what’s inside the clip. Removing clipping reveals all the content, plus the entire Absolutely positioned box. You’ll also note that while the contents of the Red box are larger than its container, you can’t see it because the Green box has an instruction to hide Overflow.
Luckily, I didn’t have to resort to clipping anything. If you tell the Absolutely positioned element not to show its Overflow, and it’s not a child of the content parent, then the tray will slide out of an invisible element into an invisible element as long as the parent element extends long enough to hold it.
Invisible, yes, but still there. Remember that an element positioned over another element, whether or not it contains something you can see, will turn off all links on the page you’re looking at. So the challenge was to hide the tray when it was closed, reveal only the portion of the tray that appeared below the Title, allow the tray to close and have its contents become partially invisible as they tucked back up under the Title.
The answer was to Absolutely position the tray’s holder at the top of the page, Relatively position another element inside that so it would float center screen, then Fixed position a third element inside the Relative element to hold it in place during scrolling. Finally, the tray itself is in another Absolutely positioned element so it can slide freely when animated. Then, I instructed the script that creates the animation to switch the Tray’s display from “none” to “block” depending on whether it was down or up.
This is all a convoluted mess, I agree, and could all have been avoided (well, partially avoided) if I had made two simple concessions; don’t center the content, and don’t keep that window of empty space above the title. Those two decisions caused all the headaches to come.
You may remember, if you actually read all this crap, that I mentioned some weirdness that the interface experiences on Apple’s Safari browser. If you’re using Safari (as almost all my compatriots are anymore, even though it still represents only a small fraction of the general public I’d guess that over 50% of anyone interested in this site is probably on a Mac) you can open the tray at the top of the page when you open glassdog and scroll up and down and watch the content move under the tray and appear over the title and everything just works wonderfully.
However, if you close the tray and scroll down to any other point, then open the tray, and then scroll the page, the tray will visually roll itself up as the content scrolls under it as if the content is erasing it. If you then move your mouse to where the tray used to be, portions of it will reappear as if Safari had a brain fart and went “Oops! Oh, yeah, that thing. It’s still there if you really want it.” And you can close and open it as normal again.
This action varies depending on where the tray is in relation to the rest of the page, and if you are scrolling the content upward or downward.
Now, I realize that the point of a web page isn’t in the scrolling or even in the navigating, it’s in the reading. One presumes that you will open the tray only occasionally to use whatever parts you deem necessary and then close it again to continue reading, rather than open it and scroll and scroll and close it and scroll and open it and close it and open it and scroll and scroll and scroll the other way… but it doesn’t work. And it’s the one piece I have yet to resolve. Anyone who might have a clue about that, feel free to write and inform me of the reasons and, hopefully, a solution other than “don’t center the content and don’t have that stupid open area at the top of your stupid page.”
And that’s the story of the animated tray at glassdog.com. Not very interesting, is it?
Going forward, I’ll be using this space for even more uninteresting things concerning the art and science of web page design. More CSS tricks, more fun with PNGs, more about the use of Clipping and Overflow, subclasses and navigation, Blogs and tables and things that go bump in the browser.