How to prevent column break within an element?
Asked Answered
W

19

356

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.

Woodberry answered 16/10, 2011 at 15:44 Comment(1)
have you tried to give that li a standalone style? like <li style="width: ???px">Number four is a bit longer</li> ???px = needed width to fit that number four.Meetly
P
560

The correct way to do this is with the break-inside CSS property:

.x li {
    break-inside: avoid-column;
}

Unfortunately, as of October 2021, this is still 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;
    page-break-inside: avoid;           /* Theoretically FF 20+ */
    break-inside: avoid-column;         /* Chrome, Safari, 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>
Pyroelectric answered 16/10, 2011 at 16:37 Comment(14)
I believe Opera 11.5 supports break-inside: avoid-columnWilled
Looking at Comment 15 page-break-inside:avoid should work in FF 20.Pyroelectric
Internet Explorer 10 supports break-inside: avoid-column.Enactment
At year 2014, the right syntax seems to be: -webkit-column-break-inside:avoid; -moz-column-break-inside:avoid; -o-column-break-inside:avoid; -ms-column-break-inside:avoid; column-break-inside:avoid; Corwin
@CarlesJoveBuxeda Not seeing any improvement in Firefox 31. Neither column-break-inside or page-break-inside (with or without prefix) are working.Pyroelectric
Opera doesn't support -o-column-break-inside: avoid; But is does support; -webkit-column-break-inside: avoid;Dissimilarity
It's a little late, but as this is still an issue in 2018 this might be useful to others who end up here. If anyone is still having bugs between browsers with this, overflow: hidden is the better option. display: inline-block; causes new quirks with Chrome, unfortunately.Empedocles
I cannot make it work in Chrome and that's exactly what's written on canIuse: Partial support refers to not supporting the avoid-column, column, and avoid (in the column context) values for the properties break-before, break-after, and break-inside.Menke
update: it is broken when an inside container element has relatively big vertical margin. Replacing margin with empty gutter element fixed the issueMenke
Use both avoid and avoid-column. Seems to work across all standard browsersFeinberg
@BrianNickel May be time to update this as Firefox v82.0 (out this month) release notes say they added support for this property.Muddlehead
Tested on Firefox 97.0.1, break-inside: avoid-column; works perfectly.Cavazos
@Cavazos I still see the issue in 97.0.1. <li style="break-inside: avoid-column"> still breaks.Pyroelectric
Wonderful, this solution resolved me column elements breaking and spreading out over the second column in Safair. Thank you.Demi
A
213

Adding;

display: inline-block;

to the child elements will prevent them being split between columns.

Attribute answered 9/5, 2012 at 13:7 Comment(9)
This is good. A possible way to prevent the bad behavior of inline-block causing stuff to now get squished on one line (if they are too short) is to further wrap this with a display:block element. This will likely be a solid Firefox workaround for now.Agrigento
This solution removes the list item, so if you're using order lists for example this wouldn't be an alternative.Eulogia
Works perfectly for splitting up paragraphs into columns.Levey
for list items, this can work if you embed the content of the list item (li) within a "span" element set with the "display:inline-block". The situation is much more complex if you want to control where to break pages or columns within tables : you would like to avoid breaks within table rows (tr). Really, multi-columns layouts are still difficult to setup, but we need it to allow sites to adapt to very narrow screens (such as smartphones) and to wide displays (where very narrow colulns are really unfair.Lelalelah
For now the only solution is to create separate pages for several pagewidths, using columns broken manually using tables (and hope that no accesibility option or zoom will change the font sizes! Developers of browser should really work seriously on multi-columns because smartphones are now spreading, but there are still lot of users wanting to use their wide screens or TV !Lelalelah
Works for my <li> but I had to add width:100%; to prevent them from stacking horizontally.Isosceles
weird that display:block won't let firefox prevent splittingMunmro
@StevenLu - as at 2020, wrapping this in a display:block element now seems to stop this from working in FireFoxOutlaw
I have two columns, and this (as opposed to break-inside: avoid-column;) allowed the child to remain in the first column rather than being moved to the second.Ebonize
C
57

set following to the style of the element that you don't want to break:

overflow: hidden; /* fix for Firefox */
break-inside: avoid-column;
-webkit-column-break-inside: avoid;
Champerty answered 2/7, 2013 at 0:13 Comment(2)
nice. works for colum text paragraph as well. Added overflow: hidden to the <p> ind the <div> with the columns. Works for FF.Adenosine
Actually, the overflow:hidden rule is not a fix for the other rules, it is what causes the nonbreaking layout…Payne
C
26

