CSS: The Definitive Guide, 3rd Edition (48 page)

Read CSS: The Definitive Guide, 3rd Edition Online

Authors: Eric A. Meyer

Tags: #COMPUTERS / Web / Page Design

Element Visibility

In addition to all of the clipping
and
overflowing, you can also control the visibility of
an
entire element.

visibility

Values:

visible
|
hidden
|
collapse
|
inherit

Initial value:

visible

Applies to:

All elements

Inherited:

Yes

Computed value:

As specified

This one is pretty easy. If an element is set to have
visibility
:
visible
, then it is, of
course, visible.

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 also removed from the document altogether so that
it doesn't have any effect on document layout.
Figure 10-37
shows a document in which a paragraph has been set to
hidden
, based on the following styles and
markup:

em.trans {visibility: hidden; border: 3px solid gray; background: silver;
margin: 2em; padding: 1em;}


This is a paragraph that should be visible. Lorem ipsum, dolor sit amet,
consectetuer adipiscing elit, sed diam nonummy nibh
euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.


Figure 10-37. Making elements invisible without suppressing their element boxes

Everything visible about a hidden 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. You 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 its siblings) is invisible.
To do so, you must explicitly declare the descendant element
visible
, since
visibility
is
inherited:

p.clear {visibility: hidden;}
p.clear em {visibility: visible;}

As for
visibility
:
collapse
, this value is used in CSS table rendering, which is covered
in the next chapter. According to the CSS2 specification,
collapse
has the same meaning as
hidden
if it is used on nontable elements.

Absolute Positioning

Since most of the examples and figures in the previous
sections illustrate absolute
positioning,
you're already halfway to
an understanding of how it works. Most of the remaining material covers the details
of what happens when absolute positioning is invoked.

Containing blocks and
absolutely positioned elements

When an element is positioned absolutely, it is
completely removed from the document flow. It is then positioned with respect to
its containing block, and its edges are placed using the offset properties
(
top
,
left
, etc.). The positioned element does not flow around the content of
other elements, or vice versa. This implies that an absolutely positioned element
may overlap other elements or be overlapped by them. (You'll see how you can
affect the overlapping order later in the chapter.)

The containing
block for an absolutely positioned element is the nearest ancestor element that
has a
position
value other than
static
. It is common for an author to pick an element
that will serve as the containing block for the absolutely positioned element and
give it a
position
of
relative
with no
offsets:

p.contain {position: relative;}

Consider
the example in
Figure 10-38
, which is
an illustration of the
following:

p {margin: 2em;}
p.contain {position: relative;} /* establish a containing block*/
b {position: absolute; top: auto; right: 0; bottom: 0; left: auto;
width: 8em; height: 5em; border: 1px solid gray;}


This paragraph does not establish a containing block for any of its
descendant elements that are absolutely positioned. Therefore, the absolutely
positioned boldface element it contains will be positioned with
respect to the initial containing block.



Thanks to 'position: relative', this paragraph establishes a containing
block for any of its descendant elements that are absolutely positioned.
Since there is such an element-- that is to say, a boldfaced element
that is absolutely positioned,
placed with respect to its containing
block (the paragraph)
, it will appear within the element box generated
by the paragraph.



Figure 10-38. Using relative positioning to define containing blocks

The
b
elements in both paragraphs
have been absolutely positioned. The difference is in the containing block used
for each one. The
b
element in the first
paragraph is positioned with respect to the initial containing block because all
of its ancestor elements have a
position
of
static
. The second paragraph, though, has
been set to
position
:
relative
, so it establishes a containing block for its
descendants.

You've probably noted that in the second paragraph, the
positioned element overlaps some of the text content of the paragraph. There is no
way to avoid this, short of positioning the
b
element outside of the paragraph (by using a negative value for
right
or one of the other offset properties) or by
specifying a padding for the paragraph that is wide enough to accommodate the
positioned element. Also, since the
b
element
has a transparent background, the paragraph's text shows through the positioned
element. The only way to avoid this is to set a background for the positioned
element, or move it out of the paragraph entirely.

You will sometimes
want to ensure that the body element establishes a containing block for all its
descendants, rather than allowing the user agent to pick an initial containing
block. This is as simple as
declaring:

body {position: relative;}

In
such a document, you could drop in an absolutely positioned paragraph, as follows,
and get a result like that shown in
Figure
10-39
:

...


Figure 10-39. Positioning an element whose containing block is the root element

The paragraph is now positioned at the very beginning of the document,
half as wide as the document's width and overwriting the first few
elements.

An important point to highlight is that when an element is
absolutely positioned, it also establishes a containing block for its descendant
elements. For example, you could absolutely position an element and then
absolutely position one of its children, as shown in
Figure 10-40
, which was generated using
the following styles and basic
markup:

