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.

Timwi
fonte
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>

Brian Nickel
fonte
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.

Steve
fonte
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;
user2540794
fonte
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;
VerticalGrain
fonte
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.

paul haine
fonte
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;
}
keithjgrant
fonte
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>

Sébastien Gicquel
fonte
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;
AlphaMycelium
fonte
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;
}
hextech
fonte
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;
MAPA
fonte
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/

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

Christopher
fonte
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!

mateostabio
fonte
1

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

eu consertei usando

 display: inline-flex ;
 column-break-inside: avoid;
 width:100%;
Mysterious_Anny
fonte
1
<style>
ul li{display: table;}  
</style>

funciona perfeitamente

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

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

Tod
fonte