As of October 2014, break-inside still seems to be buggy in Firefox and IE 10-11. However, adding overflow: hidden to the element, along with the break-inside: avoid, seems to make it work in Firefox and IE 10-11. I am currently using:

overflow: hidden; /* Fix for firefox and IE 10-11  */
-webkit-column-break-inside: avoid; /* Chrome, Safari, Opera */
page-break-inside: avoid; /* Firefox */
break-inside: avoid; /* IE 10+ */
break-inside: avoid-column;
Colwen answered 29/10, 2014 at 18:21 Comment(1)
This seems to be the most exhaustive listBlameful
D
16

Firefox now supports this:

page-break-inside: avoid;

This solves the problem of elements breaking across columns.

Death answered 29/6, 2013 at 11:0 Comment(3)
Have you got this working? I am looking at this fiddle in FF 22 and it doesn't work: jsfiddle.net/bnickel/5qwMfPyroelectric
Same here, doesn't work in Firefox 22. Also, Firebug only displays page-break-before: or page-break-after: but not page-break-inside:Eulogia
Version 28 of Firefox. This is the only one that works for me yet, thanks!Searcy
V
11

This works for me in 2015 :

li {
  -webkit-column-break-inside: avoid;
  /* Chrome, Safari, Opera */
  page-break-inside: avoid;
  /* Firefox */
  break-inside: avoid;
  /* IE 10+ */
}
.x {
  -moz-column-count: 3;
  column-count: 3;
  width: 30em;
}
<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>
Virginity answered 21/12, 2015 at 11:12 Comment(1)
This is working for me on ul elements, is posted on CSS tricks: css-tricks.com/almanac/properties/b/break-inside, and seems correct based on caniuse compatibility notes: "Partial support refers to not supporting the break-before, break-after, break-inside properties. WebKit- and Blink-based browsers do have equivalent support for the non-standard -webkit-column-break-* properties to accomplish the same result (but only the auto and always values). Firefox does not support break-* but does support the page-break-* properties to accomplish the same result."Longsome
D
10

The accepted answer is now two years old and things appear to have changed.

This article explains the use of the column-break-inside property. I can't say how or why this differs from break-inside, because only the latter appears to be documented in the W3 spec. However, the Chrome and Firefox support the following:

