Grow your CSS skills. Land your dream job.

Minimum Paragraph Widths in Fluid Layouts

Published by Guest Author

The following is a guest post by Gustav Andersson who has come up with a clever little technique for a text flow problem. I've struggled with this myself in the past, so I'm happy to add this technique to the ol' toolbox. Not mention, yet another one of these.
An example where a floating image leaves only enough space for a very narrow column of text which looks ugly and is broken up be a long word.
An example where a floating image leaves a few orphaned words.

A floating image takes away horizontal space from the text that flows around it. In fixed width layouts, you can check that the space left for the text is enough to create a decent looking column, safe in the knowledge that everyone else will see the same thing.

In a fluid layout, however, you have no such guarantee. If a user views your site on a smaller device, the horizontal space left for the text may only fit a word or two per line. Such a narrow column of text doesn't just look ugly; it is also brittle. A sentence containing a long word will split when the long word moves down below the floating image, leaving behind it dead empty space mid-sentence.

The elusive minimum paragraph width

To solve the problem of too narrow paragraphs, we need a way to implement a minimum paragraph width. If the space left by the floating image is below this width, then the whole paragraph moves down underneath the image.

Same example as above, but with a red border around the paragraph, showing that it extends behind the  image.
The red border is the boundary of the paragraph element.

Intuitively, the following CSS seems to fit the bill:

p {
  min-width: 10em;
  /* For demonstration */
  border: 1px solid red;
}

However, this has no effect. The image floats above the paragraph, and thus doesn't reduce the paragraph's 'official' width. Meanwhile, the text within the paragraph dutifully moves aside to make room for the floating image, and so the problem remains.

The media query solution for known image widths

An example showing how the media query has disabled the floating of the image, and the entire paragraph is underneath.
The Media Query solution works, but requires fixed-width images.

If your images (or other floating content) share a fixed and predefined width, then you can use CSS3 media queries to disable the floating at screen sizes that are too narrow to fit both an image and a text column side by side.

This solution will of course only work on browsers that support CSS media queries. For other browsers, the solution degrades to the original problem.

@media screen and (max-width: 400px) {
  img {
    float: none;
  }
}

General case solution using pseudo element

The media query solution doesn't work when the floating elements have arbitrary widths, nor is it very elegant.

An example of the pseudo-element rule in place, showing a thin green border surrounding the pseudo element. Both the element and the paragraph are below the image.
This example shows the pseudo-element rule in place, showing a thin green border surrounding the pseudo element. Both the element and the paragraph are below the image.

A better solution is to give every paragraph an invisible CSS pseudo-element with the desired minimum paragraph width. If there isn't enough space to fit this pseudo-element, then it will be pushed down underneath the image, taking the paragraph with it.

This solution is supported by most browsers. On older browsers, the solution degrades gracefully to the original problem.

p:before {
  content: "";
  width: 10em;
  display: block;
  overflow: hidden;
  /* For Demonstration */
  border: 1px solid green;
}

The pseudo element's green border is there for demonstration purpose only. It is not required for the solution and you should remove it in your code. The pseudo element will then take no vertical space at all.

Demo & Download

View Demo   Download Files

 

About the Author

Gustav Andersson is the author behind The Modern Nomad, a site exploring nomadic lifestyles which frees people to live and work anywhere, anytime. He is a tango-dancing, steer-wrestling, grammar-loving burner who wants to inspire you to consider a life without an address.


Comments

  1. Interesting solution regarding the pseudo element.
    I’ve used the float:none before and hadn’t thought about the other one. Will try it next time.

  2. Robson Sobral
    Permalink to comment#

    Great idea!

    I’m on mobile, so I can’t test, but I believe that and adjacent selector could be useful here: “img + p:before”.

  3. Great advice, will try it out very soon.

  4. Nice tip. Worth trying

  5. Permalink to comment#

    Nice, very clever.

  6. Schmotty
    Permalink to comment#

    This works great if you keep your img tag before or after the paragraph. If you put an image in the midst of it, then the paragraph won’t maintain its minimum width.

  7. This only works if we float the image to the right. What about float left? Should we also have to float the pseudo element to the right, or move the pseudo element to the right with absolute position? I think media queries are still the best solution, we can simply get the algnment class from the images, then disable the float, or just make the pseudo element via media queries:

    @media screen and (max-width: 400px) {
        .alignleft, .alignright {
          float:none;
          display:block;
        }
        p:before {
          content:"";
          display:block;
          width:100%;
          clear:both;
        }
    }
  8. Permalink to comment#

    Hi,

    Do common email clients support this css trick? Could this be a way to avoid using tables?

  9. Great tip. I’m sure i’ll be using this a lot.

  10. You could also give the image a max width… Eg 50% of a P.

  11. you just gave me a one great tip, i’m sure i’m gona use this

  12. rainmakr
    Permalink to comment#

    This doesn’t work for me in FF 11.0 without a top border (border-top:1px solid transparent) on the P tag — it reverts to the original problem.

    It works as described in IE8, I have not had a chance to test other browsers.

  13. Nice post man! I personally use min-width for just about everything now, lol. RWD all the way!

  14. Thomas Dybdahl Ahle
    Permalink to comment#

    What we really need is breaking lines with hyphens. Wonder when webbrowsers get advanced enough for that.

  15. A very helpful workaround! Thank you for the in-sight, I am sure this will come in useful.

  16. Nice post – thanks for sharing :)

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".