How to prevent column break within an element?

2019-01-01 06:30发布

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.

16条回答
长期被迫恋爱
2楼-- · 2019-01-01 06:48

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;
}
查看更多
栀子花@的思念
3楼-- · 2019-01-01 06:50

Adding;

display: inline-block;

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

查看更多
临风纵饮
4楼-- · 2019-01-01 06:50
<style>
ul li{display: table;}  
</style>

works perfectly

查看更多
浮光初槿花落
5楼-- · 2019-01-01 06:51

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;
查看更多
路过你的时光
6楼-- · 2019-01-01 06:53

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

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

Unfortunately, no browser currently supports this. With Chrome, I was able to use the following, but I couldn't make anything work for Firefox (See Bug 549114):

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

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 {
    -moz-column-count: 3;
    -webkit-column-count: 3;
    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>

查看更多
牵手、夕阳
7楼-- · 2019-01-01 06:56

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>

查看更多
登录 后发表回答