Search code examples
htmlcsswhitespaceword-wrapline-breaks

How to line-break an HTML list on last possible white space


I have a simple HTML list:

<ul>
  <li>First Item</li>
  <li>Second Item</li>
  <li>Third Item</li>
</ul>

I want to display the list with the following features:

  1. Items in a row.
  2. List would have a maximum width, after which items are expected to break to the next line.
  3. Items should only break on beginning / spaces (not mid-word).
  4. Lines should contain the most text possible before breaking.

Desired outcome:

[   maximum width   ]
First Item * Second
Item * Third Item

Failed attempts:

#1 (word breaks)

[   maximum width   ]
First Item * Second I
tem * Third Item

#2 (item doesn't break properly)

[   maximum width   ]
First Item * Second Item
* Third Item

#3 (line breaks "prematurely")

[   maximum width   ]
First
Item * Second Item *
Third Item

Update: A simple li {display: inline;} won't work if the HTML is not indented / spaced (some frameworks -- say, GatsbyJS -- automatically "squeeze" the HTML):

<ul><li>First Item</li><li>Second Item</li><li>Third Item</li></ul>

(Fiddle example)


Solution

  • This seems to work for me:

    ul {
        max-width: 100px;
    }
    ul li {
        display: inline;
    }
    ul li::after {
      content:" ";
    }
    

    Why the after part?

    Well, unless there is a white-space / new-line after each <li> in the HTML source, the line won't break at the end of items, which may very well cause a "premature" line-break (as in the failed attempt #3). Some frameworks automatically "squeeze" the HTML -- basically removing these white-spaces -- and this requires an explicit space to be added after each item.

    Here's a Fiddle examples (try removing the after from the css and see how you get failed attempt #3).