Ïðèãëàøàåì ïîñåòèòü
Ìàéêîâ (maykov.lit-info.ru)

7.4 Altering Element Display

Previous Page Table of Contents Next Page

7.4 Altering Element Display

As I mentioned briefly in Chapter 1, you can affect the way a user agent displays by setting a value for the property display. Now that we've taken a close look at visual formatting, let's revisit the display property and discuss two more of its values using concepts from this chapter.

display


Values

none | inline | block | inline-block | list-item | run-in | table | inline-table | table-row-group | table-header-group | table-footer-group | table-row | table-column-group | table-column | table-cell | table-caption | inherit


Initial value

inline


Applies to

all elements


Inherited

no


Computed value

varies for floated, positioned, and root elements (see CSS2.1, section 9.7); otherwise, as specified


Note

the values compact and marker appeared in CSS2 but were dropped from CSS2.1 due to a lack of widespread support


We'll ignore the table-related values, since they get covered in Chapter 11, and we'll also ignore the value list-item since we deal with lists in detail in Chapter 12. We've spent quite some time discussing block and inline elements, but let's spend a moment talking about how altering an element's display role can alter layout before we look at inline-block and run-in.

7.4.1 Changing Roles

When it comes to styling a document, it's obviously handy to be able to change the display role of an element. For example, suppose you have a series of links in a div that you'd like to lay out as a vertical sidebar:

<div id="navigation">

<a href="/css/015/index.html">WidgetCo Home</a><a href="products.html">Products</a>

<a href="services.html">Services</a><a href="fun.html">Widgety Fun!</a>

<a href="support.html">Support</a><a href="about.html" id="current">About Us</a>

<a href="contact.html">Contact</a>

</div>

You could put all the links into table cells, or wrap each one in its own div—or you could just make them all block-level elements, like this:

div#navigation a {display: block;}

This will make every a element within the navigation div a block-level element. If you add on a few more styles, you could have a result like that shown in Figure 7-49.

Figure 7-49. Changing the display role from inline to block
figs/css2_0749.gif

Changing display roles can be useful in cases where you want non-CSS browsers to get the navigation links as inline elements but to lay out the same links as block-level elements. With the links as blocks, you can style them as you would div elements, with the advantage that the entire element box becomes part of the link. Thus, if a user's mouse pointer hovers anywhere in the element box, he can then click the link.

You may also want to take elements and make them inline. Suppose you have an unordered list of names:

<ul id="rollcall">

<li>Bob C.</li>

<li>Marcio G.</li>

<li>Eric M.</li>

<li>Kat M.</li>

<li>Tristan N.</li>

<li>Arun R.</li>

<li>Doron R.</li>

<li>Susie W.</li>

</ul>

Given this markup, say you want to make the names into a series of inline names with vertical bars between them (and on each end of the list). The only way to do so is to change their display role. The following rules will have the effect shown in Figure 7-50:

#rollcall li {display: inline; border-right: 1px solid; padding: 0 0.33em;}

#rollcall li:first-child {border-left: 1px solid;}
Figure 7-50. Changing the display role from list-item to inline
figs/css2_0750.gif

There are plenty of other ways to use display to your advantage in design. Be creative and see what you can invent!

