Como evitar quebra de coluna dentro de um elemento?


272

Considere o seguinte 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>

e o seguinte CSS:

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

No momento, o Firefox atualmente processa isso da mesma forma que o seguinte:

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

Observe que o quarto item foi dividido entre a segunda e a terceira coluna. Como evito isso?

A renderização desejada pode parecer algo como:

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

ou

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

Editar: a largura é especificada apenas para demonstrar a renderização indesejada. No caso real, é claro que não há largura fixa.


você tentou dar a esse estilo um estilo independente? like <li style = "width: ??? px"> O número quatro é um pouco mais </li> ??? px = largura necessária para se ajustar ao número quatro.
rmagnum2002

Respostas:


397

A maneira correta de fazer isso é com a propriedade CSS invasora :

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

Infelizmente, a partir de outubro de 2019, isso não é suportado no Firefox, mas é suportado por todos os outros principais navegadores . Com o Chrome, eu pude usar o código acima, mas não consegui fazer nada funcionar no Firefox ( consulte Bug 549114 ).

A solução alternativa que você pode fazer para o Firefox, se necessário, é agrupar seu conteúdo ininterrupto em uma tabela, mas essa é uma solução realmente terrível se você puder evitá-lo.

ATUALIZAR

De acordo com o relatório de bug mencionado acima, o Firefox 20+ suporta page-break-inside: avoidcomo um mecanismo para evitar quebras de coluna dentro de um elemento, mas o trecho de código abaixo demonstra que ele ainda não está funcionando com listas:

Como outros mencionar, você pode fazer overflow: hiddenou display: inline-blockmas isso remove as balas mostrados na pergunta original. Sua solução variará de acordo com quais são seus objetivos.

ATUALIZAÇÃO 2 Como o Firefox impede a interrupção display:tablee display:inline-blockuma solução confiável, mas semântica, seria agrupar cada item da lista em sua própria lista e aplicar a regra de estilo:

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


4
Acredito Opera 11,5 suportesbreak-inside: avoid-column
Alohci

2
Observar o Comentário 15 page-break-inside:avoid deve funcionar em FF 20.
Brian Nickel

23
No ano de 2014, a sintaxe direita parece ser: -webkit-column-break-inside:avoid; -moz-column-break-inside:avoid; -o-column-break-inside:avoid; -ms-column-break-inside:avoid; column-break-inside:avoid;
Carles Jove i Buxeda

3
@CarlesJoveBuxeda Não está vendo nenhuma melhoria no Firefox 31. Nem a quebra de coluna nem a quebra de página (com ou sem prefixo) estão funcionando.
Brian Nickel

6
É um pouco tarde, mas como ainda é um problema em 2018, isso pode ser útil para outras pessoas que acabam aqui. Se alguém ainda está tendo erros entre os navegadores com isso, overflow: hiddené a melhor opção. display: inline-block;causa novas peculiaridades com o Chrome, infelizmente.
SilasOtoko

170

Adicionando;

display: inline-block;

para os elementos filhos impedirá que eles sejam divididos entre colunas.


1
Isso é bom. Uma maneira possível de impedir o mau comportamento do bloco inline, fazendo com que as coisas agora sejam esmagadas em uma linha (se elas forem muito curtas), é envolvê-las ainda mais com um display:blockelemento. Provavelmente será uma solução alternativa sólida para o Firefox por enquanto.
Steven Lu

Esta solução remove o item da lista; portanto, se você estiver usando listas de pedidos, por exemplo, isso não seria uma alternativa.
Ricardo Zea

Funciona perfeitamente para dividir parágrafos em colunas.
21313 ChrisC

