SiteExperts.com Logo Home | Community | Developer's Paradise | Jobs
User Groups | Site Tools | Site Information | Search

Inside Technique : DHTMLLib 2.0 : CSS-Positioning

Examining the positioning features, for cross-browser DHTML, limit yourself to DIV, SPAN, and TABLE elements and don't put position elements in FORMs. When scripting, you know you can reposition and resize elements, change the background colors, and change the contents. With a little browser detection you should be all set. Unfortunately that is not true. Before we even get to event tracking, there are a number of cross-browser issues you need to be aware of. These are the issues that are most prevalent and this list is by far not complete.

The Default Width

When positioning an element, if you don't specify a width the browser will determine a width for you. In Internet Explorer, DIV and SPAN elements have their width default to the width of the window. In Netscape Navigator, the width defaults to the width of the contents. This difference can become apparent if have a background color and can even make pages to seem broken in certain circumstances, especially in Internet Explorer.

For example, if you position a DIV without an explicit width the width becomes the width of the window. If you do not have a background color or border you may not realize this has happened. However, if you had an link on the page (not positioned) that is overlapped by this DIV, you will not be able to click on the anchor. This is because the DIV by default appears above the text on the page. Since the link is behind the DIV, you are always clicking on the DIV and not the anchor. If you ever have a page with positioned elements, and links do not seem to work (and when over the link you are not seeing the correct hand cursor), you should add background colors to all your positioned elements and check if they overlap the link. If you are seeing the correct hand cursor the problem is probably unrelated to the positioned element and you should check if your scripts are cancelling the links default action.

In general, when positioning a DIV or SPAN you should always specify the element's width. If you want the size of the element to be automatically calculated, their is an easy work-around. TABLE elements are defined to automatically size themselves to their contents. Positioning a table element has the same effect. Therefore, when you want the positioned element to automatically size itself, position the TABLE. The table needs to be properly creates so do not forget to add the TR and TD element inside of the table (you can have as many rows and columns as you want). This causes Internet Explorer to size the contents, and causes no change in layout in Netscape as Netscape uses the same layout mechanism for positioning the TABLE as they do for the DIV and SPAN.

Before you go and decide to use table's everywhere, we have had trouble changing the contents of the positioned table in Netscape nor does DHTMLLib support it. Therefore, if you must be able to rewrite the contents and be cross-browser, you should restrict yourself to positioning DIV and SPAN elements and define a fixed width.

[Width Demonstration]

Clipping versus Sizing

On the previous page, I made an elusive statement about Netscape allowing you to change the clipping size of elements and said I will mention it later. Well, now is later and this is a fairly important difference. Netscape does not let you do anything through script that will change the flow of the document's existing content. Flow means anything that will cause other contents to change (for an example of reflow, if you resize your window and the words rewrap, you are changing the flow). While you can manually cause a page to reflow by resizing the window, you have no such control from script.

What this means for positioned elements is that you can't change the width and height of an element to cause the contents to relayout. Instead, when you change the width and height in Netscape, you are only clipping the contents. This means that some of the contents are no longer visible. In CSS-speak, you are changing the CSS clip property, not the CSS width or height. In Netscape, if the contents don't fit, they are always clipped.

Internet Explorer, on the other hand, allows you to change both the clip property and the width and height. Changing the width of an element causes the contents to rewrap to the new size. Changing the height of an element may or may not effect the element depending upon the CSS overflow attribute. The CSS overflow attribute defines what happens if the contents don't fit to the specified size. For example, you can have scrollbars appear (overflow: scroll or overflow: auto). In addition, you can clip the contents like in Netscape.

This means in Internet Explorer you can define a width and height, have scrollbars appear, and then clip the contents so only a portion of the scrollbars and contents are visible. You can then later through script change the size causing the contents to flow differently removing the scrollbars, and then change the clip property to change the contents being viewed. In Netscape, you can only define an initial size, and then later change what portion of the content is being viewed. Scrollbars on positioned elements are currently not supported in Netscape.

