¿Cómo evitar el salto de columna dentro de un elemento?

272

Considere el siguiente 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>

y el siguiente CSS:

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

Tal como está, Firefox actualmente representa esto de manera similar a lo siguiente:

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

Observe que el cuarto elemento se dividió entre la segunda y la tercera columna. ¿Cómo evito eso?

El renderizado deseado podría parecerse más a:

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

o

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

Editar: el ancho solo se especifica para demostrar la representación no deseada. En el caso real, por supuesto, no hay un ancho fijo.

Timwi
fuente
¿Has intentado darle a ese li un estilo independiente? como <li style = "width: ??? px"> El número cuatro es un poco más largo </li> ??? px = ancho necesario para ajustarse a ese número cuatro.
rmagnum2002

Respuestas:

397

La forma correcta de hacerlo es con la propiedad CSS de ruptura :

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

Desafortunadamente, a partir de octubre de 2019, esto no es compatible con Firefox, pero es compatible con todos los demás navegadores principales . Con Chrome, pude usar el código anterior, pero no pude hacer que nada funcionara para Firefox ( ver error 549114 ).

La solución alternativa que puede hacer para Firefox si es necesario es envolver su contenido sin interrupciones en una tabla, pero esa es una solución realmente terrible si puede evitarlo.

ACTUALIZAR

Según el informe de error mencionado anteriormente, Firefox 20+ es compatible page-break-inside: avoidcomo un mecanismo para evitar saltos de columna dentro de un elemento, pero el fragmento de código a continuación demuestra que todavía no funciona con listas:

Como otros mencionan, puede hacer overflow: hiddeno display: inline-blockpero esto elimina las viñetas que se muestran en la pregunta original. Su solución variará según cuáles sean sus objetivos.

ACTUALIZACIÓN 2 Dado que Firefox evita la ruptura display:tabley display:inline-blockuna solución confiable pero no semántica sería envolver cada elemento de la lista en su propia lista y aplicar la regla de estilo allí:

.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
fuente
44
Creo que Opera 11.5 es compatiblebreak-inside: avoid-column
Alohci
2
Mirar el comentario 15 page-break-inside:avoid debería funcionar en FF 20.
Brian Nickel
23
En el año 2014, la sintaxis correcta 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 No veo ninguna mejora en Firefox 31. Ni la columna-salto de página ni el salto de página (con o sin prefijo) están funcionando.
Brian Nickel
66
Es un poco tarde, pero como sigue siendo un problema en 2018, esto podría ser útil para otros que terminan aquí. Si alguien todavía tiene errores entre los navegadores con esto, overflow: hiddenes la mejor opción. display: inline-block;Causa nuevas peculiaridades con Chrome, desafortunadamente.
SilasOtoko
170

Sumando;

display: inline-block;

a los elementos secundarios evitará que se dividan entre columnas.

Steve
fuente
1
Esto es bueno. Una posible forma de evitar el mal comportamiento del bloqueo en línea que causa que las cosas se aplasten ahora en una línea (si son demasiado cortas) es envolver esto con un display:blockelemento. Es probable que por ahora sea una solución sólida para Firefox.
Steven Lu
Esta solución elimina el elemento de la lista, por lo que si usa listas de pedidos, por ejemplo, esta no sería una alternativa.
Ricardo Zea
Funciona perfectamente para dividir párrafos en columnas.
ChrisC
para los elementos de la lista, esto puede funcionar si incrusta el contenido del elemento de la lista (li) dentro de un conjunto de elementos "span" con "display: inline-block". La situación es mucho más compleja si desea controlar dónde dividir páginas o columnas dentro de las tablas: le gustaría evitar interrupciones dentro de las filas de la tabla (tr). Realmente, los diseños de columnas múltiples siguen siendo difíciles de configurar, pero necesitamos que permita que los sitios se adapten a pantallas muy estrechas (como teléfonos inteligentes) y a pantallas anchas (donde las columnas muy estrechas son realmente injustas.)
verdy_p
77
Funciona para mi, <li>pero tuve que agregar width:100%;para evitar que se apilen horizontalmente.
Justin
47

establezca lo siguiente en el estilo del elemento que no desea romper:

overflow: hidden; /* fix for Firefox */
break-inside: avoid-column;
-webkit-column-break-inside: avoid;
usuario2540794
fuente
1
¡¡Gracias!! Estaba teniendo problemas con FF y esto lo solucionó.
Francis Perron
Yo también. Las soluciones anteriores no funcionaban para mí, pero las suyas sí. ¡Prestigio!
Maxx
¡Esto funciona en FF y en realidad no oculta mi contenido!
Justin
bonito. funciona para el párrafo de texto de columna también. Desbordamiento agregado: oculto para el <p> ind el <div> con las columnas. Trabaja para FF.
dichterDichter 01 de
1
En realidad, la overflow:hiddenregla no es una solución para las otras reglas, es lo que causa el diseño sin interrupciones ...
Gras Double
23

A partir de octubre de 2014, la intrusión todavía parece estar defectuosa en Firefox e IE 10-11. Sin embargo, agregar overflow: oculto al elemento, junto con el break-inside: evitar, parece que funciona en Firefox e IE 10-11. Actualmente estoy 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
fuente
Esta parece ser la lista más exhaustiva
binaryfunt
12

