【问题标题】:How to prevent column break within an element?如何防止元素内的列中断?
【发布时间】:2021-10-14 05:00:27
【问题描述】:

考虑以下 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>

以及以下 CSS:

.x {
    -moz-column-count: 3;
    column-count: 3;
    width: 30em;
}

目前,Firefox 将其呈现为类似于以下内容:

• Number one    • Number three          bit longer
• Number two    • Number four is a    • Number five

请注意,第四项拆分为第二列和第三列。我该如何预防?

所需的渲染可能看起来更像:

• Number one    • Number four is a
• Number two      bit longer
• Number three  • Number five

• Number one    • Number three        • Number five
• Number two    • Number four is a
                  bit longer

编辑:宽度仅用于演示不需要的渲染。在实际情况下,当然没有固定的宽度。

【问题讨论】:

  • 你试过给那个 li 一个独立的风格吗?比如
  • 第四个有点长
  • ???px = 需要的宽度来适应第四个。

标签: html css css-multicolumn-layout


【解决方案1】:

正确的做法是使用break-inside CSS property:

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

很遗憾,截至 2021 年 10 月,this is still not supported in Firefoxit is supported by every other major browser。使用 Chrome,我可以使用上面的代码,但我无法为 Firefox (See Bug 549114) 做任何事情。

如有必要,您可以为 Firefox 做的解决方法是将不间断的内容包装在一个表格中,但如果您可以避免它,这是一个非常非常糟糕的解决方案。

更新

根据上面提到的错误报告,Firefox 20+ 支持 page-break-inside: avoid 作为避免元素内分栏符的机制,但下面的代码 sn-p 表明它仍然不适用于列表:

.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>

正如其他人所提到的,您可以使用 overflow: hiddendisplay: inline-block 但这会删除原始问题中显示的项目符号。您的解决方案将根据您的目标而有所不同。

更新 2 由于 Firefox 确实可以防止破坏 display:tabledisplay:inline-block,因此可靠但非语义的解决方案是将每个列表项包装在其自己的列表中并在那里应用样式规则:

.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>

【讨论】:

  • 相信Opera 11.5支持break-inside: avoid-column
  • 查看 Comment 15 page-break-inside:avoid 应该可以在 FF 20 中使用。
  • 在 2014 年,正确的语法似乎是:-webkit-column-break-inside:avoid; -moz-column-break-inside:avoid; -o-column-break-inside:avoid; -ms-column-break-inside:avoid; column-break-inside:avoid;
  • @CarlesJoveBuxeda 在 Firefox 31 中没有看到任何改进。column-break-inside 或 page-break-inside(带或不带前缀)都不起作用。
  • 有点晚了,但由于这在 2018 年仍然是一个问题,这可能对最终来到这里的其他人有用。如果有人仍然在浏览器之间遇到错误,overflow: hidden 是更好的选择。不幸的是,display: inline-block; 导致 Chrome 出现了新的怪癖。
【解决方案2】:

对于 Firefox,一个可能的解决方法是将您不希望在内部中断的元素的 CSS 属性“显示”设置为“表格”。我不知道它是否适用于 LI 标签(你可能会丢失 list -item-style),但它适用于 P 标签。

【讨论】:

  • 此解决方案会删除列表项,因此如果您使用的是订单列表,例如,这将不是替代方案。
【解决方案3】:

添加;

display: inline-block;

到子元素将防止它们在列之间被拆分。

