Chapter 9. Positioning
The
idea behind positioning is fairly simple. It allows you to define
exactly where element boxes will appear relative to where they would
ordinarily be -- or relative to a parent element, or another
element, or even to the browser window itself. The power of this
feature is both obvious and surprising. It shouldn't be too
surprising to learn that this is the part of CSS2 that user agents
usually first attempt to support. Given that there were some very
good positioning implementations on the horizon as the book was being
completed, we felt it worthwhile to give readers a glimpse of
what's coming soon -- or, if you're reading this book
a year or three after its publication, what can be done.
You may notice that, unlike other chapters, almost none of the
figures in this chapter was generated with a web browser. This is
something of a statement about the reliability and consistency of
positioning implementations at the time of this writing: not one of
them was solid enough to trust completely. It was actually easier to
draw theoretical examples by hand than to take screenshots in web
browsers and then retouch them in Photoshop.
This is also why this chapter is largely (but not entirely) free of
browser warnings and caveats. Rather than drown the explanatory text
in side notes, we have chosen to simply describe positioning as it is
given by the CSS2 specification and leave things there. Perhaps the
second edition of this book will contain more practical advice, but
at this time, the only practical advice we can give is this: test
your positioning code thoroughly, and be prepared for inconsistencies
between positioning implementations.
9.1. General Concepts
Before delving into the specific mechanisms of positioning, we need
to establish a number of concepts. These concepts actually form the
foundation of CSS layout in general since every displayed element can
be described in terms of its positioning. After all, any element that
is placed onscreen, or printed on a piece of paper, has a position
and must therefore be positioned -- by the user agent, if nothing
else.
The containing
block is the context in which formatting takes
place. For example, the containing block of a boldface element could
be the paragraph in which it occurs, as demonstrated in Figure 9-1.
Figure 9-1. An example of a containing block
Not every element in CSS generates a containing block for its
descendant elements. The rules for the establishment of a containing
block are as follows:
-
The containing block of the "root element" (also called
the initial containing
block) is established by the user agent. In
HTML, the root element is the HTML element,
although some browsers may incorrectly use BODY.
-
For nonroot elements that are not absolutely positioned, the
containing block for an element is set as the content edge of the
nearest block-level ancestor. This is true even in relative
positioning, although it might not seem so at first.
-
For nonroot elements that are absolutely positioned using a
position of absolute, the
containing block is set to the nearest ancestor (of any kind) that
has a position other than
static. This happens as follows:
-
If the ancestor is block-level, the containing block is set to be
that element's padding edge; in other words, the area that
would be bounded by a border.
-
If the ancestor is inline-level, the containing block is set to the
content edge of the ancestor. In left-to-right languages, the top and
left of the containing block are the top and left content edges of
the first box in the ancestor, and the bottom and right edges are the
bottom and right content edges of the last box. In right-to-left
languages, the right edge of the containing block corresponds to the
right content edge of the first box, and the left is taken from the
last box. The top and bottom are the same.
If there is no such ancestor, then the content edge of the root
element is used to establish a containing block.
The main thing to remember about the containing block is that it
establishes a formatting context for all of its descendant elements.
For example, if margins are declared as percentages, the percentages
are calculated with respect to the containing block. This gives us
rule #2, which says that the containing block is usually equivalent
to the content area of an element.
Another important thing about the containing block is this: elements
can be positioned outside of their containing block. This is very
similar to the way in which floated elements can use negative margins
to float outside of their parent's content area. It also makes
it seem like the term "containing block" should really be
"positioning context," but since the specification uses
"containing block," so will this text. (We do try to
minimize confusion. Really!)
9.1.1. Positioning Schemes
You can
choose one of four different types of positioning by using the
position property.
position
- Values
-
static | relative |
absolute | fixed |
inherit
- Initial Value
-
static
- Applies to
-
all elements
- Inherited
-
no
|
The values of position have the following meanings:
- static
-
The element's box is generated as normal. Block-level elements
generate a rectangular box that is part of the document's flow,
and inline-level boxes are generated in the context of one or more
line boxes that are flowed within their parent element.
- relative
-
The element's box is offset by some distance. Its containing
block is the area that the element would occupy if it were not
positioned. The element retains the shape it would have had were it
not positioned, and the space that the element would ordinarily have
occupied is preserved. Relative positioning is accomplished by
generating the element as though it were set to
static, and then simply shifting the
element's box (or boxes, in the case of an inline element that
crosses multiple lines). It is possible that the positioned element
will overlap other content. The direction and magnitude of the offset
are specified using some combination of the properties
top, right,
bottom, and left.
- absolute
-
The element's box is completely removed from the flow of the
document and positioned with respect to its containing block.
Whatever space the element might have occupied in the normal document
flow is closed up, as though the element did not exist. The size and
position of the element are defined by a combination of the
properties height, width,
top, right,
bottom, and left, plus any
margins, padding, and borders set for the element. Absolutely
positioned elements can have margins, but these margins do not
collapse.
- fixed
-
The element's box is positioned as though it were set to
absolute, but its containing block is the viewport
itself. In screen media such as web browsers, the element will not
move within the browser window when the document is scrolled. This
allows for frame-style layouts, for example. In paged media such as
printouts, a fixed element will appear in the same place on every
page. This potentially can be used to create running heads or
footers.
- inherit
-
The value is inherited from the parent element. See Chapter 10, "CSS2: A Look Ahead", for more details.
9.1.2. Side Offsets
Three of the positioning schemes
described in the previous section -- relative,
absolute, and fixed -- use
four distinct properties to describe the offset of a positioned
element's sides with respect to its containing block. These
four properties, which we will refer to as the
side-offset properties, are
a big part of what makes positioning work.
top, right, bottom, left
- Values
-
<length> | <percentage> |
static-position | auto |
inherit
- Initial Value
-
auto
- Applies to
-
positioned elements (that is, elements for which the value of
position is something other than
static)
- Inherited
-
no
WARNING
Percentages refer to the width of the containing block
(right, left) or the height of
the containing block (top, bottom
).
|
These properties describe an offset from the nearest side of the
containing block (thus the term side-offset ).
For example, top describes how far the outer top edge
of the positioned element should be placed from the top of its
containing block. In the case of top, positive
values move the top edge of the positioned element
downward, while negative values move it
above the top of its containing block.
Similarly, left describes how far to the right (for
positive values) or left (for negative values) the outer left edge of
the positioned element is from the left edge of its containing block.
Another way to look at it is that positive values cause inward
offsets, moving the edges toward the center of the containing block,
and negative values cause outward offsets.
TIP
The description of offsetting the outer edges is based on an erratum.
The original CSS2 specification actually
says that the content edges are offset, but it has been widely agreed
that this is a serious error, and in fact, readings of other parts of
the specification show that it is the outer edges that are offset.
The implication of offsetting the outer edges of a positioned element
is that everything about an element -- margins, borders, padding,
and content -- is moved in the process of positioning the element.
In other words, it is possible to set margins, borders, and padding
for a positioned element. These will be preserved and kept with the
positioned element, and will be contained within the area defined by
the side-offset properties.
There are two other side-offset property values that should be
mentioned here. The first, static-position, causes
the user agent to place the given side of a positioned element where
it would have been if the element had not been positioned. For
example, consider a nonpositioned element whose top edge is 3 ems
from the top of its containing block. If the element is then
positioned and given a top of
static-position, then the top of the positioned
element will be 3 ems from the top of the containing block. Later in
the chapter, we'll see how this can be useful.
The other value, auto, allows for some even more
interesting effects. It acts much the same as setting
auto on margins, but in positioning, this can
permit the creation of elements that are only as wide or tall as they
need to be in order to display their content, without having to
exactly specify how high or wide that will be. We'll explore
this in detail later in the chapter as well.
It is important to remember that the side-offset properties define
offset from the analogous side (e.g., left defines
the offset from the left side) of the containing block, not from the
upper-left corner of the containing block. That's why, for
example, one way to fill up the lower-right corner of a containing
block would use these values:
top: 50%; bottom: 0; left: 50%; right: 0;
In this example, the outer left edge of the positioned element is
placed halfway across the containing block. This is its offset from
the left edge of the containing block. The outer right edge of the
positioned element, however, is not offset from the right edge of the
containing block, so the two are coincident. Similar reasoning holds
true for the top and bottom of the positioned element: the outer top
edge is placed halfway down the containing block, but the outer
bottom edge is not moved up from the bottom. This leads to
what's shown in Figure 9-2.
TIP
What's depicted in Figure 9-2, and in most of
the examples in this chapter, will only work if the containing block
was established by an element with an explicitly defined height. This
is because a line in the specification says that if the height of the
containing block is not explicitly specified -- say, for example,
that it's dependent on the content of the element, as in a
normal paragraph -- then both top and
bottom for any positioned element within that
containing block are treated as auto.
In addition, even though they don't explicitly say so, the
examples in this section (and the next few sections) are all based
around absolute positioning. Since absolute positioning is the
simplest scheme in which to demonstrate how top,
right, bottom, and
left work, we'll stick to that for now.
Figure 9-2. Positioning an element within its containing block
Note that the positioned element has padding, a double border, and a
slightly different background color. In Figure 9-2,
it has no margins, but if it did, they would create blank space
between the borders and the offset edges. This would make the
positioned element appear as though it did not completely fill the
lower-right quarter of the containing block. In truth, it would do
so, but this would not be immediately apparent to the eye. In other
words, the following two sets of styles would have the same visual
appearance, assuming the containing block to be 100 ems high by 100
ems wide:
top: 50%; bottom: 0; left: 50%; right: 0; margin: 10em;
top: 60%; bottom: 10%; left: 60%; right: 10%; margin: 0;
Again, the similarity would be only visual in nature.
By using negative values, it is possible to position an element
outside its containing block. For example, the
following values will lead to the result shown in Figure 9-3:
top: -5em; bottom: 50%; left: 75%; right: -3em;
Figure 9-3. Positioning an element beyond its containing block
Now let's see why leaving out width and
height isn't always a bad thing in
positioning, as well as how declaring them can work to your
advantage.
9.1.3. Width and Height
There will be many cases when, having determined
where you're going to position an element, you will want to go
ahead and declare how wide and how high that element should be. In
addition, there will likely be conditions where you'll want to
limit how high or wide a positioned element gets, not to mention
cases where you want the browser to go ahead and automatically
calculate the width, or the height, or both.
9.1.3.1. Setting width and height
If you want to give your positioned element a specific width, then
the obvious property to turn to is
width. Similarly,
height will let you declare a specific height
for a positioned element.
width
- Values
-
<length> | <percentage> | auto
- Initial Value
-
auto
- Applies to
-
block-level and replaced elements
- Inherited
-
no
WARNING
Percentage values refer to the width of the containing block.
|
height
- Values
-
<length> | auto
- Initial Value
-
auto
- Applies to
-
block-level and replaced elements
- Inherited
-
no
|
Although it is sometimes important to set the width and height of an
element, this is not always necessary when positioning elements. For
example, if the placement of the four sides of the element is
described using top, right,
bottom, and left, then the
height and width of the element are determined by the placement of
the sides. Assume that you want an element to fill the left half of
its containing block, from top to bottom. You could use these styles,
with the result depicted in Figure 9-4:
top: 0; bottom: 0; left: 0; right: 50%;
Figure 9-4. Filling the left half of the containing block
Since the default value of both width and
height is auto, the result
shown in Figure 9-4 is exactly the same as if you
had used these styles:
top: 0; bottom: 0; left: 0; right: 50%; width: auto; height: auto;
Now let's say you want to position an element that is in the
upper-right corner of its containing block and is one-third as wide
as its containing block, but only as tall as necessary to display its
content, as shown in Figure 9-5.
Figure 9-5. "Shrink-wrapping" a positioned element
This is where auto really comes into its own. The
styles needed to get the result shown in Figure 9-5
is:
top: 0; bottom: auto; left: auto; right: 0; width: 33%; height: auto;
Because top is set to 0, and
bottom and height are set to
auto, the user agent is free to size the element
so that it's just tall enough to display its own content, and
no taller. This happens thanks to the revised rules for calculating
the height and width of absolutely positioned elements, which were
published in an errata to the original specification.
Note that the fact that we set an explicit width helped matters.
Since the user agent knew how wide the element should be, it was a
trivial matter to calculate the height of the element based on its
content. If width has also been set to auto, then
the user agent would have had to assign some value to it. This value
is likely to vary by user agent, so it's usually better to
declare a width that you like.
Of course, this is not always the case: you could set an explicit
height and let the width scale to fit the content. Thus:
top: 0; bottom: auto; left: auto; right: 0; width: auto; height: 10em;
Here the element will be 10 ems tall no matter what, but its width
can vary to exactly fit the content. This is sometimes called
"shrink-wrapping" the
content, since it mimics the act of applying shrink-wrap to a box or
other product. In the same way the plastic shrink-wrap precisely hugs
the contents of the package, so too does a positioned
element -- given the right styles, of course.
If bottom is set to an actual
value -- percentage or length -- then the height of the
positioned element is constrained. As a demonstration, let's
set bottom to be a specific value, with the result
shown in Figure 9-6:
top: 0; bottom: 10%; left: auto; right: 0; width: 33%; height: auto;
Figure 9-6. Defining a height by using an explicit bottom
In this case, the height of the element must be
90% the height of the containing block, since 100% -
- 10% = 90%. This assumes, of course, that there have been no
margins, borders, or padding set for the positioned element;
otherwise, the effective height would be
decreased, although the entire element (content, padding, borders,
and margins) would still be 90% as tall as the containing block.
Similarly, if we specifically declare a height but leave
bottom as auto, then something
like Figure 9-7 will occur:
top: 0; bottom: auto; left: auto; right: 0; width: 33%; height: 45%;
Figure 9-7. Defining a height by using an explicit height
In this case, the placement of the bottom of the positioned element
is the same as if we'd declared bottom:
55%, because 100% -
- 45% = 55%.
Many of the same principles hold true for widths, of course. For
example:
top: 100px; bottom: 200px; left: 30%; right: 10%; height: auto; width: auto;
Here, the width of the element is effectively 60% the width of its
containing block.
As wonderful as all of this is, there arises a serious question.
Suppose you have a positioned element that you don't want to be
any smaller than a certain size? Consider the following styles:
top: 10%; bottom: 20%; left: 50%; right: 10%;
Thus the height is 70%, and the width 40% of the containing
block's height and width. That's fine as far as it
goes -- but what happens if the containing block is only 50 pixels
tall by 200 pixels wide? That gives you an element only 35 pixels
wide by 80 pixels tall. That doesn't leave much room to show
the content, but if you use auto for the width or
height, the element might fill its entire containing block, obscuring
the containing block's contents.
As we'll see later in the chapter, you have the option to force
your content to overflow the element. For now, however, let's
concentrate on ways to deal with its width and height. You could try
explicitly assigning a width and height, like this:
top: 10%; bottom: 20%; left: 50%; right: 10%; width: 30em; height: 15em;
However, this approach seems a little heavy-handed, and could have
disastrous consequences in small browsing environments like handheld
devices. Furthermore, it forces you to declare a specific height and
width, which gives up a lot of flexibility. Wouldn't it be
better to define certain limits for the size of the height and width?
9.1.3.2. Limiting width and height
Should it become necessary or
desirable, you can place limits on an element's width and
height by using the following CSS2 properties, which I'll refer
to as the min-max properties.
min-width
- Values
-
<length> | <percentage> | inherit
- Initial Value
-
UA specific
- Applies to
-
all elements except nonreplaced inline elements and table elements
- Inherited
-
no
WARNING
Percentages refer to the width of the
containing block.
|
max-width
- Values
-
<length> | <percentage> | none |
inherit
- Initial Value
-
UA specific
- Applies to
-
all elements except nonreplaced inline elements and table elements
- Inherited
-
no
WARNING
Percentages refer to the width of the
containing block.
|
min-height
- Values
-
<length> | <percentage> | inherit
- Initial Value
-
0
- Applies to
-
all elements except nonreplaced inline elements and table elements
- Inherited
-
no
WARNING
Percentages refer to the height of the
containing block.
|
max-height
- Values
-
<length> | <percentage> | none |
inherit
- Initial Value
-
none
- Applies to
-
all elements except nonreplaced inline elements and table elements
- Inherited
-
no
WARNING
Percentages refer to the height of the
containing block.
|
The names of these properties make them fairly self-explanatory. Here
we have one possible solution for the example given in the previous
section:
top: 10%; bottom: 20%; left: 50%; right: 10%;
min-width: 20em; min-height: 30em;
Of course, this still isn't a very good solution, since it
forces the element to be at least 20em wide by
30em tall. Here's a better one:
top: 10%; bottom: auto; left: 50%; right: 10%; height: auto; min-width: 15em;
Here we have a case where the element should be 40% as wide as the
containing block but can never be less than 15em
wide. We've also changed the bottom and
height so that they're automatically
determined. This will let the element be as tall as necessary to
display its content, no matter how narrow it gets (never less than
15em, of course!).
We can turn this around to keep elements from getting too wide or
tall by using max-width and
max-height. Let's consider a situation
where, for some strange reason, we want an element to have
three-quarters the width of its containing block, but to stop getting
wider when it hits 400 pixels. The appropriate styles are:
left: 0%; right: auto; width: 75%; max-width: 400px;
The great advantage of the min-max properties is that they let you
mix units with relative safety. You can set percentage-based sizes
while setting length-based limits, or vice versa.
TIP
These min-max properties can be very useful in conjunction with
floated elements as well. For example, you
can allow a floated element's width to be relative to the width
of its parent element (which is its containing block), while also
making sure that the float's width never goes below
10em. The reverse approach is also possible:
P.aside {float: left; width: 40em; max-width: 40%;}
This will set the float to be 40em wide, unless
that would be more than 40% the width of the containing block, in
which case the float will be narrowed.
Of course, it's still possible to use these properties to keep
an element from exceeding a certain size, as in this:
max-height: 30em; max-width: 20em;
The question here, though, is what happens if the content of the
element doesn't all fit into the specified element size. Does
it get cut off at the boundaries, or does it spill outside the
positioned element? That's what the next section will
explore.
9.1.4. Content Overflow and Clipping
Should the content
of an element be too much for the element's size, it will be in
danger of overflowing the element itself. There are a few
alternatives in such situations, and CSS lets you select between
them. It will also allow you to define a clipping region to determine
the area of the element outside which these sorts of things become an
issue, as well as give a way to clip off parts of an element.
9.1.4.1. Overflow
So let's say that you have, for whatever reason, an element
that has been pinned to a specific size, and the content
doesn't fit. You can take control of the situation with the
overflow property.
overflow
- Values
-
visible | hidden |
scroll | auto |
inherit
- Initial Value
-
visible
- Applies to
-
block-level and replaced elements
- Inherited
-
no
|
This property only applies in one (or more) the following cases:
-
When an element has negative margins.
-
When a line box must be wider than its parent's content area,
perhaps due to the existence of an unusually long word, nonwrapped
text such as PRE text, or another circumstance
where line-wrapping cannot occur.
-
When a block-level box is wider than its parent's content area.
-
When an element's box is taller than the height explicitly set
for its parent.
-
When an element has been absolutely positioned.
The default value of visible means that the
content may be visible outside the element's box. Typically,
this would lead to the content simply running outside its own element
box, but not altering the shape of that box. The following styles
would result in Figure 9-8:
DIV#sidebar {position: absolute; top: 0; left: 0; width: 25%; height: 7em;
overflow: visible;}
Figure 9-8. Overflowing the content area of an element
TIP
The specification does not say whether or not visible overflowed
content can overlap the content of other elements, but it is
reasonable to infer that this is possible. Since positioned elements
can overlap other elements, it stands to reason that the content of a
positioned element should be treated no differently.
If the overflow is set to
scroll, the element's content is
clipped -- that is, cannot be seen -- but some way is provided
to make the extra content available to the user. In a web browser,
this would mean a scrollbar (or set of them) or another method of
accessing the content without altering the shape of the element
itself. One possibility is depicted in Figure 9-9,
which could result from the following styles:
DIV#sidebar {position: absolute; top: 0; left: 0; width: 15%; height: 7em;
overflow: scroll;}
Figure 9-9. Invoking a scrollbar with overflow
If scroll is used, the panning mechanisms (e.g., scrollbars)
should always be rendered. To quote the specification, "this
avoids any problems with
scrollbars
appearing or disappearing in a dynamic environment." Thus, even
if the element has sufficient space to display all of its content,
the scrollbars would still appear. In addition, when printing a page
or otherwise displaying the document in a paged medium, the content
should be displayed as though the value of
overflow were declared to be
visible.
If the overflow is set to
hidden, the element's content is clipped,
but no mechanism should be provided to make the content accessible to
the user. Consider the following styles:
DIV#sidebar {position: absolute; top: 0; left: 0; width: 15%; height: 7em;
overflow: hidden;}
In such an instance, the clipped content would not be accessible to
the user. This would lead to a situation like that illustrated by
Figure 9-10.
Figure 9-10. Clipping content with overflow
Finally, there is overflow:
auto. This allows user agents to determine what
behavior to use, although they are encouraged to provide a scrolling
mechanism when necessary. This is a potentially useful way to use
overflow, since user agents could interpret it to
mean "provide scrollbars only when needed." (They may
not, but they certainly could, and probably should.)
In the simplest case, the clipping region for any positioned element
is the content area of the element itself, as depicted in Figure 9-10. However, you may wish to change the clipping
area. That's what we'll do in the next section.
9.1.4.2. Overflow clipping
In
situations where the content of an element overflows its element box,
and overflow has been set such that the content
should in fact be clipped, it is possible to alter the shape of the
clipping region by using the property
overflow-clip.
overflow-clip
- Values
-
rect(<top>,
<right>, <bottom>,
<left>) | auto |
inherit
- Initial Value
-
auto
- Applies to
-
block-level and replaced elements with an overflow
value other than visible
- Inherited
-
no
|
The default value, auto, means that the clipping
region should have the same size and location as the element's
content area. The other possibility is to define a clipping shape
that is relative to the element's content area. This does not
alter the shape of the content area, but instead alters the area in
which content may be rendered.
TIP
While the only clipping shape available in CSS2 is a rectangle, the
specification does offer the possibility that other shapes will be
included in future specifications.
This is done with the shape value
rect(top,
right,
bottom,
left). We could specify
no change in the clipping region like this:
overflow-clip: rect(0, auto, auto, 0);
This would be no different than declaring
overflow-clip: auto. It's
more interesting to shift the clipping area, of course. For example:
DIV#sidebar {position: absolute; top: 0; left: 0; width: 5em; height: 7em;
overflow: hidden; overflow-clip: rect(0.5em, 4em, 6.5em, 1em);}
This sets the clipping area inward half an em from the top and
bottom, and one em from the right and left. This would cause a result
something like that shown in Figure 9-11, where a
dashed line has been added to illustrate the edges of the clipping
region. This line would not actually appear in a user agent
attempting to render the document.
Figure 9-11. Contracting the clipping region
The syntax of rect is an interesting case.
Technically, it can be
rect(top,
right,
bottom,
left) -- note the
commas -- but
the CSS2 specification contains examples both with and without commas
and defines rect as accepting both the comma and
noncomma versions. This text will stick to the comma version mostly
because it makes things easier to read.
It is extremely important to note that the values for
rect(...) are not
side-offsets. They are, instead, distances from the
upper-left corner of the element. Thus, a clipping rectangle which
encloses a square 20 pixels by 20 pixels in the upper-left corner of
the element would be defined as:
rect(0, 20px, 20px, 0)
The only values permitted with rect(...) are
length values and auto, which is the same as
"set the clipping edge to the appropriate content edge."
Thus, the following two statements mean the same thing:
overflow-clip: rect(auto, auto, 10px, 1cm);
overflow-clip: rect(0, 0, 10px, 1cm);
It is possible to set negative lengths, though, which will expand the
clipping area outside the element's box. If you wanted to push
the clipping area up and left by a quarter-inch, it would be done
with the following styles (illustrated by Figure 9-12):
overflow-clip: rect(-0.25in, auto, auto, -0.25in);
Figure 9-12. Expanding the clipping area
This doesn't do much good, as you can see. The clipping
rectangle extends up and to the left, but since there isn't any
content there, the visual effect is the same as if the author had
declared overflow-clip: auto.
On the other hand, it might be okay to go beyond the bottom and right
edges, but not the top or left. Figure 9-13 shows
the results of these styles (and remember, the dashed lines are only
for illustrative purposes):
DIV#sidebar {position: absolute; top: 0; left: 0; width: 5em; height: 7em;
overflow: hidden; overflow-clip: rect(0, 6em, 9em, 0);}
Figure 9-13. Expanding the clipping region
This extends the area in which content can be seen. However, it
doesn't change the flow of the content, so the only visual
effect is that more content can be seen below the element. The text
does not flow out to the right, because the width of its line boxes
is still constrained by the width of the positioned element. If there
had been an image wider than the positioned element, or preformatted
text with a long line, this might have been visible to the right of
the positioned element, up to the point where the clipping rectangle
ends.
The syntax of rect(...) is, as you may have
already realized, rather unfortunate. It is based on an early draft
of the positioning section, which used the top-left-offset scheme.
Internet Explorer implemented this
before CSS2 was made a full Recommendation, and so came into conflict
with a last-minute change that made rect(...) use
side-offsets, just like the rest of CSS2. This was done, reasonably
enough, because it would make positioning consistent with itself.
By then, however, it was too late: there was an implementation in the
marketplace, and rather than force Microsoft to change the browser
and thus potentially cause existing pages to break, the standard was
changed to reflect implementation. This means, sadly, that it is
impossible to set a consistent clipping rectangle in situations where
the height and width are not precisely defined. For example, there is
no way to create a clipping rectangle that is 1 em larger than this
element's content area:
position: absolute; top: 0; bottom: 50%; right: 50%; left: 0;
Since there is no way to know how many ems tall or wide the element
will be, there is no way to make a clipping rectangle that ends 1 em
to the right, or 1 em below, the content area of the element.
Further compounding the problem is that rect(...)
only accepts length units and auto. The addition
of percentage units as valid rect(...) values
would go a long way toward improving things, and hopefully a future
version of CSS will add this capability.
9.1.4.3. Element clipping
There is
another way to clip in CSS, but this is very different from what
we've just seen.
clip
- Values
-
rect(<top>,
<right>, <bottom>,
<left>) | auto |
inherit
- Initial Value
-
auto
- Applies to
-
block-level and replaced elements
- Inherited
-
no
|
This property can be used to clip the element with a simple
intersection operation. The area of the element contained within the
clip rectangle is displayed, and any part
of it outside that rectangle is not. In addition, the
clip rectangle is set in relation to the outer
edge of the element -- not its content edge. Thus, let's say
you wanted (for whatever reason) to clip the top 10 pixels of an
image:
<IMG SRC="foo.gif" STYLE="clip: rect(10px, auto, auto, 0);">
The auto values will set the clipping
rectangle's bottom to align with the bottom of the image, and
the right edge to the right edge of the image. The value of
0 for left keeps the left edge
of the clipping rectangle against the left edge of the image, but the
10px for top moves the top edge
of the clipping rectangle downward 10 pixels. This will cause the top
10 pixels of the image to become effectively invisible.
clip can be applied to any element. Thus, you
could display only the top left corner of a paragraph using something
like this:
<P STYLE="clip: rect(0, 10em, 10em, 0);">
This will display a square 10 ems wide by 10 ems high. This square is
drawn from the top left outer corner, so any margins, borders, and
padding will influence how much of the element is visible and how
much is clipped out.
9.1.5. Element Visibility
In addition to all the clipping and
overflowing, you can also control the visibility of an entire
element.
visibility
- Values
-
visible | hidden |
collapse | inherit
- Initial Value
-
inherit
- Applies to
-
all elements
- Inherited
-
no
|
This one is pretty easy. If an element is set to have
visibility: visible, then it is
visible. Of course.
However, if an element is set to visibility:
hidden, it is made "invisible" (to use
the wording in the specification). In its invisible state, the
element still affects the document's layout as though it were
visible. In other words, the element is still there: you just
can't see it. Note the difference between this and
display: none. In the latter
case, the element is not displayed and is removed from the document
altogether so that it doesn't have any effect on document
layout. Figure 9-14 shows a document in which an
EM element has been set to be
hidden, based on the following styles and markup:
EM.trans {visibility: hidden; border: 3px solid gray; background: silver;
padding: 1em;}
<P>
This is a paragraph which should be visible. Lorem ipsum, dolor sit amet,
<EM CLASS="trans">consectetuer adipiscing elit, sed diam nonummy nibh </EM>
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
</P>
Figure 9-14. Hiding an element
Everything visible about an element -- such as content,
background, and borders -- will be made invisible. Note that the
space is still there because the element is still part of the
document's layout. We just can't see it.
Note too that it's possible to set the descendant element of a
hidden element to be visible.
This would cause the element to appear wherever it normally would,
despite the fact that the ancestor (and possibly the siblings) is
invisible. In order to do so, you would need to explicitly declare
the descendant element to be visible, since
visibility is inherited. Thus:
P.clear {visibility: hidden;}
P.clear EM {visibility: visible;}
As for visbility: collapse,
this value is used in CSS table rendering, which isn't covered
in this book because it wasn't well implemented as the book was
being written. According to the CSS2 specification,
collapse has the same meaning as
hidden if it is used on nontable elements. From a
semantic standpoint, this seems somewhat confusing (since
collapse sounds like it should trigger the kind of
behavior you'd see with display:
none), but there it is nonetheless.
 |  |  | | 8.5. Summary |  | 9.2. Relative Positioning |
Copyright © 2002 O'Reilly & Associates. All rights reserved.
|