Be careful to note, however, that you are changing the display role of elements—not changing their inherent nature. In other words, causing a paragraph to generate an inline-level box does not turn that paragraph into an inline element. In XHTML, for example, some elements are block while others are inline. (Still others are "flow" elements, but we're ignoring them for the moment.) An inline element can be a descendant of a block element, but the reverse is not true. Thus, while a link can be placed inside a paragraph, a link cannot be wrapped around a paragraph. This will hold true no matter how you style the elements in question. Consider the following markup:

<a href="http://www.example.net" style="display: block;">

<p style="display: inline;">this is wrong!</p>

</a>

The markup will not validate because the block element (p) is nested inside an inline element (a). The changing of display roles does nothing to change this. display has its name because it affects how the element is displayed, not what kind of element it is.

7.4.2 Inline-Block Elements

As befits the hybrid look of the value name inline-block, inline-block elements are indeed a hybrid of block-level and inline elements. This display value is new in CSS2.1.

An inline-block element relates to other elements and content as an inline box. In other words, it's laid out in a line of text just as an image would be, and, in fact, inline-block elements are formatted within a line as a replaced element. This means the bottom of the inline-block element will rest on the baseline of the text line by default and will not line-break within itself.

Inside the inline-block element, the content is formatted as though the element were block-level. The properties width and height apply to it, as they do to any block-level or inline replaced element, and those properties will increase the height of the line if they are taller than the surrounding content.

Let's consider some example markup that will help make this clearer:

<div id="one">

This text is the content of a block-level level element.  Within this 

block-level element is another block-level element.  <p>Look, it's a block-level 

paragraph.</p>  Here's the rest of the DIV, which is still block-level.

</div>

<div id="two">

This text is the content of a block-level level element.  Within this 

block-level element is an inline element.  <p>Look, it's an inline 

paragraph.</p>  Here's the rest of the DIV, which is still block-level.

</div>

<div id="three">

This text is the content of a block-level level element.  Within this 

block-level element is an inline-block element.  <p>Look, it's an inline-block 

paragraph.</p>  Here's the rest of the DIV, which is still block-level.

</div>

To this markup, we apply the following rules:

div {margin: 1em 0; border: 1px solid;}

p {border: 1px dotted;}

div#one p {display: block; width: 6em; text-align: center;}

div#two p {display: inline; width: 6em; text-align: center;}

div#three p {display: inline-block; width: 6em; text-align: center;}

The result of this style sheet is depicted in Figure 7-51.

Figure 7-51. The behavior of an inline-block element
figs/css2_0751.gif

Notice that in the second div, the inline paragraph is formatted as normal inline content, which means width and text-align get ignored (since they do not apply to inline elements). For the third div, however, the inline-block paragraph honors both properties, since it is formatted as a block-level element. That paragraph also forces its line of text to be much taller, since it affects line height as though it were a replaced element.

If an inline-block element's width is not defined or explicitly declared auto, the element box will shrink to fit the content. That is, the element box is exactly as wide as necessary to hold the content, and no wider. Inline boxes act the same way, although they can break across lines of text, just as inline-block elements cannot. Thus, the following rule, when applied to the previous markup example:

 div#three p {display: inline-block; height: 2em;}

will create a tall box that's just wide enough to enclose the content, as shown in Figure 7-52.

Figure 7-52. Auto-sizing of an inline-block element
figs/css2_0752.gif

Inline-block elements can be useful if, for example, you have a set of five hyperlinks that you want to be equal width within a toolbar. To make them all 20% the width of their parent element, but still leave them inline, declare:

#navbar a {display: inline-block; width: 20%;}

7.4.3 Run-in Elements

CSS2 introduced the value run-in, another interesting block/inline hybrid that can make some block-level elements an inline part of a following element. This ability is useful for certain heading effects that are quite common in print typography, where a heading will appear as part of a paragraph of text.

In CSS, you can make an element run-in simply by changing its display value and by making the next element box block-level. Note that I'm talking here about boxes, not the element themselves. In other words, it doesn't matter if an element is block or inline. All that matters is the box that element generates. A strong element set to display: block generates a block-level box; a paragraph set to display: inline generates an inline box.

So, to rephrase this: if an element generates a run-in box, and a block box follows that box, then the run-in element will be an inline box at the beginning of the block box. For example:

<h3 style="display: run-in; border: 1px dotted; font-size: 125%; 

  font-weight: bold;">Run-in Elements</h3>

<p style="border-top: 1px solid black; padding-top: 0.5em;">

Another interesting block/inline hybrid is the value <code>run-in</code>, introduced 

in CSS2, which has the ability to take block-level elements and make them an inline 

part of a following element. This is useful for certain heading effects that are 

quite common in print typography, where a heading will appear as part of a paragraph 

of text.

</p>

Since the element following the h3 generates a block-level box, the h3 element will be turned into an inline element at the beginning of the p element's content, as illustrated in Figure 7-53.

Figure 7-53. Making a heading run-in
figs/css2_0753.gif

Note how the borders of the two elements are placed. The effect of using run-in in this situation is exactly the same as if you'd used this markup instead:

<p style="border-top: 1px solid black; padding-top: 0.5em;">

<span style="border: 1px dotted; font-size: 125%; font-weight: bold;">Run-in

Elements</span> Another interesting block/inline hybrid is the value <code>run-in</

code>, introduced in CSS2, which has the ability to take block-level elements and 

make them an inline part of a following element. This is useful for certain heading 

effects that are quite common in print typography, where a heading will appear as 

part of a paragraph of text.

</p>

However, there is a slight difference between run-in boxes and the markup example. Even though run-in boxes are formatted as inline boxes within another element, they still inherit properties from their parent element in the document, not the element into which they're placed. Let's extend our example to include an enclosing div and some color:

<div style="color: silver;">

<h3 style="display: run-in; border: 1px dotted; font-size: 125%; 

  font-weight: bold;">Run-in Elements</h3>

<p style="border-top: 1px solid black; padding-top: 0.5em; color: black;">

Another interesting block/inline hybrid is the value <code>run-in</code>, introduced 

in CSS2, which has the ability to take block-level elements and make them an inline 

part of a following element.

In this situation, the h3 will be silver, not black, as illustrated in Figure 7-54. That's because it inherits the color value from its parent element before it gets inserted into the paragraph.

Figure 7-54. Run-in elements inherit from their source parents
figs/css2_0754.gif

The important thing to remember is that run-in will work only if the box after the run-in box is block-level. If it is not, then the run-in box itself will be made block-level. Thus, given the following markup, the h3 will remain or even become block-level, since the display value for the table element is (oddly enough) table:

<h3 style="display: run-in;">Prices</h3>

<table>

<tr><th>Apples</th><td>$0.59</td></tr>

<tr><th>Peaches</th><td>$0.79</td></tr>

<tr><th>Pumpkin</th><td>$1.29</td></tr>

<tr><th>Pie</th><td>$6.99</td></tr>

</table>

It's unlikely that an author would ever apply the value run-in to a naturally inline element, but if this happens, the element will most likely generate a block-level box. For example, the em element in the following markup would become block-level because a block-level box does not follow it:

<p>

This is a <em>really</em> odd thing to do, <strong>but</strong> you could do it

if you were so inclined.

</p>

7.4 Altering Element Display

At the time of this writing, very few contemporary browsers offer support for run-in.


7.4.3.1 Computed values

The computed value of display can change if an element is floated or positioned. It can also change when declared for the root element. In fact, the values display, position, and float interact in interesting ways.

If an element is absolutely positioned, the value of float is set to none. For either floated or absolutely positioned elements, the computed value is determined by the declared value, as shown in Table 7-1.

Table 7-1. Computed display values

Declared value

Computed value

inline-table

table

inline, run-in, table-row-group, table-column, table-column-group, table-header-group, table-footer-group, table-row, table-cell, table-caption, inline-block

block

All others

As specified

In the case of the root element, declaring either of the values inline-table or table results in a computed value of table, whereas declaring none results in the same computed value. All other display values are computed to be block.

    Previous Page Table of Contents Next Page