para itens da lista, isso pode funcionar se você incorporar o conteúdo do item da lista (li) em um elemento "span" definido com o "display: bloco embutido". A situação é muito mais complexa se você deseja controlar onde quebrar páginas ou colunas nas tabelas: você gostaria de evitar quebras nas linhas da tabela (tr). Realmente, multi-colunas layouts são ainda difíceis de configurar, mas precisamos dele para permitir que os sites se adaptar às telas muito estreitas (como smartphones) e para monitores de largura (onde colulns muito estreitas são realmente injusto.
verdy_p

7
Funciona para o meu, <li>mas tive que adicionar width:100%;para impedir que eles sejam empilhados horizontalmente.
Justin

47

defina a seguir o estilo do elemento que você não deseja quebrar:

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

1
Obrigado!! Eu estava tendo problemas com o FF e isso foi corrigido!
12133 Francis Perron

Eu também. As soluções acima não estavam funcionando para mim, mas as suas funcionaram. Parabéns!
Maxx

Isso funciona no FF e na verdade não oculta meu conteúdo!
Justin

legais. também funciona para o parágrafo do texto em colunas. Excesso adicionado: oculto para <p> e <div> com as colunas. Trabalha para FF.
precisa saber é o seguinte

1
Na verdade, a overflow:hiddenregra não é uma solução para as outras regras, que é o que faz com que o layout não separável ...
Gras Duplo

23

Em outubro de 2014, a invasão ainda parece estar com problemas no Firefox e no IE 10-11. No entanto, a adição de overflow: hidden ao elemento, juntamente com o break-inside: evitar, parece fazê-lo funcionar no Firefox e IE 10-11. Atualmente, estou usando:

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;

Este parece ser o mais exaustiva lista
binaryfunt

12

O Firefox agora suporta isso:

page-break-inside: avoid;

Isso resolve o problema de elementos quebrando nas colunas.


Você está trabalhando? Estou vendo esse violino no FF 22 e ele não funciona: jsfiddle.net/bnickel/5qwMf
Brian Nickel

Mesmo aqui, não funciona no Firefox 22. Além disso, Firebug somente é exibida page-break-before:ou page-break-after:, mas nãopage-break-inside:
Ricardo Zea

Versão 28 do Firefox. Este é o único que funciona para mim ainda, obrigado!
Sander Verhagen

9

A resposta aceita agora tem dois anos e as coisas parecem ter mudado.

Este artigo explica o uso da column-break-insidepropriedade Não sei dizer como ou por que isso difere break-inside, porque apenas o último parece estar documentado na especificação W3. No entanto, o Chrome e o Firefox suportam o seguinte:

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

Isso não funciona para um <div class = "a"> geral em que "a" substitui seu "Li" acima. A div ainda quebrou por dentro. FF 26
Nasser

Não é um bug. o código acima está correto para a função descrita, mesmo que seu seletor seja apenas para um elemento li. Você ainda pode usar outro seletor de CSS "div.a {...}" em vez de "li {...}" neste exemplo.
verdy_p

No entanto, o Chrome ainda não suporta -webkit-column-break-inside: evite; em uma linha da tabela: isso não funciona e ainda não podemos evitar a quebra de tabelas em posições incorretas (principalmente se uma célula de conto não contém apenas texto, mas ícones; o Chrome também parece se dividir em qualquer posição vertical no meio de uma linha de texto , quebrando o texto com a parte superior de glifos de texto na parte inferior da primeira coluna, e a parte inferior de glifos de texto na parte superior da próxima coluna !!! o resultado é absolutamente ilegível !!!
verdy_p

A partir de 2017, a quebra de coluna não parece ser uma propriedade css válida. O MDN diz apenas "O Edge também suporta a variante não-padrão do kit-coluna-quebra-dentro da web".
Jacob C. disse Reinstate Monica

9

Isso funciona para mim em 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>


Isso está funcionando para mim em ulelementos, é publicado de truques CSS: css-tricks.com/almanac/properties/b/break-inside , e parece correta com base em notas de compatibilidade caniuse: "O apoio parcial refere-se a não apoiar o break-before, break-after, break-insidepropriedades Os navegadores WebKit e Blink têm suporte equivalente para as -webkit-column-break-*propriedades não padrão para obter o mesmo resultado (mas apenas os valores autoe always). O Firefox não suporta, break-*mas suporta as page-break-*propriedades para obter o mesmo resultado. "
Nabrown

3

O código a seguir funciona para impedir quebras de coluna dentro de elementos:

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

3

Em 2019, ter isso funciona para mim no Chrome, Firefox e Opera (depois de muitas outras tentativas malsucedidas):

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

2

O Firefox 26 parece exigir

page-break-inside: avoid;

E o Chrome 32 precisa

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

2

Eu tive o mesmo problema que eu acho e encontrei uma solução nisso:

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

Trabalhando também no FF 38.0.5: http://jsfiddle.net/rkzj8qnv/


Esta solução me ajuda
OzzyCzech

1

Uma possível solução alternativa para o Firefox é definir a propriedade CSS "display" do elemento que você não deseja interromper como "table". Não sei se funciona para a tag LI (você provavelmente perderá a lista-item-style), mas funciona para a tag P.


Esta solução remove o item da lista; portanto, se você estiver usando listas de pedidos, por exemplo, isso não seria uma alternativa.
Ricardo Zea

1

Eu apenas consertei alguns divs que estavam se dividindo na próxima coluna adicionando

overflow: auto

para a criança divs.

* Percebi que só o corrige no Firefox!


1

Eu enfrentei o mesmo problema ao usar colunas de cartão

eu consertei usando

 display: inline-flex ;
 column-break-inside: avoid;
 width:100%;

1
<style>
ul li{display: table;}  
</style>

funciona perfeitamente


0

Eu fiz uma atualização da resposta real.

Isso parece estar funcionando no firefox e no 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 */
}

Nota: A propriedade float parece ser a responsável pelo comportamento do bloco.


0

Essa resposta pode se aplicar apenas a determinadas circunstâncias; Se você definir uma altura para seus elementos, isso será obedecido pelo estilo da coluna. Mantendo tudo o que está contido nessa altura em uma linha.

Eu tinha uma lista, como o op, mas continha dois elementos, itens e botões para atuar sobre esses itens. Tratei-o como uma tabela <ul> - table, <li> - table-row, <div> - table-cellcolocar o UL em um layout 4 coluna. Às vezes, as colunas eram divididas entre o item e seus botões. O truque que usei foi dar aos elementos Div uma altura de linha para cobrir os botões.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.