【讨论】:

  • 这很好。防止 inline-block 的不良行为导致内容现在在一行上被挤压(如果它们太短)的一种可能方法是用display:block 元素进一步包装它。目前这可能是一个可靠的 Firefox 解决方法。
  • 此解决方案会删除列表项,因此如果您使用的是订单列表,例如,这将不是替代方案。
  • 非常适合将段落分成列。
  • 对于列表项,如果您将列表项 (li) 的内容嵌入到使用“display:inline-block”设置的“span”元素中,这将起作用。如果您想控制在表中的何处分页或分列,则情况要复杂得多:您希望避免在表行 (tr) 中分页。确实,多列布局仍然难以设置,但我们需要它来允许网站适应非常窄的屏幕(例如智能手机)和宽显示器(非常窄的列确实不公平。
  • 适用于我的 &lt;li&gt;,但我必须添加 width:100%; 以防止它们水平堆叠。
【解决方案4】:

Firefox 现在支持这个:

page-break-inside: avoid;

这解决了元素跨列的问题。

【讨论】:

  • 你有这个工作吗?我正在看 FF 22 中的这个小提琴,但它不起作用:jsfiddle.net/bnickel/5qwMf
  • 这里相同,在 Firefox 22 中不起作用。此外,Firebug 仅显示 page-break-before:page-break-after: 但不显示 page-break-inside:
  • Firefox 28 版。这是唯一对我有用的,谢谢!
【解决方案5】:

将以下设置为您不想破坏的元素的样式:

overflow: hidden; /* fix for Firefox */
break-inside: avoid-column;
-webkit-column-break-inside: avoid;

【讨论】:

  • 不错。也适用于列文本段落。将溢出:隐藏到

    与列。为 FF 工作。
  • 实际上,overflow:hidden 规则并不是对其他规则的修复,它导致不间断布局的原因......
【解决方案6】:

现在接受的答案已有两年之久,情况似乎发生了变化。

This article 解释了column-break-inside 属性的使用。我不能说这与break-inside 有何不同或为什么不同,因为W3 规范中似乎只记录了后者。但是,Chrome 和 Firefox 支持以下内容:

li {
    -webkit-column-break-inside:avoid;
       -moz-column-break-inside:avoid;
            column-break-inside:avoid;
}

【讨论】:

  • 这不适用于一般的
    其中“a”替换了上面的“Li”。 div仍然在里面破了。 FF 26
  • 不是错误。上面的代码对于所描述的函数是正确的,即使它的选择器只是一个 li 元素。在此示例中,您仍然可以使用另一个 CSS 选择器“div.a {...}”而不是“li{...}”。
  • 但是 Chrome 仍然不支持 -webkit-column-break-inside:avoid;在表格行上:这不起作用,我们仍然无法避免在不好的位置打破表格(特别是如果故事单元格不仅包含文本还包含图标;但 Chrome 也似乎在文本行中间的任何垂直位置拆分,用第一列底部的文本字形的上部和下一列顶部的文本字形的下部打破文本!!!结果绝对不可读!!!
  • 截至 2017 年,column-break-inside 似乎不是有效的 CSS 属性。 MDN 只说“Edge 还支持非标准的 -webkit-column-break-inside 变体。”
【解决方案7】:

Firefox 26 似乎需要

page-break-inside: avoid;

而 Chrome 32 需要

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

【讨论】:

    【解决方案8】:

    我更新了实际答案。

    这似乎适用于 Firefox 和 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 */
    }
    

    注意: float 属性似乎是产生块行为的属性。

    【讨论】:

      【解决方案9】:

      截至 2014 年 10 月,在 Firefox 和 IE 10-11 中,break-inside 似乎仍然存在问题。但是,向元素添加溢出:隐藏,以及 break-inside:避免,似乎使它在 Firefox 和 IE 10-11 中工作。我目前正在使用:

      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;
      

      【讨论】:

      • 这似乎是最详尽的列表
      【解决方案10】:

      我刚刚修复了一些 divs 通过添加

      拆分到下一列
      overflow: auto
      

      给孩子divs.

      *意识到它只在 Firefox 中修复它!

      【讨论】:

        【解决方案11】:

        这个答案可能只适用于某些情况;如果您为元素设置高度,则列样式将遵循这一点。从而将包含在该高度内的任何内容保持在一行。

        我有一个列表,就像操作一样,但它包含两个元素,项目和对这些项目进行操作的按钮。我把它当作一张表来对待&lt;ul&gt; - table&lt;li&gt; - table-row&lt;div&gt; - table-cell 将 UL 放在 4 列布局中。列有时会在项目和它的按钮之间拆分。我使用的技巧是给 Div 元素一个行高以覆盖按钮。

        【讨论】:

          【解决方案12】:

          我遇到了同样的问题,并在此找到了解决方案:

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

          也在 FF 38.0.5 中工作:http://jsfiddle.net/rkzj8qnv/

          【讨论】:

            【解决方案13】:

            这在 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>

            【讨论】:

            • 这对我有用 ul 元素,发布在 CSS 技巧上:css-tricks.com/almanac/properties/b/break-inside,根据 caniuse 兼容性说明似乎是正确的:“部分支持是指不支持 break-beforebreak-after, break-inside 属性。基于 WebKit 和 Blink 的浏览器确实对非标准 -webkit-column-break-* 属性具有同等的支持,以实现相同的结果(但只有 autoalways 值)。Firefox 支持不支持break-*,但支持page-break-* 属性以实现相同的结果。"
            【解决方案14】:

            以下代码可防止元素内出现分栏:

            -webkit-column-break-inside: avoid;
            -moz-column-break-inside: avoid;
            -o-column-break-inside: avoid;
            -ms-column-break-inside: avoid;
            column-break-inside: avoid;
            

            【讨论】:

              【解决方案15】:

              我在使用卡片列时遇到了同样的问题

              我用

              修复了它
               display: inline-flex ;
               column-break-inside: avoid;
               width:100%;
              

              【讨论】:

              • 这里也一样。我的li {display: flex} 2 列上的多个元素在li 中间的某处中断,这有助于更改为li {display: inline-flex}
              【解决方案16】:
              <style>
              ul li{display: table;}  
              </style>
              

              完美运行

              【讨论】:

                【解决方案17】:

                在 2019 年,我在 Chrome、Firefox 和 Opera 上都可以使用此功能(经过许多其他不成功的尝试):

                .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;
                }
                

                【讨论】:

                  【解决方案18】:

                  试试这个:

                  -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;
                  

                  ...对我有用,可能对你有用。

                  【讨论】:

                  • 似乎 3 个独特属性中的每一个都在这里定义了两次。
                  【解决方案19】:

                  当我要申请时,大多数属性都显示无效,例如

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

                  当我检查响应性时,它对我来说不能正常工作......

                  任何人都可以为我提供相同的解决方案...

                  【讨论】:

                    猜你喜欢
                    相关资源
                    最近更新 更多
                    热门标签