Is It Wrong to Change a Block Element to Inline With CSS If It Contains Another Block Element

Is it wrong to change a block element to inline with CSS if it contains another block element?

From the CSS 2.1 Spec:

When an inline box contains an in-flow block-level box, the inline box (and its inline ancestors within the same line box) are broken around the block-level box (and any block-level siblings that are consecutive or separated only by collapsible whitespace and/or out-of-flow elements), splitting the inline box into two boxes (even if either side is empty), one on each side of the block-level box(es). The line boxes before the break and after the break are enclosed in anonymous block boxes, and the block-level box becomes a sibling of those anonymous boxes. When such an inline box is affected by relative positioning, any resulting translation also affects the block-level box contained in the inline box.

This model would apply in the following example if the following rules:

p    { display: inline }
span { display: block }

were used with this HTML document:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HEAD>
<TITLE>Anonymous text interrupted by a block</TITLE>
</HEAD>
<BODY>
<P>
This is anonymous text before the SPAN.
<SPAN>This is the content of SPAN.</SPAN>
This is anonymous text after the SPAN.
</P>
</BODY>

The P element contains a chunk (C1) of anonymous text followed by a block-level element followed by another chunk (C2) of anonymous text. The resulting boxes would be a block box representing the BODY, containing an anonymous block box around C1, the SPAN block box, and another anonymous block box around C2.

The properties of anonymous boxes are inherited from the enclosing non-anonymous box (e.g., in the example just below the subsection heading "Anonymous block boxes", the one for DIV). Non-inherited properties have their initial value. For example, the font of the anonymous box is inherited from the DIV, but the margins will be 0.

Properties set on elements that cause anonymous block boxes to be generated still apply to the boxes and content of that element. For example, if a border had been set on the P element in the above example, the border would be drawn around C1 (open at the end of the line) and C2 (open at the start of the line).

Some user agents have implemented borders on inlines containing blocks in other ways, e.g., by wrapping such nested blocks inside "anonymous line boxes" and thus drawing inline borders around such boxes. As CSS1 and CSS2 did not define this behavior, CSS1-only and CSS2-only user agents may implement this alternative model and still claim conformance to this part of CSS 2.1. This does not apply to UAs developed after this specification was released.

Make of that what you will. Clearly the behaviour is specified in CSS, although whether it covers all cases, or is implemented consistently across today's browsers is unclear.

Can inline elements contain block elements?

Leaving aside the fact that LI and P are both block level ...

It's never valid to do so, but in behavioural terms, sometimes you can nest a block level element inside a inline level one, but it depends on the browser parser.

For example, in FireFox 3.x, with this markup

<!DOCTYPE html>
<i>
foo
<div>bar</div>
baz
</i>

will display foo, bar, and baz all in italics.

But this markup, replacing the inline element <i> with inline element <var> (which also has italics as its default rendering)

<!DOCTYPE html>
<var>
foo
<div>bar</div>
baz
</var>

will only display foo in italics.

JSFiddle for this

Other browsers do not behave the same. Which is one reason why you should stick to using valid markup.

Is it illegal to set the parent of block element to inline display?

CSS rules do not, in any way, influence the validity of markup.

The rules for how to handle display: block elements inside display: inline elements can be found in the CSS specification.

When an inline box contains an in-flow block-level box, the inline box (and its inline ancestors within the same line box) are broken around the block-level box (and any block-level siblings that are consecutive or separated only by collapsible whitespace and/or out-of-flow elements), splitting the inline box into two boxes (even if either side is empty), one on each side of the block-level box(es). The line boxes before the break and after the break are enclosed in anonymous block boxes, and the block-level box becomes a sibling of those anonymous boxes. When such an inline box is affected by relative positioning, any resulting translation also affects the block-level box contained in the inline box.

Is it possible for an inline element to validly have a block level element descendant?

The W3C validator (in XHTML mode) lists the following elements as valid between a <span> and a <p>:

  • object
  • ins
  • del
  • map
  • button

A page using these as inline-to-block spanners validates in XHTML Strict, but not in HTML 5. Of these tags, I would favor object, since it has the least semantic baggage.

HTML 5 seems to have discarded the inline vs. block distinction in favor of a more complex system, in which there are several different categories of element, and which children an element can have depends on what its ancestors are. Of these elements, ins, del and map now accept the same kind of children that their parent element accepts, and button only accepts "phrasing content" (the closest thing to inline elements). The error message for object doesn't make much sense, but as near as I can gather, it's inheriting the parent element's restrictions while also imposing some restrictions of its own.

As near as I can tell, there's no way to escape from phrasing content once you're in it (short of an iframe and a new document), so the answer to this question is no, can't be done in HTML5 (as of this writing).

Shrink inline block element if it can't fit the container having another absolute element inside

If you switch the order of your elements so that the "tags" element is first:

<div class="document-belt">
<div class="tags">sometag</div>
<a class="link">some_very_looong_file_name.txt</a>
</div>

Then the following will work:

.document-belt { 
overflow:hidden;
border: 1px solid blue;
width:250px;
}

.link {
display: block;
margin-left:0px;
overflow:hidden;
text-overflow: ellipsis;
white-space: nowrap;
border: 1px solid red;
}

.tags {
float:right;
border: 1px solid green;
}

http://jsfiddle.net/vTm75/11/



Related Topics



Leave a reply



Submit