li {
    -webkit-column-break-inside:avoid;
       -moz-column-break-inside:avoid;
            column-break-inside:avoid;
}
Decerebrate answered 6/11, 2013 at 21:53 Comment(4)
This does not work for a general <div class="a"> where "a" replaces your "Li" above. The div still broke inside. FF 26Uppsala
Not a bug. the code above is correct for the described function even if its selector is just for an li element. You could still use another CSS selector "div.a {...}" instead of "li{...}" in this sample.Lelalelah
However Chrome still does not support -webkit-column-break-inside:avoid; on a table row: this does not work and we still cannot avoid breaking tables in bad positions (notably if a tale cell does not just contain text but icons; but Chrome also appears to split at any vertical position in the middle of a text line, breaking the text with the upper part of text glyphs at bottom of the first column, and the lower part of text glyphs at top of the next column !!! The result is absolutely unreadable !!!Lelalelah
As of 2017, column-break-inside does not seem to be a valid css property. MDN only says "Edge also supports the non-standard -webkit-column-break-inside variant."Reinhard
A
7

I faced same issue while using card-columns

i fixed it using

 display: inline-flex ;
 column-break-inside: avoid;
 width:100%;
Adalbert answered 7/6, 2018 at 9:50 Comment(1)
Same here. With my li {display: flex} multiple elements on 2 columns breaking somewhere in the middle of li it helped to change to li {display: inline-flex}.Damondamour
N
5

The following code works to prevent column breaks inside elements:

-webkit-column-break-inside: avoid;
-moz-column-break-inside: avoid;
-o-column-break-inside: avoid;
-ms-column-break-inside: avoid;
column-break-inside: avoid;
Neurovascular answered 13/6, 2017 at 16:12 Comment(0)
B
4

Firefox 26 seems to require

page-break-inside: avoid;

And Chrome 32 needs

-webkit-column-break-inside:avoid;
   -moz-column-break-inside:avoid;
        column-break-inside:avoid;
Beisel answered 13/1, 2014 at 15:14 Comment(0)
C
4

In 2019, having this works for me on Chrome, Firefox and Opera (after many other unsuccessful attempts):

.content {
    margin: 0;
    -webkit-column-break-inside: avoid;
    break-inside: avoid;
    break-inside: avoid-column;
}

li {
    -webkit-column-break-inside:avoid;
       -moz-column-break-inside:avoid;
            column-break-inside:avoid;
           break-inside: avoid-column;
             page-break-inside: avoid;
}
Charwoman answered 12/3, 2019 at 21:5 Comment(0)
E
3

I just fixed some divs that were splitting onto the next column by adding

overflow: auto

to the child divs.

*Realized it only fixes it in Firefox!

Enki answered 1/2, 2015 at 6:44 Comment(0)
A
3

I had the same problem i think and found a solution in this:

-webkit-column-fill: auto; /* Chrome, Safari, Opera */
-moz-column-fill: auto; /* Firefox */
column-fill: auto;  

Working also in FF 38.0.5: http://jsfiddle.net/rkzj8qnv/

Adenosine answered 1/7, 2015 at 14:14 Comment(0)
D
3
<style>
ul li{display: table;}  
</style>

works perfectly

Douche answered 5/9, 2018 at 13:5 Comment(1)
This removes bullets in a listNeoptolemus
G
2

A possible workaround for Firefox is to set the CSS property "display" of the element you don't want to have a break inside to "table". I don't know if it works for the LI tag (you'll probably lose the list -item-style), but it works for the P tag.

Gigantic answered 10/3, 2012 at 18:5 Comment(1)
This solution removes the list item, so if you're using order lists for example this wouldn't be an alternative.Eulogia
A
2

I made an update of the actual answer.

This seems to be working on firefox and chrome: http://jsfiddle.net/gatsbimantico/QJeB7/1/embedded/result/

.x{
columns: 5em;
-webkit-columns: 5em; /* Safari and Chrome */
-moz-columns: 5em; /* Firefox */
}
.x li{
    float:left;
    break-inside: avoid-column;
    -webkit-column-break-inside: avoid;  /* Safari and Chrome */
}

Note: The float property seems to be the one making the block behaviour.

Aristotelianism answered 23/3, 2014 at 12:26 Comment(0)
F
2

Try this:

-webkit-column-break-inside: avoid;
page-break-inside: avoid;
break-inside: avoid;
-webkit-column-break-inside: avoid-column;
page-break-inside: avoid-column;
break-inside: avoid-column;

...worked for me, might work for you.

Feinberg answered 12/8, 2020 at 11:21 Comment(1)
Seems each of the 3 unique properties are defined twice here.Christiniachristis
P
1

This answer might only apply to certain circumstances; If you set a height to your elements, this will be obeyed by the column styling. There-by keeping anything that is contained within that height to a row.

I had a list, like the op, but it contained two elements, items and buttons to act upon those items. I treated it like a table <ul> - table, <li> - table-row, <div> - table-cell put the UL in a 4 column layout. The columns were sometimes being split between the item and it's buttons. The trick I used was to give the Div elements a line height to cover the buttons.

Polyphagia answered 23/6, 2015 at 8:5 Comment(0)
R
1

Most of the propertis is showing invalid when I am going to apply such as

  page-break-inside: avoid-column;
  break-inside: avoid-column;
  -webkit-column-break-inside: avoid-column; 

and when I am checking is responsiveness it not working fine for me...

Anyone can provide me a solution for the same...

Rhee answered 15/2, 2021 at 12:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.