When writing cross-platform scripts, there is a different between Internet Explorer for Windows and for the Macintosh. On the Macintosh, the clip attribute is not supported. Using this attribute or setting its properties does not cause any errors, but depending on your script you may need to add some special code. The next page is an example of a sliding menu. The slide is created using the clip property. On Internet Explorer for the Macintosh, we added code to make the menu appear and disappear without the animation.

Netscape Resize Issue

This is a fairly well-known problem where Netscape usually falls apart when a page is resized with positioned elements. Netscape has a tendency to lose the position information causing script errors when the window is resized. The general fix is to grab the resize event and force the page to reload. While this causes all positioned elements to reposition themself, they are repositioned at their initial location and all script state is lost. A better fix, when available, is to always open pages that use css-positioning in a non-resizeable window.

WebReference's DHTMLLab has a solution that does not reload the page on every resize. However, when testing this solution we have found cases where it did not seem to lose the positioned state, but our scripts stopped running correctly (mostly timer related scripts). Therefore, our recommended approach is still to reload() the page.

Stylesheets and Positioned Elements

In theory, the use of CSS-Positioning should not effect the application of other CSS properties to elements. For the most part, CSS works as advertised in Internet Explorer 4.0. Unfortunately we have had significant problems with CSS in Netscape, especially with CSS positioned elements and standard tables. We have had limited success by ensuring that any CSS that should apply inside of a CSS-Positioned element includes the positioned element in the declaration. For example:

<STYLE>
  P, #div1 P {color: red} /*Also scope the style to the positioned element *?
</STYLE>
<DIV ID="div1" STYLE="position: absolute">
  <P>Red!
</DIV>

The only advice we can give for cross-browser CSS is to test your pages. In absence of diligent testing, we have found our best results by limiting ourselves to using in-line styles (the style attribute directly on the element). Unfortunately this advice does remove most of CSS's value.

Positioned Elements Background Color

Giving a positioned element a particular background color is a very simple task. This should just work, right? Unfortunately, as you can probably now guess, this is another area where you need to do a very little extra work. The background color on positioned elements should apply to background of the entire region. Netscape incorrectly applies the background color only to the individual words. However, Netscape has defined their own proprietary CSS property for solving this problem, background-layer-color. So, if you need a background color on a positioned element, you need to define it twice - once using the real CSS background property, and a second time for Netscape:

<DIV ID=div1 STYLE="position: absolute; layer-background-color: red; background: red">
  Make me red!
</DIV>

Nested Positioned Elements

This is another area where our recommendation is lots of testing or to avoid in Netscape. With CSS-Positioning you can position an element within another positioned element. This appears to work well in Internet Explorer but we have had a number of problems with Netscape. While this appears reasonably stable when defined directly within the HTML using in-line styles, trying to dynamically write the positioned elements into the page usually spelt disaster for scripts and the positioned elements.

If you do use nested elements, you are creating a hierarchical programming model in Netscape. This is one of the areas where DHTMLLib goes a long way for simplifying your scripting and is one of the major reasons we chose to simulate Internet Explorer's object model for scripting. In Internet Explorer (and with DHTMLLib) you can either access the element directly through the all collection, or you can walk the containership hierarchy of elements.

Setting the Z-Index Property

According to CSS, when no z-index is specified, absolutely positioned elements default to a z-order above the text. However, we have found that Internet Explorer for the Macintosh tends to put absolutely positioned elements behind the text. Therefore, whenever positioning elements, we recommend you explicitly supply a z-index even if it is as simple as setting them all to 1. Internet Explorer for Windows and Netscape Navigator (Mac and Windows) interpret the lack of a z-index correctly. We found this issue with our menu code where on the Macintosh version of Internet Explorer, the menu rendered behind images and text (fixed by adding an explicit z-index).

However, only Internet Explorer supports putting a positioned element behind the text (on windows, you use a negative z-index). On Netscape, positioned elements always appear on top of the text.

Sliding Menu Demonstration

Before we continue we want to give you a quick demonstration to show you that, yes, lots can be easily accomplished even with these limitations. We show you how to use the clip property to create an animated menu.

[Sliding Menu]