logo

Faking Action Bars With CSS

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.

Feedback

  1. 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.

      • avatar
      • Jake Howlett
      • Fri 1 Jul 2005

      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.

      Show the rest of this thread

  2. Awesome

    It's working great in FF, but check out what I get in IE:

    http://communityfirst.cc/chris/blog/scrolltest.JPG

    See the IE Native scroll bar on the far right? That won't go away. Here's my scroll div:

    #scrolls { position:expression("absolute"); top:31px; left:0px; margin-right:5px; overflow:expression("auto"); height:600px; padding:10px; height:expression(document.body.clientHeight); width:expression(document.body.clientWidth); margin-top:30px; margin-top:expression("0px"); }

    I even left that div completely like you have in your code with no luck...

    Thanks - something I just never thought of doing!

      • avatar
      • Jake Howlett
      • Fri 1 Jul 2005

      Re: Awesome

      How did you get code in to your new database? Did you copy it all over? It looks like it's missing this declaration:

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

      Show the rest of this thread

  3. 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!

  4. 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!

    -rich

      • avatar
      • Jake Howlett
      • Tue 5 Jul 2005

      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.

    1. 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!

      Chris

    • avatar
    • Karen
    • Tue 5 Jul 2005

    Error on example page

    "General Error Unfortunately the following error occurred: HTTP Web Server: Invalid URL Exception"

    When viewing the example page in Firefox 1.0.4

      • avatar
      • Jake Howlett
      • Tue 5 Jul 2005

      Thanks. Fixed now

    • avatar
    • Rod Stauffer
    • Wed 6 Jul 2005

    Very nice. Watchout for printing though...

    There's always a catch isn't there.

    position:fixed elements are displayed on every page. Not really noticable in a browser as a single page just scrolls. Printing changes things as multiple pages are definitely possible.

    The result in this example is a header of sorts. Unfortunately, this header effect takes precendence over content "under" it--some content is hidden by the "header."

    Try a print preview to see the problem. For me (with Firefox), page 2 ends with: "Chyba, że ze stołka!" The first document listed on page 3 is: "Look at this"

    The position:fixed header essentially hides two documents on any page after the first one. CSS specifically for printing should avoid the problem (i.e. media="print")

    Side effects like these are something to be aware of anytime position:fixed is used and there's any chance the page will be printed. I learned the hard way of course. :-)

    In any case, nice write Jake. Good stuff.

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

      Just began implementation...

      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:

      "TOPMARGIN=\"0\" LEFTMARGIN=\"0\" MARGINHEIGHT=\"0\" MARGINWIDTH=\"0\""

      to my HTML Body Attributes.

      Thanks again - I've used a good bit of tips/code from your site Jake!

      • avatar
      • Jake Howlett
      • Wed 6 Jul 2005

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

      Interesting. This of course could be used to our advantage. Using:

      @media print{ }

      We can show headers on printed pages.

      Or we can use:

      @media screen{ }

      To hide fixed DIVs from the printed page.

  5. 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?

      • avatar
      • Jake Howlett
      • Wed 6 Jul 2005

      Re: Printing not getting more than one page

      Weird. I thought hiding the extras.css page from "media print" would fix this, but it doesn't. Don't have time to investiage this right now, but I'll try and remember to soon...

      Show the rest of this thread

    • avatar
    • paul
    • Thu 7 Jul 2005

    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.

    • avatar
    • Ravi
    • Thu 28 Jul 2005

    Problem with another DIV on form

    Hi,

    I am using the web datepicker from http://nsftools.com/tips/DatePickerTest.htm

    When I try to lock the action bar, the date picker popup in the scrolls is not displayed properly. Is it to do with postioning of layer?

    1. Re: Problem with another DIV on form

      Ravi et al

      did you get this problem with another div and the datepicker sorted?

      Thanks

  6. Anyone solved the printing issue?

    Hi

    this is fantastic. The only problem is the printing issue where it only prints one page. Has anyone managed to find a workaround as yet?

    Cheers Kerry

      • avatar
      • Roger J
      • Thu 15 Dec 2005

      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...)

      Omitting media means media=all

      Show the rest of this thread

    • avatar
    • Komix
    • Wed 17 Aug 2005

    what about CSS in R5 Domino Server

    How can I implement this great solution in database on R5 domino server? I want to know how can I store CSS or use it for form?

      • avatar
      • Jake
      • Wed 17 Aug 2005

      Re: what about CSS in R5 Domino Server

      You can store the CSS in a Page.

  7. Fixed header table

    How do you fix the table header using css in a browser independent way?

    Thank you so much, Mikhail

  8. 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?

    http://nicophoto.com/scroll.html

    Thanks! Nico

      • avatar
      • Jake Howlett
      • Mon 19 Sep 2005

      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.

      HTH Jake

      Show the rest of this thread

  9. 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!

    1. Re: More IE Problems...

      For now, I have modified my form to have 4 instead of 2 columns to move fields up the screen. I'm also maximizing the browser with:

      window.moveTo(0,0); window.resizeTo(screen.availwidth,screen.availheight);

      This isn't a fix, but should provide a decent workaround.

  10. Faking Action Bars With CSS for Dummies

    Hello!

    I'm still learning the basics of html.

    Can anyone please write the full code of a basic example?

    I was following this article and the code I wrote isn't functioning. What am I doing wrong?

    Thank you!

    My code:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <title>Untitled Document</title>

    <style type="text/css">

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

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

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

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

    </head>

    <body> <div id="container">

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

    <div id="scrolls"> <p>This is the content of the page. </p> <p>&nbsp;</p> <p>&nbsp;</p> <p>asdffadf</p> <p>&nbsp;</p> <p>&nbsp;</p> <p>&nbsp;</p> <p>asdfasd</p> <p>&nbsp;</p> <p>&nbsp;</p> <p>&nbsp;</p> <p>asdf</p> <p>&nbsp;</p> <p>&nbsp;</p> <p>asdf</p> <p>&nbsp;</p> <p>&nbsp;</p> <p>asdf</p> <p>&nbsp;</p> <p>asdf</p> <p>&nbsp;</p> <p>&nbsp;</p> <p>asdf</p> <p>&nbsp; </p> </div>

    </div> </body>

    </html>

  11. 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).

      • avatar
      • Jake
      • Mon 19 Dec 2005

      Re: Examples works for Firefox, but not for IE6

      You're right Tony. Same here. How odd!

      I'll have a look and see what it might be...

      Show the rest of this thread

  12. 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%.

    Thanks for any help, greetings to all, Boyzl

      • avatar
      • Boyzl, Slovenia
      • Thu 19 Jan 2006

      Re: problems with downloaded DB

      sorry, typo... it DOES work fine when i open your online example... sometimes hard to think and write in other language at the same time with LN problems lol

      • avatar
      • Jake
      • Thu 19 Jan 2006

      Re: problems with downloaded DB

      Hi Boyzl,

      It shouldn't be anything to do with the server version. I can't think why your scroll area would be empty.

      Sorry, Jake

      Show the rest of this thread

    • avatar
    • Josh
    • Tue 13 Nov 2007

    Problem with demo 1.1

    demo 1.1 work in firefox 2, but not in IE7. (bad)

    demo 1.0 work in firefox 2, and in IE7. (good)

  13. Nice tip, but...

    Hello!

    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?

    Thanks & keep up the good work!

    Steve in NYC

    "It hurts to be on the cutting edge."

Your Comments

Name:
E-mail:
(optional)
Website:
(optional)
Comment:


Navigate other articles in the category "Miscellaneous"

« Previous Article Next Article »
Managing Domino File Resources Using WebDAV   Searching Domino Simplified

About This Article

Author: Jake Howlett
Category: Miscellaneous
Keywords: CSS; Actions; Buttons;

Attachments

actionbar-v1.0.zip (179 Kbytes)
actionbar-v1.1.zip (180 Kbytes)

Options

View Online Demo
Feedback
Print Friendly

Let's Get Social


About This Website

CodeStore is all about web development. Concentrating on Lotus Domino, ASP.NET, Flex, SharePoint and all things internet.

Your host is Jake Howlett who runs his own web development company called Rockall Design and is always on the lookout for new and interesting work to do.

You can find me on Twitter and on Linked In.

Read more about this site »