Hero image

Playing with Flow

What is flow?

Flow is the default layout algorithm used by browsers, and although it has some popular competitors is still has some great use cases.

The idea for flow comes from how a physical document would be designed, where one block of content comes after another. For instance, a paragraph would be followed by another paragraph with a bit of spacing between them.

This article isn’t here to tell you what flow is but instead here to give decent insights into how it works. If you want to know more MDN does a great job of explaining this in a great amount of detail.

Now that is out of the way, lets look at some of the interesting features of flow.

Box model

A fundamental concept in CSS and browser rendering in the Box Model. The box model is simply a definition of the different parts that make up an individual element on the page. The parts are:

  1. Margin
  2. Border
  3. Padding
  4. Content

Note that every element on the page has its own box, meaning you can customise the spacing of anything you like.

Have a play with the below widget to see what each part of the model is. It is set to change all sides of the box equally, but know that each side has its own option that can be defined, set by *-top, *-right, *-bottom, and *-left.


Margin Collapse

Flow layout uses a concept called Margin Collapse. This is where adjacent elements will have their vertical margins overlap down until the larger margins size has been met.

For instance, if an element has a bottom margin of 10px and its next sibling has a top margin of 20px the total space between them will be 20px, not 30px like you may expect.

Have a play with the following sliders to see this in affect. You will notice that the default values add up to 100px, but the actual margin is taking up 80px. This is margin collapse in action.

Some content
First 20px
Some content
Second 80px

Total margin size: 80px

Text in flow

Flow is designed to do its best in making sure your content is available, and it is not overlapping any other content. It does this by making sure that each box is in its own space according to its given box model settings. But what happens if the parent box is smaller than the child content?

By default the browser will do its best to make sure your content is visible. In flow this means that it will display the content even when it is outside its parents bounds. The idea behind this is that poorly formatted content is better than missing content. To change this behaviour you can use the overflow property on the parent container.

This is some text content that will be overflowing the parent element. You can modify they way the element handles the overflowing content by changing the values of the controls above.

You can also change the individual horizontal X overflow or vertical Y overflow individually using overflow-x and overflow-y.

Custom paths in flow

To really customise the flow layout you can use properties that change the shape of the box used to clip or wrap text.

The properties clip-path and shape-outside can be combined to give some really great effects when you have text next to a stylistic element, such as an image, or blob of colour.

You can do this other ways too, but using flow gives a lot of safe-guards for content overlapping and will do its best to keep things visible on the page.

Take the below example, where I have some text next to a floating block of colour at 50% width and 100% height.

This is some text content that I want to have wrap automatically wherever the colour blob div is not.

By default both elements are taking up 50% of the parent container, and the text is staying withing its element. Lets add a clip path to the left edge of the colour blob to see what happens. Starting from the top left corner and working clockwise around the box we can set where each limit is. Lets set:

  • Top left: 60px 0% - moves the top left part of the blob 60px further
  • Top right: 100% 0% - default top right position
  • Bottom right: 100% 100% - default top right position
  • Bottom left: 0% 100% - default bottom left position

The full style looks like:

clip-path: polygon(60px 0%, 100% 0%, 100% 100%, 0% 100%);

This is some text content that I want to have wrap automatically wherever the colour blob div is not.

This has given a nice angle to the colours, but the text is still wrapping at its original location. To fix this we can also add the shape-outside path. The shape-outside path in this case should be set to be exactly the same as the clip path.

This is some text content that I want to have wrap automatically wherever the colour blob div is not.

You should now see a difference between the wrapping of the original element vs the new one, where text can now go beyond the 50% mark of the parent element.

This looks alright, but we have only explored what is possible with the coloured blobs paths. Lets add some to the text content too. Lets say you want to overlap the colours but keep the text wrapping at the intersect between the two elements.

Using a clip path on the text content will keep the text wrapping with flow, but allow the non-text content to overlap.

Note: I added a top margin to the text content to move it down a bit for a better looking style.

This is some text content that I want to have wrap automatically wherever the colour blob div is not.

What to read more? Check out more posts below!