div {position: relative; width: 100%; height: 10em;
border: 1px solid; background: #EEE;}
div.a {position: absolute; top: 0; right: 0; width: 15em; height: 100%;
margin-left: auto; background: #CCC;}
div.b {position: absolute; bottom: 0; left: 0; width: 10em; height: 50%;
margin-top: auto; background: #AAA;}

absolutely positioned element A
absolutely positioned element B


containing block

Figure 10-40. Absolutely positioned elements establish containing blocks

Remember that if the document is scrolled, the positioned elements
will scroll right along with it. This is true of all absolutely positioned
elements that are not descendants of fixed-position elements. It happens because,
eventually, the elements are positioned in relation to something that's part of
the normal flow. For example, if you absolutely position a table whose containing
block is the initial containing block, then the table will scroll because the
initial containing block is part of the normal flow. Similarly, even if you set up
absolutely positioned elements nested four levels deep, the "outermost" of these
elements is still positioned with respect to the initial containing block. Thus,
it will scroll along with the initial containing block, and all of its descendants
will go along for the ride.

Tip

If you want to position elements so that they're placed relative to the
viewport and
don't
scroll along with the rest of the
document, keep reading. The upcoming section on fixed positioning will tell you
how.

Placement and sizing of absolutely positioned elements

It may seem odd to combine the concepts of
placement and sizing, but it's necessary with absolutely positioned elements
because the specification binds them very closely together. Upon closer
inspection, this is not such a strange pairing. Consider what happens if an
element is positioned using all four offset properties, like so:

#masthead h1 {position: absolute; top: 1em; left: 1em; right: 25%; bottom: 10px;
margin: 0; padding: 0; background: silver;}

Here, the height and width of the
h1
's
element box is determined by the placement of its outer margin edges, as shown in
Figure 10-41
.

Figure 10-41. Determining the height of an element based on the offset properties

If the containing block were made taller, then the
h1
would also become taller; if the containing block is narrowed, then
the
h1
would become narrower. If you were to
add margins or padding to the
h1
, it would have
further effects on the calculated height and width of the
h1
.

But what if you do all of that and then also try to set an explicit height and
width:

#masthead h1 {position: absolute; top: 0; left: 1em; right: 10%; bottom: 0;
margin: 0; padding: 0; height: 1em; width: 50%; background: silver;}

Something has to give, because it's incredibly unlikely that all those values
will be accurate. In fact, the containing block would have to be exactly
two-and-a-half times as wide as the
h1
's
computed value for
font-size
for all of the
shown values to be accurate. Any other width would mean at least one value is
wrong and must be ignored. Figuring out which one depends on a number of factors,
and the factors change depending on whether an element is replaced or nonreplaced.

For that matter, consider the following:

#masthead h1 {position: absolute; top: auto; left: auto;}

What should the result be? As it happens, the answer is
not
"reset the values to zero." We'll see the actual answer
in the next section.

Auto-edges

When an element is absolutely positioned, a special
behavior applies when any of the offset properties
other than
bottom
are set to
auto
. Let's take
top
as an example. Consider the
following:


When we consider the effect of positioning, it quickly becomes clear that authors
can do a great deal of damage to layout, just as they can do very interesting
things.[4]
This is usually the case with useful technologies: the sword always has
at least two edges, both of them sharp.


What
should happen? For
left
, it's easy: the left
edge of the element should be placed against the left edge of its containing block
(which you can assume to be the initial containing block). For
top
, however, something much more interesting
happens. The top of the positioned element should line up with the place where its
top would have been if it were not positioned at all. In other words, imagine
where the
span
would have been placed if its
position
value were
static
; this is its
static position
—where its top edge should be calculated to sit.
CSS2.1 elaborates:

...the term "static position" (of an element) refers, roughly, to the
position an element would have had in the normal flow. More precisely, the
static position for "top" is the distance from the top edge of the containing
block to the top margin edge of a hypothetical box that would have been the
first box of the element if its "position" property had been "static". The
value is negative if the hypothetical box is above the containing block.

Therefore, you should get the result shown in
Figure 10-42
.

Figure 10-42. Absolutely positioning an element consistently with its "static" position

The "[4]" sits just outside the paragraph's content because the
initial containing block's left edge is to the left of the paragraph's left
edge.

The same basic rules hold true for
left
and
right
being set to
auto
. In those cases, the left (or right) edge of a
positioned element lines up with the spot where the edge would have been placed if
the element weren't positioned. Let's modify our previous example so that both
top
and
left
are set to
auto
:


When we consider the effect of positioning, it quickly becomes clear that authors
can do a great deal of damage to layout, just as they can do very interesting
things.[4]
This is usually the case with useful technologies: the sword always has
at least two edges, both of them sharp.


This
would have the result shown in
Figure
10-43
.

Figure 10-43. Absolutely positioning an element consistently with its "static" position

The "[4]" now sits right where it would have, were it not positioned.
Note that, since it is positioned, its normal-flow space is closed up. This causes
the positioned element to overlap with the normal-flow content.

Tip

It should be noted that CSS2 and CSS2.1 both state that in cases such as
these, "...user agents are free to make a guess at its probable [static]
position." Current browsers do a fairly decent job of treating
auto
values for
top
and
left
as intended and of
placing the element consistent with the place it would have been in the normal
flow.

This auto-placement works only in certain situations, generally wherever
there are few constraints on the other dimensions of a positioned element. Our
previous example could be auto-placed because it had no constraints on its height
or width, nor any constraints on the placement of the bottom and right edges. But
suppose, for some reason, there had been such constraints?
Consider:


When we consider the effect of positioning, it quickly becomes clear that authors
can do a great deal of damage to layout, just as they can do very interesting
things.[4] This is usually the case with
useful technologies: the sword always has at least two edges, both of them sharp.


It
is not possible to satisfy all of those values. Determining what happens is the
subject of the next section.

Other books

Stone Cold Cowboy by Jennifer Ryan
Captain's Bride by Kat Martin
Chaser by John W. Pilley
The Hero's Lot by Patrick W. Carr
Breaking Sky by Cori McCarthy
Bury Me When I'm Dead by Cheryl A Head
Bending Bethany by Aria Cole