W3CWD-positioning-970131


Positioning HTML Elements
with Cascading Style Sheets

W3C Working Draft 31-Jan-1997

This version:
http://www.w3.org/pub/WWW/TR/WD-positioning-970131.html
Editor:
Robert Stevahn, Hewlett Packard Co.
Authors:
Scott Furman, et.al., Netscape Communications Corp.
Scott Isaacs, et.al., Microsoft Corp.

Status of this document

This document is an intermediate draft produced by the W3C HTML Editorial Review Board as part of the Stylesheets Activity; it is stable enough to be released for public comment (to www-style@w3.org) but may change before approval as (part of) a recommendation. Hence it should not be implemented as part of a production system, but may be implemented on an experimental basis.

This is a W3C Working Draft for review by W3C members and other interested parties. It is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to use W3C Working Drafts as reference material or to cite them as other than "work in progress". A list of current W3C technical reports can be found at http://www.w3.org/pub/WWW/TR. Since working drafts are subject to frequent change, you are advised to reference the latter URL, rather than the URL for this working draft.


Abstract

The HyperText Markup Language (HTML) is a simple markup language used to create hypertext documents that are portable from one platform to another. HTML documents are SGML documents with generic semantics that are appropriate for representing information from a wide range of applications. CSS (Cascading Style Sheets) is a style sheets language that can be applied to HTML to control the style of a document: which fonts and colors to use, how much white space to insert, etc. The following specification extends CSS to support the positioning and visibility of HTML elements in three-dimensional space. Familiarity with both CSS1 and HTML 3.2 are assumed.


Contents

Abstract
Contents

1 Introduction
2 Positioning Elements by example
2.1 'Absolute' Positioning
2.2 'Relative' Positioning
2.2.1 Moving relatively positioned elements
2.2.2 Placing 'absolute' positioned elements relative to the flow
2.3 'Static' Positioning
2.4 Floating elements
2.5 Visibility
2.6 Z-order
3 CSS Positioning Properties
3.1 'position'
3.1.2 The <BODY> element
3.2 'left', 'top'
3.3 'width', 'height'
3.4 'clip'
3.5 'overflow'
3.6 'z-index'
3.7 'visibility'


1 Introduction

The inability to explicitly control the positions of HTML elements has become a stumbling block for producing rich static HTML documents. There is an even greater need for powerful layout control to enable dynamic, animated HTML-based content. This document describes extensions to CSS that allow authors to exercise greater accuracy in page description and layout for both purposes.

This document introduces two methods of positioning HTML elements using the new 'position' property: 1) 'relative' positioning may be offset relative to their natural position in the document's flow, and 2) 'absolute' positioning may be positioned arbitrarily. These elements establish a new context for the flowing of contained HTML elements, and establish a coordinate system for positioning of child elements. The examples below will clearly demonstrate these features. Dynamic aspects of managing positioned elements such as hiding, displaying and movement can only be performed using an external scripting language.


2 Positioning Elements by example

Positioning elements are specified using the new 'position' property. Let's examine each of the 'position' property's possible values. Most of the examples below utilize the following HTML:

<body>
<p>Beginning of body contents.
<span id=outer> Start of outer contents.
<span id=inner> Inner contents.</span>
End of outer contents.</span>
End of body contents.
</p>
</body>

Each example will define outer and inner differently.

2.1 'Absolute' Positioning

Elements with 'absolute' positioning are rectangular areas into which the contents of the positioned element will flow. An 'absolute' positioned element and its parent element are laid out independently, without regard for each others' dimensions or position. For that matter, the layout of each 'absolute' positioned element is independent of any others. The contents of an element with a higher z-order may obscure the contents of a element with a lower z-order. 'Absolute' positioned elements know nothing about one another. By default, a positioned element will be placed just above (in z-space) its parent.

Example 1

Consider the following definitions of outer and inner:

#outer {position:absolute; top: 200px; left: 200px; color: red;}
#inner {color: green;}

This results in something like the following:

(0,0)
+----------document window----------+(400,0)
|Beginning of body contents. End of |
|body contents.                     |
|                                   |
|                                   |
|                                   |
|                                   |
|                +-----------------+|
|                |Start of outer   ||
|                |contents. Inner  ||
|                |contents. End of ||
|                |outer contents.  ||
|                +-----------------+|
|                                   |
|                                   |
+-----------------------------------+(400,400)
(0, 400)

'Absolute' Positioned have the following characteristics:

