Consider the following HTML:
<div class='x'>
<ul>
<li>Number one</li>
<li>Number two</li>
<li>Number three</li>
<li>Number four is a bit longer</li>
<li>Number five</li>
</ul>
</div>
and the following CSS:
.x {
-moz-column-count: 3;
column-count: 3;
width: 30em;
}
As it stands, Firefox currently renders this similarly to the following:
• Number one • Number three bit longer
• Number two • Number four is a • Number five
Notice that the fourth item was split between the second and third column. How do I prevent that?
The desired rendering might look something more like:
• Number one • Number four is a
• Number two bit longer
• Number three • Number five
or
• Number one • Number three • Number five
• Number two • Number four is a
bit longer
Edit: The width is only specified to demonstrate the unwanted rendering. In the real case, of course there is no fixed width.
The correct way to do this is with the break-inside CSS property:
.x li {
break-inside: avoid-column;
}
Unfortunately, as of October 2019, this is not supported in Firefox but it is supported by every other major browser. With Chrome, I was able to use the above code, but I couldn't make anything work for Firefox (See Bug 549114).
The workaround you can do for Firefox if necessary is to wrap your non-breaking content in a table but that is a really, really terrible solution if you can avoid it.
UPDATE
According to the bug report mentioned above, Firefox 20+ supports page-break-inside: avoid
as a mechanism for avoiding column breaks inside an element but the below code snippet demonstrates it still not working with lists:
.x {
column-count: 3;
width: 30em;
}
.x ul {
margin: 0;
}
.x li {
-webkit-column-break-inside: avoid;
-moz-column-break-inside:avoid;
-moz-page-break-inside:avoid;
page-break-inside: avoid;
break-inside: avoid-column;
}
<div class='x'>
<ul>
<li>Number one, one, one, one, one</li>
<li>Number two, two, two, two, two, two, two, two, two, two, two, two</li>
<li>Number three</li>
</ul>
</div>
As others mention, you can do overflow: hidden
or display: inline-block
but this removes the bullets shown in the original question. Your solution will vary based on what your goals are.
UPDATE 2 Since Firefox does prevent breaking on display:table
and display:inline-block
a reliable but non-semantic solution would be to wrap each list item in its own list and apply the style rule there:
.x {
-moz-column-count: 3;
-webkit-column-count: 3;
column-count: 3;
width: 30em;
}
.x ul {
margin: 0;
-webkit-column-break-inside: avoid; /* Chrome, Safari */
page-break-inside: avoid; /* Theoretically FF 20+ */
break-inside: avoid-column; /* IE 11 */
display:table; /* Actually FF 20+ */
}
<div class='x'>
<ul>
<li>Number one, one, one, one, one</li>
</ul>
<ul>
<li>Number two, two, two, two, two, two, two, two, two, two, two, two</li>
</ul>
<ul>
<li>Number three</li>
</ul>
</div>