Firefox ahora es compatible con esto:

page-break-inside: avoid;

Esto resuelve el problema de los elementos que se rompen a través de las columnas.

Paul Haine
fuente
¿Tienes esto funcionando? Estoy mirando este violín en FF 22 y no funciona: jsfiddle.net/bnickel/5qwMf
Brian Nickel
Lo mismo aquí, no funciona en Firefox 22. Además, Firebug solo muestra page-break-before:o page-break-after:nopage-break-inside:
Ricardo Zea
Versión 28 de Firefox. Este es el único que funciona para mí todavía, ¡gracias!
Sander Verhagen
9

La respuesta aceptada ahora tiene dos años y las cosas parecen haber cambiado.

Este artículo explica el uso de la column-break-insidepropiedad. No puedo decir cómo o por qué esto difiere break-inside, porque solo este último parece estar documentado en la especificación W3. Sin embargo, Chrome y Firefox admiten lo siguiente:

li {
    -webkit-column-break-inside:avoid;
       -moz-column-break-inside:avoid;
            column-break-inside:avoid;
}
keithjgrant
fuente
Esto no funciona para un <div class = "a"> donde "a" reemplaza su "Li" anterior. El div todavía se rompió por dentro. FF 26
Nasser
No es un error el código anterior es correcto para la función descrita, incluso si su selector es solo para un elemento li. Aún podría usar otro selector CSS "div.a {...}" en lugar de "li {...}" en este ejemplo.
verdy_p
Sin embargo, Chrome todavía no admite -webkit-column-break-inside: evitar; en una fila de la tabla: esto no funciona y todavía no podemos evitar dividir tablas en malas posiciones (especialmente si una celda de cuento no solo contiene texto sino iconos; pero Chrome también parece dividirse en cualquier posición vertical en el medio de una línea de texto , rompiendo el texto con la parte superior de los glifos de texto en la parte inferior de la primera columna, y la parte inferior de los glifos de texto en la parte superior de la siguiente columna !!! El resultado es absolutamente ilegible !!!
verdy_p
A partir de 2017, column-break-inside no parece ser una propiedad CSS válida. MDN solo dice "Edge también admite la variante no estándar -webkit-column-break-inside".
Jacob C. dice Restablecer a Mónica el
9

Esto funciona para mí en 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
fuente
Esto es trabajo para mí en ullos elementos, se publica en trucos CSS: css-tricks.com/almanac/properties/b/break-inside , y parece correcto basado en las notas de compatibilidad caniuse: "Apoyo parcial se refiere a no apoyar la break-before, break-after, break-insidepropiedades . Los navegadores basados ​​en WebKit y Blink tienen compatibilidad equivalente para las -webkit-column-break-*propiedades no estándar para lograr el mismo resultado (pero solo los valores autoy always). Firefox no admite break-*pero admite las page-break-*propiedades para lograr el mismo resultado ".
Nabrown
3

El siguiente código funciona para evitar saltos de columna dentro de los 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
fuente
3

En 2019, tener esto funciona para mí en Chrome, Firefox y Opera (después de muchos otros intentos fallidos):

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

Firefox 26 parece requerir

page-break-inside: avoid;

Y Chrome 32 necesita

-webkit-column-break-inside:avoid;
   -moz-column-break-inside:avoid;
        column-break-inside:avoid;
MAPA
fuente
2

Creo que tuve el mismo problema y encontré una solución en esto:

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

Trabajando también en FF 38.0.5: http://jsfiddle.net/rkzj8qnv/

dichterDichter
fuente
Esta solución me ayuda
OzzyCzech
1

Una posible solución para Firefox es establecer la propiedad CSS "mostrar" del elemento que no desea que tenga un descanso dentro de "tabla". No sé si funciona para la etiqueta LI (probablemente perderá la lista -item-style), pero funciona para la etiqueta P.

Christopher
fuente
Esta solución elimina el elemento de la lista, por lo que si usa listas de pedidos, por ejemplo, esta no sería una alternativa.
Ricardo Zea
1

Acabo de corregir algunos divmensajes que se estaban dividiendo en la siguiente columna agregando

overflow: auto

al niño div s.

* ¡Se dio cuenta de que solo lo corrige en Firefox!

mateostabio
fuente
1

Enfrenté el mismo problema al usar columnas de tarjeta

Lo arreglé usando

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

funciona perfectamente

Tahir
fuente
0

Hice una actualización de la respuesta real.

Esto parece estar funcionando en Firefox y 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: La propiedad float parece ser la que hace el comportamiento del bloque.

Gatsbimantico
fuente
0

Esta respuesta solo puede aplicarse a ciertas circunstancias; Si establece una altura para sus elementos, esto será obedecido por el estilo de columna. Ahí, manteniendo todo lo que está contenido dentro de esa altura en una fila.

Tenía una lista, como la operación, pero contenía dos elementos, elementos y botones para actuar sobre esos elementos. Lo tratan como una mesa <ul> - table, <li> - table-row, <div> - table-cellpuse la UL en un diseño de 4 columnas. Las columnas a veces se dividían entre el elemento y sus botones. El truco que usé fue darle a los elementos Div una altura de línea para cubrir los botones.

Tod
fuente