2.2 'Relative' Positioning

'Relative' positioning contents are flowed into the parent element just like any other HTML. This type of positioning allows an element to retain its "natural" formatting, while supporting features similar to 'absolute' positioned elements, such as:

Like 'absolute' positioned elements, 'relative'ly positioned define a new coordinate system for child elements, with the origin located in the position where the first child element is rendered. Consider the following example:

Example 2

#outer {position: relative; color: red;}
#inner {position: absolute; top: 200px; left: -100px; height: 130px; width: 130px; color: green;}

This results in something like the following:

(0,0)
+----------document window----------+(0,400)
|Beginning of body contents. Start  |
|of outer contents. End of outer    |
|contents. End of body contents.    |
|                                   |
|                                   |
|                                   |
|                  +----------+     |
|                  |Inner     |     |
|                  |contents. |     |
|                  |          |     |
|                  |          |     |
|                  +----------+     |
|                                   |
|                                   |
+-----------------------------------+(400,400)
(400,0)

2.2.1 Moving relatively positioned elements

When 'top' and/or 'left' properties are used in conjunction with a 'relative' positioned element, the contents are offset relative to its original position, rather than being positioned relative to the parent coordinate system as with 'absolute' positioned elements. The element keeps its original, "flowed" shape. Thus, any line breaks will be retained when the 'relative'ly positioned element is moved. Dynamic movement of 'relative'ly positioned elements can provide animation effects in scripting environments. Static positioning can be used as a general form of super- and subscripting, although the line height will not be automatically adjusted to take the positioning into consideration. Consider the following example:

Example 3

In the <HEAD>: <STYLE TYPE="text/css"> BODY {line-height: 200%} </STYLE>

#outer {position: relative; top: -12px; color: red;}
#inner {position: relative; top: 12px; color: green;}

This results in the outer text being superscripted, while the inner text is subscripted relative to the outer text (but even with the normal body text). In the illustration below, the numbers to the left of the illustration indicate the normal position of the double-spaced lines.

 +----------document window----------+
 |                            Start  |
1|Beginning of body contents.        |
 |of outer contents.                 |
2|                   Inner contents. |
 |End of outer contents.             |
3|                       End of body |
 |                                   |
4|contents.                          |
 |                                   |
5|                                   |
 |                                   |
6|                                   |
 |                                   |
7|                                   |
 |                                   |
 |                                   |
 +-----------------------------------+

2.2.2 Placing 'absolute' positioned elements relative to the flow

Using 'auto' for the value of the 'top' property, an 'absolute' positioned element may be used to display change bars as follows:

Example 4
<SPAN STYLE="position: relative; left: 10px;">
I used two red hyphens to serve as a change bar. They
will "float" to the left of the line containing the following
<SPAN STYLE="position: absolute; left: -10px; color: red;">--</SPAN>
word.</SPAN>

This might result in something like:

+----------document window----------+
|   I used two red hyphens to serve |
|   as a change bar. They will      |
|   "float" to the left of the line |
|-- containing the following word.  |
|                                   |
|                                   |
|                                   |
|                                   |
+-----------------------------------+

2.3 Static Positioning

'Static' positioning is identical to normally rendered HTML. These elements cannot be positioned or repositioned, nor do they define a coordinate system for child elements. This is the default value for 'position', except for the <BODY> element, which, while it cannot be positioned, does define a coordinate system for child elements.

Example 5

Compare this example to Example 2. The only difference in the CSS is that in this case the outer element is static, rather than in-flow.

#outer {/* position: static; */ color: red;}
#inner {position: absolute; top: 200px; left: -100px; height: 130px; width: 130px; color: green;}

Since the static element does not establish a new coordinate system, the inner element is positioned relative to the <BODY> element:

(0,0)
+----------document window----------+(0,400)
|Beginning of body contents. Start  |
|of outer contents. End of outer    |
|contents. End of body contents.    |
|                                   |
|                                   |
|                                   |
|------+                            |
|r     |                            |
|ents. |                            |
|      |                            |
|      |                            |
|------+                            |
|                                   |
|                                   |
+-----------------------------------+(400,400)
(400,0)

2.4 Floating elements

Floating "elements" can already be created using CSS1, as demonstrated by the following example. We anticipate future extensions to the 'float:' property to allow more flexibility in flowing text around elements.

Example 6

#outer {color: red;}
#inner {float: right; width: 130px; color: green;}

