Layouts in CSS: Floating Elements and Normal Flow

When we float an item by setting the value of the float , we remove it from the normal flow. Instead of stacking in the block direction, the box is shifted to either end of the current line until its edge aligns with the containing block or another floated element. float has four possible values:

  • Left , which shifts the box to the left of the current line
  • right , which shifts the box to the right of the current line
  • inline-start , which shifts the box to the start of the current line
  • inline-end , which shifts the box to the end of the current line

Both inline-start and inline-end depend on the language direction of the document. For languages that are written and read horizontally, from left to right, inline-start aligns the box to the left, while inline-end shifts it to the right. For languages that are written and read from right to left, such as Arabic, inline-start shifts the box to the right and inline-end shifts it to the left. When the language is written vertically, inline-start is the top of the container, and inline-end is the bottom.

Content flows along the far edge of a floated box if there’s enough horizontal space. If, for example, we left-float an image that’s 300 pixels wide by 225 pixels high, the adjacent lines of text fill in along its right edge. If the computed height of the content exceeds 225 pixels, the text wraps around the bottom of the image.

If, however, the computed height of the remaining content is shorter than 200 pixels, the floated element overflows its container.

Text in sibling elements will also flow along the edge of a float if there’s enough room. The length of each line—its line box-will be shortened to accommodate the float.

Floating a series of elements works a little bit differently. Let’s apply float: Left to a series of <div> elements that are 500 pixels wide inside a container that’s 1500 pixels wide. As you can see in the image below, these elements stack horizontally to fill the available space. Elements that don’t fit in the available horizontal space will be pushed down until the box fits or there are no more floated elements.

Floated elements don’t wrap neatly. Yet before Flexbox and Grid layout, developers used floats to create gridded layouts. This requires setting an explicit height value to elements within a floated grid to ensure that elements don’t “snag” on previously floated elements. The drawback, of course, is that you have to adjust the height of every element should the content require it, or edit your text and images to ensure that they don’t overflow the container, as is happening in the image below.

Removing elements from the normal flow can be tricky. Other content in the document will want to cozy up next to a floated element, but that may not be the layout we’re trying to achieve.

Consider the UI pattern known as a media object. A media object consists of an image or video thumbnail that’s aligned to the left or right of its container, accompanied by some related text. You’ve probably seen this style of component in comments sections, on news sites, or as part of YouTube’s “Up Next” feature.

Here’s what the markup for a media object might look like:

<div class=”media__ object”>

<img src=”video_thumbnail.]pg”>

<div class=”media__ object_ text”>

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt utlabore et dolore magna aliqua.

</div>

</div>

The media object is a simple pattern: it consists of an image placed to the left or right of its container and some related text. Floating an image is one way to create a media object layout:

.media_ object {

background: #ccc;

padding: 1rem;

}

.media_ obj’ect img {

float: left;

margin-right: 1rem;

}

The drawback of simply floating an image is that the height of the accompanying text may be shorter than the height of the floated image. When that happens, our container will collapse to match the height of the text. Content in adjacent elements will flow around the floated element, as illustrated in the image below.

To prevent this, we need to clear our float. That is, we need to force the container to wrap around its floated contents. Let’s look at some methods for doing so in the next section.

1. Clearing Floats

The simplest way to clear a float is to establish a new block formatting context for its container. A block formatting context always contains its children, even when those children are floated.

So how do we create a new block formatting context? We have a couple of options.

Using display: flow-root

One way is to use the display: flow-root property. Let’s add display: flow-root to our .media_object rule set:

.media_ object {

background: #ccc;

padding: 1rem;

display: flow-root;

}

.media_ obj’ect img {

float: left;

margin-right: 1rem;

}

Now our floated image is completely contained by its parent, as shown below.

The fLow-root value for the display property is a fairly recent addition to CSS. Its sole purpose is to trigger a block formatting context for a containing element. It’s well supported in modern browsers, but it’s not the only option for creating a new block formatting context.

Using the contain Property

The contain property is a performance-related property. Its purpose is to constrain reflow
and repaint operations to an element and its children, instead of the entire document. However, it also creates a new block formatting context for that element. That means we can also use it to clear floats.

Let’s update our CSS. We’ll float the image to the right this time. The image below shows what our media objects look like before clearing the float.

Now let’s add contain: content to the .media__object rule set:

.media_ object {

background: #ccc;

padding: 1rem;

contain: content;

}

.media_ obj’ect–right img {

float: right;

margin-left: 1rem;

}

Now our .media__object elements encompass their floated image children.

Unfortunately, Safari versions 15 and below don’t support the contain property. Since display: flow-root has broader compatibility, use that instead.

For older browsers—versions of Firefox prior to 52, Chrome prior to 57, Safari prior to 13, Edge prior to 79, and every version of Internet Explorer—use the “clearfix” method.

2. Clearfix

Clearfix uses the ::after pseudo-element and the content property to insert a box at the end of a containing element. Since pseudo-elements can be styled like actual elements, we can apply display: table (or display: block ) and clear: both to clear our float:

.media_ object::after {

content: ‘”‘;

display: table;

clear: both;

}

Floats are best used for aligning images and tables to the left or right, or for placing content asides within a page. For most other uses, Flexbox and Grid are better choices. Flexbox and Grid typically require less markup and less CSS, while offering more flexibility in the kinds of layouts we can create. Grid and Flexbox also make vertical centering remarkably easy, as we’ll see later in this chapter.

But first, let’s discuss another way to remove elements from the normal flow: the position and z-index properties.

Source: Brown Tiffany B (2021), CSS , SitePoint; 3rd edition.

Leave a Reply

Your email address will not be published. Required fields are marked *