Seong Lee Seong Lee - 16 days ago 5
CSS Question

CSS - make paragraph text wrap around image without float

I can simply use

float
to achieve the text wrap around
<img>
element and I understand that
<img>
is an inline element and
<p>
is a block level element so to make them inline, I should either make
<p>
an inline element or use
<span>
instead.

The thing is that if I treat them all as inline elements, it leaves a huge white space next to the image and on top of the text.

enter image description here

I would like to know what causes the blank space.

Here is my JS Fiddle

Answer

This question seems to be concerned about the why over the how, so I'll focus on the inner-workings:

The Visual formatting model section of the CSS 2.1 spec describes inline formatting contexts:

In an inline formatting context, boxes are laid out horizontally, one after the other, beginning at the top of a containing block. Horizontal margins, borders, and padding are respected between these boxes. The boxes may be aligned vertically in different ways: their bottoms or tops may be aligned, or the baselines of text within them may be aligned. The rectangular area that contains the boxes that form a line is called a line box.

The property they describe is vertical-align which takes a number of different values, baseline being the default. This is why your two inline elements appear as they do, by sitting on the baseline. You could change the <p> to vertical-align: top, and the top of the first line of text will align with the top of the image. However, you will still get a gap between the first line of text and the following lines.

This is because the text is rendering one line-box to the next, vertically. Regardless if the line-box of the first line is larger than the rest, it will still flow one line-box at a time. Here’s a visualization of this concept:

enter image description here

Another important concept in understanding this is that <img> is a replaced inline element, which means its appearance is constructed by an external resource outside of the document. replaced inline elements can take a height value, while so-called non-replaced inline (like a <span>) elements cannot. This is why <img> <span>foo</span> can behave differently than <span>foo</span> <em>bar</em> (because the image has an intrinsic height), even though they are all inline elements. Imagine setting the height of the image to the x-height of the text -- it would effectively render the same as your image, but in this case it behaves exactly as you would expect:

img {
  height: 10px;
  }

p { 
  display: inline;
  }
<div>
    <img src="http://placehold.it/100x100/E8117F/000.png">
    <p>hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello</p>
</div>

This may be where some of the confusion is happening. If you can imagine the lines then you can understand that there is no expectation for inline elements to behave like floated elements.

Compare that information to what the spec says about floats:

A float is a box that is shifted to the left or right on the current line. The most interesting characteristic of a float (or "floated" or "floating" box) is that content may flow along its side (or be prohibited from doing so by the 'clear' property). Content flows down the right side of a left-floated box and down the left side of a right-floated box.

A floated box is shifted to the left or right until its outer edge touches the containing block edge or the outer edge of another float. If there is a line box, the outer top of the floated box is aligned with the top of the current line box.

While I can't describe to you what's happening down to the electron, I hope this is a good starting point in understanding why these different scenarios render how they do.

Comments