(0,0)
+----------document window----------+(0,400)
|Beginning of body contents. Start  |
|of outer contents. End+-----------+|
|of outer contents.    |Inner      ||
|End of body contents. |contents.  ||
|                      +-----------+|
+-----------------------------------+

2.5 Visibility

The 'visibility' property determines whether or not an element is initially displayed. In scripting environments, this property can be dynamically modified to hide or show an element. Unlike 'display: none', elements that are not visible still take up space--they are simply rendered transparently. Example:

Example 7
<P>Choose a suspect:</P>
<DIV ID="container1" STYLE="position:relative">
   <IMG WIDTH=100 HEIGHT=100 SRC="suspect1.jpg">
   <P>Name: Al Capone</P>
   <P>Residence: Chicago</P>
</DIV>

<DIV ID="container2" STYLE="position:relative">
   <IMG WIDTH=100 HEIGHT=100 SRC="suspect2.jpg">
   <P>Name: Lucky Luciano</P>
   <P>Residence: New York</P>
</DIV>

<FORM NAME="myForm">
   <INPUT TYPE="button" VALUE="Capone" onClick='show("container1");hide("container2")'>
   <INPUT TYPE="button" VALUE="Luciano" onClick='show("container2");hide("container1")'>
</FORM>

Pressing either form button invokes a user-defined script function that causes the corresponding element to become visible and the other element to be hidden. Because the elements positioning is 'relative', they have no effect on the document's layout. The HTML contained in each element is laid out within the flow of the enclosing block, just as it normally is. A more visually appealing version of the above might be designed using overlapping 'absolute' positioned elements:

Example 8
<BODY>
<STYLE type="text/css">
<!--
   #container1 { position: absolute; top: 2in; left: 2in;}
   #container2 { position: absolute; top: 2in; left: 2in; visibility: hidden;}
-->
</STYLE>

<P>Choose a suspect:</P>
<DIV ID="container1">
   <IMG WIDTH=100 HEIGHT=100 SRC="suspect1.jpg">
   <P>Name: Al Capone</P>
   <P>Residence: Chicago</P>
</DIV>

<DIV ID="container2">
   <IMG WIDTH=100 HEIGHT=100 SRC="suspect2.jpg">
   <P>Name: Lucky Luciano</P>
   <P>Residence: New York</P>
</DIV>

<FORM NAME="myform">
   <INPUT TYPE="button" VALUE="Capone" onClick='show("container1");hide("container2")'>
   <INPUT TYPE="button" VALUE="Luciano" onClick='show("container2");hide("container1")'>
</FORM>

In this example, 'container2' has the same origin as 'container1', and it occupies the same area. Note also that the visibility property has been used to specify that 'container2' is initially invisible. The scripted event handler of the 'Capone' button can hide 'container1' and show 'container2'. Since the containers occupy the same position, and are the same size, the effect is that of one replacing the other.

2.6 Z-order

By default, the z-ordering of elements in a document is back-to-front in the order they appear in the HTML. In Example 8, therefore, 'container2' will be stacked immediately above 'container1', since it appeared after 'container1' in the document. It is possible to explicitly specify a element's z-order, relative to other containers, through the 'z-index' property. For example:

Example 9
<STYLE type="text/css">
<!--
.pile { position: absolute; left: 2in; top: 2in; width: 3in; height: 3in; }
-->

<IMG SRC="butterfly.gif" CLASS="pile" ID="image" STYLE="z-index: 1">

<DIV CLASS="pile" ID="text1" STYLE="z-index: 3">
   This text will overlay the butterfly image.
</DIV>

<DIV CLASS="pile" ID="text2" STYLE="z-index: 2">
   This text will underlay text1, but overlay the butterfly image
</DIV>

In this example, the order of the elements, listed back-to-front is:

Example 9 also demonstrates the notion of transparency. The default behavior of an element is to allow elements below it to be visible through transparent areas in its HTML content. In this example, each element transparently overlays the elements below it. This behavior can be overridden by utilizing one of the existing background-related properties like 'background'.


3 CSS Positioning properties

This section utilizes the same notation for property values as the CSS1 Specification to describe the new CSS properties.

3.1 'position'

Value: absolute | relative | static
Initial: static
Applies to: all elements
Inherited: no
Percentage values: N/A

Each variety of 'position' establishes one or more of the following:

'Absolute' Positioned elements fall outside of the CSS1 Formatting Model. 'Absolute' positioned are neither block-level, list-item, floating nor inline elements. Instead, elements positioned with type 'absolute' are formatted independently of all other elements in a rectangular container.

