Block-Level and Inline Elements

One of the key concepts to understanding properly structured HTML
is the idea of block-level and inline elements. These elements form a hierarchy
within a document, and there are definite rules about how they are used, and
which element can contain another. Violating these rules may not cause a problem
in displaying your page, since most browsers do not implement the rules of HTML
with any precision. But if you try to validate your code, a mistake in using
these elements will definitely cause an error report.

W3C definitions

So what are these elements, anyway? To begin, let’s see what the
W3C has to say about them.

7.5.3 Block-level and inline elements

Certain HTML elements that may appear in BODY are
said to be “block-level” while others are “inline” (also known as “text level”).
The distinction is founded on several notions:

Content model

Generally, block-level elements may contain inline
elements and other block-level elements. Generally, inline elements may contain
only data and other inline elements. Inherent in this structural distinction
is the idea that block elements create “larger” structures than inline elements.

Formatting

By default, block-level elements are formatted differently
than inline elements. Generally, block-level elements begin on new lines,
inline elements do not. For information about white space, line breaks, and
block formatting, please consult the section on text.

Directionality

For technical reasons involving the [UNICODE] bidirectional
text algorithm, block-level and inline elements differ in how they inherit
directionality information. For details, see the section on inheritance of
text direction.

Style sheets provide the means to specify the rendering
of arbitrary elements, including whether an element is rendered as block or
inline. In some cases, such as an inline style for list elements, this may
be appropriate, but generally speaking, authors are discouraged from overriding
the conventional interpretation of HTML elements in this way.

The alteration of the traditional presentation
idioms for block level and inline elements also has an impact on the bidirectional
text algorithm. See the section on the effect of style sheets on bidirectionality
for more information.

So, looking at this crystal clear description, what does it mean?
Several things. Let’s look at each in order.

Containing

A block-level element may contain other block-level elements, or it may contain
inline elements. But inline elements cannot contain block-level elements, only
data or other inline elements. So a block-level element is “bigger”
or “higher” in the hierarchy. It defines a larger section of of the
page than an inline element does.

Spacing

Block-level elements generally begin on new lines. In practice, most browsers
insert a blank line between any two block-level elements. So if you have a paragraph
(block-level), and you end that paragraph and begin another paragraph, there
will be blank line between them. Same thing between a header and a paragraph,
between two headers, between a paragraph and a list, between a list and a table,
etc. This is a useful clue as to what a block-level element is. You need these
clues because it is very difficult to find a sensible list of what the block-level
elements are.

Inline elements do not start on a new line. If you type out a paragraph, and
decide to make one of the words italic, does the browser jump down a line for
the italic word? No, it doesn’t and this is a clue as well. The italic tag is
an inline tag. So is bold, strong, em, a href, etc. None of these tags causes
the browser to start a new line, so these are all inline elements.

A partial list of each type of element

With the clues we now have, let’s compile a partial list of the elements on
each type. First, the block-level elements:

  • div
  • h1…h6
  • p
  • ul
  • ol
  • li
  • table
  • tr
  • td
  • th
  • blockquote

Now, the inline elements:

  • i
  • b
  • a href
  • a name
  • em
  • strong
  • q

Now, these are partial lists. I have not had the time to compile a complete
list, and with the move the XML I’m not sure it is even possible, since in XML
you can create your own tags. But the rules are what matters in this case. And
the status of some tags does not quite fit this model. A good example is the
IMG tag, which manages to be both a block-level and an inline element, depending
on where you put it. Don’t worry about that, it only gives you a headache to
think about it too much.

If you look at the list again, you may discern a trend. Block-level elements
generally describe the structure of your data, while inline
elements generally describe the appearance of your data. It
isn’t a perfect fit, but a good rule of thumb to use in getting used to these
ideas.

The Hierarchy

So, what does this mean for the rules of containment that make up the hierarchy
of a well-formed HTML page? The first rule is that an inline element cannot
contain a block-level element. If you have an i tag, and inside
of that a p tag, that is a no-no. But if you have an i
tag, and inside of that a b tag, no problem. If you want your
links to stand out by making them italic or bold, you can place an i
tag or a b tag, or even both, inside of the a href
tag, and as long as you nest them properly, it is perfectly valid. But you must
be certain to do one thing: every inline element must be inside of a block-level
element. The reason is the inline elements usually do not have any structural
role to define, since that is handled by the block-level elements. That is why
an a href tag all by itself is not proper. It can be contained
by a p tag, or an li tag, or an h1
tag, to name a few, but left out by itself is not a good idea.

While inline elements can contain any other inline elements, with only the
rules of proper nesting to worry about, the same cannot be said of block-level
elements. Some are bigger than others. Top of the hierarchy is the div
tag. This tag can contain any other block-level element. But you cannot contain
a div inside another block-level element. So, placing
a div tag inside of a p tag, or a table
tag, is not proper. A div tag can contain multiple block-level
elements, as well. You can have a few headers, several paragraphs, a list, and
a table, all inside of one div tag set.

At the other end is the paragraph tag. This tag cannot contain any
other block-level elements. Period. Section 9.3.1 of the HTML specification
says this very clearly:

The P element represents a paragraph. It cannot contain
block-level elements (including P itself).

So a paragraph can only contain inline elements. If you want to start a list,
you end the paragraph and then start the list as a new block-level element.
Headers and lists should also be treated this way. They may contain inline elements,
but not other block-level elements.

The intermediate position is occupied by tables. The td tag
may contain other block-level elements, and in some cases very definitely should.
Many designers use tables as a device for controlling page layout, and place
all of the content of their pages inside of tables with invisible borders. While
this technique is frowned upon by W3C, which would prefer to see everyone use
Cascading Style Sheets (CSS) for this purpose, as a practical matter many designers
need to use tables to make their pages accessible to people with older browsers
that cannot make sense of CSS, generally any browser before the 4.x versions
of Netscape and Internet Explorer. If you are doing this, then all of the elements
of your page should receive the proper tags for each block-level element. The
only one you should not use in this context is the div tag.
But you can use any of the other block-level tags inside of a td
tag without problems. Note that if you are using a table as a table, as God
and Tim Berners-Lee intended, you do not need to use any additional block-level
tags. It is only when you are using tables for page layout that you should incorporate
these tags.