13.5 Adjusting Positioned Element Stacking Order (z-order)
NN 4, IE 4
13.5.1 Problem
You want to control
the way an overlapping element appears in front of or behind another
element.
13.5.2 Solution
You can either use the setZIndex(
) function from the DHTML library
(Recipe 13.3) for backward-compatibility or, for all browsers that
support the style property of elements, adjust the
style.zIndex property directly:
document.getElementById("myLayer").style.zIndex = "100";
13.5.3 Discussion
Turning an element into a positioned element automatically raises it
to a layer in front of the main document content. Unless the
background of a layer is set to a color or image, the
element's background is transparent by default,
allowing content underneath to be visible in the blank spaces.
If the stacking order of a positioned element
doesn't have to change during user interaction with
the page, you can simply set the initial value via the CSS
z-index property and be done with it. But there
are times when scripts need to adjust the stacking order. For
example, if you have multiple draggable elements on the page (see
Recipe 13.11), you must ensure that the element being dragged is in
front of all other elements, including other positioned elements.
Otherwise the dragged item will submarine beneath other positioned
elements and befuddle the user. Once dropped behind other items, the
element may be lost.
Stacking
rules are pretty simple. If any two elements have the same
z-index value, the elements stack in source code
order, with the element that comes later in the source code appearing
in front of the earlier item. The default CSS
z-index value for a positioned element is
auto, which equates to zero. A negative value does
not layer the element behind the main content. An element with a
higher z-index value appears in front of elements
with lower numbers. Thus, you can control the layering regardless of
source code order.
In the drag scenario just mentioned (and demonstrated in Recipe 13.11), the script that responds to the mouse event signaling the
activation of a draggable element should raise the
zIndex property value of the dragged element to a
number guaranteed to be higher than all others. There is no practical
limit to the value you assign. Therefore, it's not
uncommon to assign an arbitrarily high number, such as 100 or 1000,
to an item that must be in front of all others. But once the user
releases the dragged element, you need to restore the original value
(which you should have preserved in a variable or custom property for
later recall). This leaves room for the next dragged item to be
assigned that high number so it appears in front of all others.
Beware, however, of mixing positioned elements and form controls.
Except in the most recent browsers, you will encounter rendering
conflicts between layers and several types of form controls when the
layers are intended to overlap those controls. The most common
offenders are text-based controls, such as text
input elements, textarea
elements, and select elements (which frequently
use text-editing innards to display their content).
Unfortunately, when these conflicts arise, you can do nothing to make
the layer display in front of the form control. Even the biggest
number assigned to the zIndex style property
won't help. If you cannot rework the design so that
the overlap does not occur, the only workaround is to hide the form
controls whenever the layer is visible. The best way to do this is to
wrap the affected form in a relative-positioned
span, and then change its
style.visibility property as needed. This keeps
the rest of the page from shifting around when the controls hide or
show themselves.
13.5.4 See Also
Recipe 13.3 and its utility library for changing stacking order,
among other DHTML tasks.
|