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:

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.

Feedback

Good tip - interesting find

This is pretty cool. But I did notice something when playing around with it. In
Firefox, you must have the "background-color" defined for the "fixed" area or
else the main body will scroll "into" the fixed area. I can't explain why it's
that way. Go into your style sheet resource and remove the background color
definition for "#static" and you'll see what I mean.

Re: Good tip - interesting find

It kind of makes sense Matt. Assuming that the default background-color is
transparent and not white, this is what you'd expect to see. Maybe in IE the
default is white, whereas Firefox assumes that the fact that the colour is not
specified means it revert to no colour - or transparent. I've no evidence of
this though. I'm just hypothesising.

Confirmed

I just created a plain HTML file with a layer on it that had no style
associated with it. I then used the DOM Inspector to see what Firefox computed
the background-color to (select the layer and then choose "Computed Style" from
the drop-down. Sure enough it defaults to transparent.

Clean!

Very clean implementation, Jake.

Cleaner than this,
http://www.datatribesoftwerks.com/datatribe/DatatribeBlog.nsf/0/4549C08676C88BD0
85256D730007D295 ,
which uses a bit of javascript and is dated for mugh older standards. Your
version makes it much more reliable. Thanks!

Very nice. But how's this for a coincidence?...

I just commented yesterday on an article that Scott Good had posted a while ago.

http://www.scottgood.com/jsg/blog.nsf/plinks/SGOD-6C6Q7J

His article describes a way to use CSS to make Domino's butt-ugly HTML
translation (as opposed to the applet as you show in your graphic) of action
bars look pretty. My suggestion was to grab the outerHTML of the table
containing the action buttons and write it into the innerHTML of a div that is
held in a fixed position while the rest of the page scrolls. The thought
occurred to me, but I hadn't had the time to work out how to actually pull it
off with CSS, so I just posted it as a rough suggestion in a comment on Scott's
article.

I think that if we combine Scott's technique, your technique, and my idea all
together into one, then we have something that is even cooler!

Interesting and doable

There's no reason that can't be done. Once you've got hold of the Action table
you can move it to where you like. In this case simply
document.getElementById('fixed')

Still, I can't help thinking that's a lot of coding that can be done without.

The only reason I can see for using Action Buttons is that you can have one
button work in client and web without the need for recoding it. Unless I had to
use one form for Notes and web I'd avoid Action buttons - and always do.

Re: Very nice. But how's this for a coincidence?...

Jake & Richard,

Great idea...this works perfectly! I just completed an implementation of this,
grabbing the outerHTML of the action bar and hiding it, then putting it in a
div where I wanted it. Jake's article about positioning it was the final key I
was looking for (the IE part was throwing me off). Kudos to you both!

Re: Very nice. Watchout for printing though...

This is really useful. I've added it to about 6 forms already and it's very
portable.

Another gotcha is with radio buttons/checkboxes with the auto-refresh option
enabled. Simple workaround I found at LDD was to put in:

_doClick('$Refresh',this,null);

for my OnChange event for the radio button. What happened (ONLY in IE!) was
that the page would refresh and place focus at the radio button. This caused
the fixed portion at the top to "disappear". If you resized the window it would
"reappear". lol

Also, I noticed that I didn't like the margins that IE was putting in so I
added in:

Printing not getting more than one page

First off, let me say this is a great tool. It was perfect timing as I needed
to "freeze" soe header for a long report and this did the trick...sort of. It
seems as though printing using IE 6.02 does not show all of the pages; just the
first one. It does this on the example in the article. Just try to do
Print>Print Preview and only one page will display. Is there a way around
this?

Re: Printing not getting more than one page

works mostly in Mac IE 5.2 even

Cool technique.

I just looked at your test page in Mac Safari, it's perfect. In Mac IE 5.2 the
horizontal scroll bar shows up and won't go away. I don't have time to figure
that out, it's not a problem as it works well otherwise, but something to note
if you need to support that nasty platform.

Anyone solved the printing issue?

Re: Anyone solved the printing issue?

The way I solved it was to create two different CSS files; One for screen and
one for printer:
My <head> would look like this:
<LINK REL="stylesheet" HREF="/db.nsf/pgStyle.css" MEDIA="screen">
<LINK REL="stylesheet" HREF="/db.nsf/pgStylePrint.css" MEDIA="print">

In the CSS file for media print I removed the Scrolls and Static DIV's.

It's easy to forgett to write media="screen" for the CSS that should be used on
the screen! At least that is what I first did! (And wrongly cursed IE6 for...)

Re: Anyone solved the printing issue?

There's a bug in IE in which an element calculated through an expression for
screen overrides the element's property for printing. In the media print CSS,
use !important to override the screen setting.

Fixed header table

IE6 problems

I'm trying to make a super simple example page, and it works great in
everything except for IE6. I'm sure I'm just being a bonehead, but I can't for
the life of myself see the problem. Can anyone look at my HTML and point out
what I'm doing wrong?

Re: IE6 problems

In IE6 I don't see the content of the scroll layer. After some investigation I
noticed that the hieght of the "scrolled" layer was 0px. It turns out that
document.body.clientHeight is 95px. So you expression() returned a height of 0.

In IE6 in "standards" mode body.clientHeight returns the document. In your case
it's 95px and so the result will always be 0.

http://www.howtocreate.co.uk/tutorials/index.php?tut=0&part=16

Try:

height: expression(document.documentElement.clientHeight-95);

Or:

If you're a Domino developer, assume you won't be in standards mode and remove
the decleration from teh top of the HTML.

Re: IE6 problems

Hello Jake,

Thanks for looking at that and the suggestion to use:
(document.documentElement.clientHeight-95)

That indeed does make the top stay fixed in IE, and the bottom scrolls, but
it's pretty ugly. The scroll bar for the bottom div is inset inside where the
normal scroll bar would be.
http://nicophoto.com/scroll3.html

It looks better if I remove the docType and go back to using
document.Element.clientHeight, but it would be nice to have a docType on the
page.

Anyway, you've pointed me in the right direction. If anyone else can manage to
make my example with the docType look better, please show me how.

More IE Problems...

Trying to figure out the best way to describe this, but say someone opens the
form in IE (6) and there are some fields down the page that you would have to
scroll to.

The user is typing away and tabbing to the next fields. When you tab to a field
that is outside of the ui, the page focus is shifting down and it takes away
the action bar. I ran across the same problem with "refresh doc on keyword
change". The action bar would get lost because the page shifts down. I got
around this by using the following in OnChange instead of the refresh doc
parameter:

_doClick('$Refresh',this,null);

I'm going to look around for possible solutions, but it seems to be IE's way of
focusing the page when tabbing. It doesn't happen in FF - tabbing just scrolls
down as it should!

Examples works for Firefox, but not for IE6

As at 19 December 2005, I just tried the example page
(http://codestore.net/apps/actonbar.nsf/all?OpenView) and found that it works
fine with Forefox 1.5 however the action bar incorrectly scrolls out of sight
with IE 6.0.2900.2180 (at least it does on my system).

Re: Examples works for Firefox, but not for IE6

Re: Examples works for Firefox, but not for IE6

I'd forgotten about this but your reminder has just given me a flash of
inspiration - it seems to have stopped working since I turned off quirks mode
using the HTML header string. This has doubtless got something to do with it
and will give me a headstart when I get round to investigating it.

Re: **Solution**

Hi Jake,
I have downloaded the example and tested it, it does not work on IE6.0, the
action bar and footer are showing, but the main content of the embedded view
does not show up,
but if I test it in Natescape 6.0, it works. the thing is most of my client
are using IE6.0, so I have to make it working IE6.0.
Anything should i change the codes?

problems with downloaded DB

Hello from Slovenia!
I have funny problems with downloaded DB when i open it on my localy installed
Domino server (6.5.4). It doesn't work fine if I open your online example in my
IE (6.0.2900.2180.xpsp_sp2.gdr) on Intel/XP/SP2 comp, but on local server i get
nothing in "scroll" part, not even when trying to create a new doc. :-(
Am I missing something? Is it up to server version? I reallised it doesn't
render the div ID=content into HTML...

btw: there is a semicolon missing in extras, line 6, class container after
width:100%.

Re: problems with downloaded DB

Re: problems with downloaded DB

Eureka!
I admit it take me lots of testing and trying to find out where the heck the
problem is before searching for the right solution on the web at all, lol!
Problem was neither in your DB of course, nor in my "first try DB"...

Here it goes:

IE6 has some "decent" bugs, including a bug called "Unscrollable content bug".
(see link: http://www.positioniseverything.net/explorer.html).

Well, I was able to see your online DB OK, but downloaded copy on my local
server didn't render well in IE6 (not to talk about that source code from IE6
had some differences compared with source from FF1.5!). That let me think it
has something to do with Domino server versions though you didn't believe it
was an issue.

Finally I hit on a chain of articles (let's link just two):
- The Quirks of Quirks Mode
http://www.notestips.com/80256b3a007f2692/1/taio-65qg97
- Domino finally does the right DOCTYPE
http://www.notestips.com/80256B3A007F2692/1/TAIO-5V5LQN

...that let me know about Domino "bug" (or was it lunacy?) by which Domino
renders just DOCTYPE declaration in to HTML file, without URL! Which
subsequently causes IE to fall off into Quirk mode :-(((

Well, there is a "crutch" - since 6.0.5 and 6.5.3 you can use the ini parameter
DominoCompleteDoctype=1 to get the correct and complete DOCTYPE output by
Domino.

Yet another info (for those who are not system admins or gurus, like i am not):
You better don't edit notes.ini file in domino server root folder, won't work.
You have to do it via server's console with command:
set con DominoCompleteDoctype=1
and you can check if you were succesfull with:
sh con DominoCompleteDoctype

Restart server with "restart server" in console.... and that's pretty all.
Now your demo works (thanks to all above mentioned articles) and my page works
like i wanted (thanks to your working demo)!
Hope this will help other desperate (like i was) users.
Btw, which version of domino server is your demo DB on?

Expanding on this idea

I've implemented this solution for one of our apps. We had another requirement
though, to be able to move the actions from top to bottom. Also, I had no need
for the "static" div, but left it in on the off chance we may need it later.
Anyway, I used the following solution, and thought it may help others out....

Problem with demo 1.1

Nice tip, but...

Nice tip, and very close to what I need! I'm trying to find a way to
replace the yucky java applet in an application I've inherited, and this looks
good. I just have two little challenges:

1. some of the actions are categories for other actions. The java applet shows
them correctly (i.e. click the action, and more actions appear). How would we
do that?

2. I have a LOT of actions in my forms! When I put a lot of them with this
method, they appear on the next line. How can we show an arrow to scroll to
the left/right in the action menu like the applet does?