'Relative' Positioned elements have their origin located at the top-, leftmost extent of the first rendered line of the element's contents. Subsequent lines of the 'relative'ly positioned element may extend to the left of the origin (such as when the element's contents start in the middle of a line).

3.1.2 The <BODY> Element

The <BODY> element defines a special implicit container having the following properties:

3.2 'left', 'top'

Value: <length> | <percentage> | auto
Initial: auto
Applies to: elements with the 'position' property of type 'absolute' or 'relative'.
Inherited: no
Percentage values: refer to parent element's width and height. If parent's height is set to 'auto', percentage is undefined.

For elements with 'absolute' positioning, 'left' and 'top' are relative to the origin of the nearest element with 'position' of value 'absolute' or 'relative'.

For elements with 'relative' positioning:

The default value ('auto') is the element's normal position in the flow. This value is calculated by the UA for positioned elements, and is 0 (no offset) for 'relative' positioned elements.

3.3 'width', 'height'

Value: <length> | <percentage> | auto
Initial: auto
Applies to: block-level and replaced elements, elements with 'position' property of type 'absolute'
Inherited: no
Percentage values: refer to parent element's width and height. If parent's height is 'auto', percentage of height is undefined.

For elements with 'position' of type 'relative' and 'static', the behavior of 'width' and 'height' is unchanged from that defined by the CSS1 formatting model.

For 'absolute' positioned elements:

3.4 'clip'

Value: <shape> | auto
<shape>: rect (<top> <right> <bottom> <left>)
<top> <right> <bottom> <left>: auto | <length>
Initial: auto
Applies to: elements with the 'position' property of type 'absolute'.
Inherited: no
Percentage values: N/A

Clipping alters the display of HTML, though it does not affect how it is laid out. The clipping region defines that part of the element that is visible. It is computed by the intersection of the parent's clip region with the value of a element's 'clip' and 'overflow' properties. Any part of an element that is outside its clipping region, including its border and padding, is transparent.

Coordinates are with respect to the element's origin. Negative coordinates are permitted. When converted to pixel coordinates, the bottom-right corner is excluded from the clipping rectangle. This rule is necessary to permit the definition of zero-width or zero-height rectangles.

Any coordinate can be replaced by the value 'auto', which causes the clipping rectangle to match the element's extent in the given direction, including padding, borders and child elements. The default value for the 'clip' property causes the clip rectangle to cover the entire element.

For now, all clipping regions are rectangular. We anticipate future extensions to permit non-rectangular clipping.

Note: If the clipping region exceeds the bounds of the UA's document window, contents may be clipped to that window by the native operating environment.

3.5 'overflow'

Value: none | clip | scroll
Initial: none
Applies to: elements with the 'position' property of type 'absolute' or 'relative'.
Inherited: no
Percentage values: N/A

'Overflow' determines what happens when an element's contents exceed its height or width. A value of 'none' indicates that no clipping is to be performed. For example, preformatted text that extends past the right edge of an element's boundaries would be rendered anyway. A value of 'clip' indicates that clipping should be performed with no scrolling mechanism. The behavior of the 'scroll' value is UA-dependent, but should cause a scrolling mechanism to be invoked.

Note: Even if 'overflow' is set to 'none', contents may be clipped to a UA's document window by the native operating environment.

3.6 'z-index'

Value: auto | <integer>
Initial: auto
Applies to: elements with the 'position' property of type 'absolute' or 'relative'.
Inherited: no
Percentage values: N/A

The 'z-index' property is used to specify the stacking order of elements, overriding the default behavior, which is to stack them bottom-to-top in the order they appear in the HTML source. The 'z-index' property allows an element's z-order to be given as an integer that specifies stacking order relative to sibling and parent elements:

The relative z-ordering between two elements that are not neither siblings nor parent/child can be determined by evaluation of the above rules for both elements' ancestors.

3.7 'visibility'

Value: inherit | visible | hidden
Initial: inherit
Applies to: all elements
Inherited: if value is 'inherit'

Visibility determines the initial display state of an element, but does not affect its layout. Elements that are hidden still take up the same physical space as they would were they visible, they are just rendered transparently. This differs from the behavior of 'display: none', in which the element is ignored, as if it were not present in the document at all. Visibility can be used in a scripting environment to dynamically display only one of several elements which overlap one another.


Robert Stevahn