Faking Action Bars With CSS

Jake Howlett, 1 July 2005

Category: Miscellaneous; Keywords: CSS Actions Buttons

For as long as the Notes Client stays around there will always be Domino developers trying to mimic its features in the web browsers. Some of these features we can duplicate, some we can't. But that doesn't stop them being requested by our users.

One of the things often asked for is a page where the content scrolls while the "action bar" buttons remains pinned to the top. This mimics what we are used to in a Notes view or a Notes document and it's a nice feature; users don't want to have to scroll all the way back to the top of a page to press a save button.

The Problem:

To describe the problem, let's look at an example. Here's a standard document in the Notes client:

Notice how the Action Bar and buttons remain at the top as the page scrolls. Now, here's the same document in the web browser:

Notice how the Action buttons disappear as the page scrolls!

Now, you could argue that the web browser is not the Notes client and so we should avoid trying to make it look like it is. Sure people know how to use the Notes client and what to expect of it, but they are familar with the web and what to expect of that too. To try and mix the two might seem like a good idea but could well confuse the user. However you look at it, sometimes it's still worth your while knowing how to do things like this. The methods involved can be applied elsewhere to good effect.

Doing It In The Browser

The obvious way to keep one part of a form static is to use frames and, in particluar, an iFrame. Well, for me, this isn't the best solution. Frames are a nightmare to work with and should be avoided at all costs. There's a much simpler solution that uses nothing but CSS.

The basic premise is that you split a page in two - the topmost part holds the actions and the bottom section is the page content. The page as a whole is set to not scroll, meaning everyting is fixed in place. The bottom part of the page is set to have its content scroll whenever needs be. In effect the lower part of the page acts as an pseudo-frame and all appears as normal to the user.

How Do we Code This:

Here's the HTML for a simple page that demonstrates how it's split in to two element. First we have the layer named "fixed" which remains in place at all times. Then there's the layer named "scrolls", which, err, scrolls.

<body>
<div id="container">

 <div id="fixed">
  This is where the butons go.
 </div>

 <div id="scrolls">
  This is the content of the page.
 </div>

</div>
</body>

Let's now jump straight in to an example page. You might need to resize your browser to see it in effect. Notice how the content of the page scrolls, but everything else stays put.

How we code the CSS to style these two layers depends on the browser being used. The overall solution involves using two methods. The first is for browsers that implement the latest W3C CSS specs. Those that do allow us to use fixed positioning. Those that don't (i.e. IE) need to use the other method, which involved dynamic properties. The combination of both techniques means we have a solution for "all" browsers. Well, the more up-to-date ones at least. I've tested this in IE, Firefox and Safari with success. Are there any others we need to worry about?

Here's how you do it the simple CSS way:

#fixed{
position:fixed;
height:95px;
}

#scrolls {
top:96px;
margin-top:100px;
}

Simple isn't it!? Wel l, there's a little more to it, but that's the crux and shouldn't really take much explaining.

The trouble is that Internet Exploere ignored position:fixed and so the layer continues to scroll. In come dynamic properties. Using an IE-only trick we can get it working in IE too. What we do is turn off the scrollbar for the whole page and then turn it on for just the scrollable layer. To turn off scrolling we use this CSS:

body{
overflow:expression("hidden");
}

Looks odd doesn't it? No need to fear though. The expression part simply computes the CSS for us and only takes effect in IE (other browsers just ignore it). The expression here simply computes to overflow:hidden. All other browsers will ignore this rule and revert to the default for overflow, which is to scroll.

Now nothing on the page will scroll at all. So we need to turn scrolling on for the lower part. Here's the code to do that:

#scrolls {
position:expression("absolute");
top:96px;
overflow:expression("auto");
height:expression(document.body.clientHeight-97);
}

Notice all the expression()s we've used? All these styles will apply only in IE. What we've done here is force the scrolling layer to appear scroll when it needs to (overflow:auto) and made it appear far enough down the screen to be below the fixed layer.

Expressions can be quite powerful. See how I've used one to make the scrolling layer tall enough to fit in the available height. We can use simple maths and the available DHTML properties to make the CSS truly dynamic.

Seeing It For Yourself:

As with all the article I write it comes with a sample database. You can download it here. In the design there's a Page called extras.css. This is where all the important CSS lives. All that in global.css you can ignore.

Summary:

So, there you go. A fairly simple cross-browser method of keeping elements fixed at the top of a page. Of course they don't have to be at the top. You can fix things to the bottom or either side too. You can even have more than just buttons in the fixed section. How about adding some meta data from the document, such as author and creation date?

You might be dissappointed that I'm not actually talking about Action Bars and Action buttons. If you want to keep these on your web page then you're braver than I. My advice is to avoid using Actions on the web. Code all the buttons yourself instead.