Comment empêcher la rupture de colonne dans un élément?

272

Considérez le code HTML suivant:

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

et le CSS suivant:

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

Dans l'état actuel des choses, Firefox rend actuellement ceci de la manière suivante:

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

Notez que le quatrième élément a été divisé entre la deuxième et la troisième colonne. Comment puis-je empêcher cela?

Le rendu souhaité pourrait ressembler à quelque chose de plus:

 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

Modifier: la largeur est uniquement spécifiée pour illustrer le rendu indésirable. Dans le cas réel, il n'y a bien sûr pas de largeur fixe.

Timwi
la source
avez-vous essayé de donner à ce li un style autonome? comme <li style = "width: ??? px"> Le numéro quatre est un peu plus long </li> ??? px = largeur nécessaire pour s'adapter à ce numéro quatre.
rmagnum2002

Réponses:

397

La façon correcte de le faire est d'utiliser la propriété CSS de rupture :

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

Malheureusement, depuis octobre 2019, cela n'est pas pris en charge dans Firefox, mais il est pris en charge par tous les autres principaux navigateurs . Avec Chrome, j'ai pu utiliser le code ci-dessus, mais je n'ai rien pu faire pour Firefox ( voir bug 549114 ).

La solution de contournement que vous pouvez faire pour Firefox si nécessaire est d'envelopper votre contenu incassable dans un tableau, mais c'est une solution vraiment, vraiment terrible si vous pouvez l'éviter.

METTRE À JOUR

Selon le rapport de bogue mentionné ci-dessus, Firefox 20+ prend page-break-inside: avoiden charge comme mécanisme pour éviter les sauts de colonne à l'intérieur d'un élément, mais l'extrait de code ci-dessous montre qu'il ne fonctionne toujours pas avec les listes:

Comme d'autres le mentionnent, vous pouvez faire overflow: hiddenoudisplay: inline-block mais cela supprime les balles affichées dans la question d'origine. Votre solution variera en fonction de vos objectifs.

MISE À JOUR 2 Étant donné que Firefox empêche la rupture display:tableet display:inline-blockqu'une solution fiable mais non sémantique serait d'encapsuler chaque élément de la liste dans sa propre liste et d'y appliquer la règle de style:

.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
la source
4
Je crois qu'Opera 11.5 prend en chargebreak-inside: avoid-column
Alohci
2
Le commentaire 15 page-break-inside:avoid devrait fonctionner en FF 20.
Brian Nickel
23
En 2014, la bonne syntaxe semble être: -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 Aucune amélioration dans Firefox 31. Ni le saut de colonne ni le saut de page (avec ou sans préfixe) ne fonctionnent.
Brian Nickel
6
C'est un peu tard, mais comme c'est toujours un problème en 2018, cela pourrait être utile à d'autres qui se retrouvent ici. Si quelqu'un a encore des bogues entre les navigateurs avec cela, overflow: hiddenc'est la meilleure option. display: inline-block;provoque malheureusement de nouvelles bizarreries avec Chrome.
SilasOtoko
170

Ajouter;

display: inline-block;

aux éléments enfants les empêcheront d'être divisés entre les colonnes.

Steve
la source
1
C'est bon. Un moyen possible d'empêcher le mauvais comportement des blocs en ligne de faire en sorte que les éléments soient maintenant écrasés sur une seule ligne (s'ils sont trop courts) consiste à envelopper davantage cela avec un display:blockélément. Ce sera probablement une solution de contournement de Firefox solide pour l'instant.
Steven Lu
Cette solution supprime l'élément de liste, donc si vous utilisez des listes de commandes par exemple, ce ne serait pas une alternative.
Ricardo Zea
Fonctionne parfaitement pour diviser des paragraphes en colonnes.
ChrisC
pour les éléments de liste, cela peut fonctionner si vous incorporez le contenu de l'élément de liste (li) dans un élément "span" défini avec le "display: inline-block". La situation est beaucoup plus complexe si vous souhaitez contrôler où séparer les pages ou les colonnes dans les tableaux: vous souhaitez éviter les ruptures dans les lignes de tableau (tr). Vraiment, les dispositions multi-colonnes sont toujours difficiles à configurer, mais nous en avons besoin pour permettre aux sites de s'adapter à des écrans très étroits (tels que les smartphones) et à des écrans larges (où les colonnes très étroites sont vraiment injustes.
verdy_p
7
Fonctionne pour moi <li>mais j'ai dû ajouter width:100%;pour les empêcher de s'empiler horizontalement.
Justin
47

définissez le style de l'élément que vous ne voulez pas casser suivant:

overflow: hidden; /* fix for Firefox */
break-inside: avoid-column;
-webkit-column-break-inside: avoid;
user2540794
la source
1
Je vous remercie!! J'avais des problèmes avec FF et ça le corrige!
Francis Perron
Moi aussi. Les solutions ci-dessus ne fonctionnaient pas pour moi, mais la vôtre l'a fait. Gloire!
Maxx
Cela fonctionne sur FF et ne cache pas vraiment mon contenu!
Justin
agréable. fonctionne également pour le paragraphe de texte colum. Débordement ajouté: caché au <p> et au <div> avec les colonnes. Fonctionne pour FF.
dichterDichter
1
En fait, la overflow:hiddenrègle n'est pas une solution pour les autres règles, il est ce qui provoque la mise en page insécable ...
Gras Double
23

En octobre 2014, l'effraction semble toujours boguée dans Firefox et IE 10-11. Cependant, l'ajout de débordement: caché à l'élément, ainsi que l'effraction: éviter, semble le faire fonctionner dans Firefox et IE 10-11. J'utilise actuellement:

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
la source
Cela semble être la liste la plus exhaustive
binaryfunt
12

Firefox prend désormais en charge ceci:

page-break-inside: avoid;

Cela résout le problème des éléments qui traversent les colonnes.

paul haine
la source
Avez-vous ce travail? Je regarde ce violon dans FF 22 et ça ne marche pas: jsfiddle.net/bnickel/5qwMf
Brian Nickel
Même chose ici, ne fonctionne pas dans Firefox 22. En outre, Firebug n'affiche que page-break-before:ou page-break-after:nonpage-break-inside:
Ricardo Zea
Version 28 de Firefox. C'est le seul qui fonctionne pour moi encore, merci!
Sander Verhagen
9

La réponse acceptée a maintenant deux ans et les choses semblent avoir changé.

Cet article explique l'utilisation de la column-break-insidepropriété. Je ne peux pas dire comment ou pourquoi cela diffère break-inside, car seul ce dernier semble être documenté dans la spécification W3. Cependant, Chrome et Firefox prennent en charge les éléments suivants:

li {
    -webkit-column-break-inside:avoid;
       -moz-column-break-inside:avoid;
            column-break-inside:avoid;
}
keithjgrant
la source
Cela ne fonctionne pas pour une <div class = "a"> générale où "a" remplace votre "Li" ci-dessus. Le div s'est cassé à l'intérieur. FF 26
Nasser
Pas un bug. le code ci-dessus est correct pour la fonction décrite même si son sélecteur est juste pour un élément li. Vous pouvez toujours utiliser un autre sélecteur CSS "div.a {...}" au lieu de "li {...}" dans cet exemple.
verdy_p
Cependant, Chrome ne prend toujours pas en charge -webkit-column-break-inside: éviter; sur une ligne de tableau: cela ne fonctionne pas et nous ne pouvons toujours pas éviter de casser des tableaux dans de mauvaises positions (notamment si une cellule de conte ne contient pas seulement du texte mais des icônes; mais Chrome semble également se diviser à n'importe quelle position verticale au milieu d'une ligne de texte , en cassant le texte avec la partie supérieure des glyphes de texte en bas de la première colonne et la partie inférieure des glyphes de texte en haut de la colonne suivante !!! Le résultat est absolument illisible !!!
verdy_p
Depuis 2017, le saut de colonne ne semble pas être une propriété CSS valide. MDN dit seulement "Edge prend également en charge la variante non standard -webkit-column-break-inside."
Jacob C. dit Réintégrer Monica
9

Cela fonctionne pour moi 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
la source
Cela fonctionne pour moi sur des uléléments, est affiché sur des tours CSS: css-tricks.com/almanac/properties/b/break-inside et semble correcte en fonction des notes de compatibilité caniuse: « Un soutien partiel fait référence à ne pas soutenir la break-before, break-after, break-insidepropriétés . Les navigateurs WebKit et Blink prennent en charge de manière équivalente les -webkit-column-break-*propriétés non standard pour obtenir le même résultat (mais uniquement les valeurs autoet always). Firefox ne prend pas en charge break-*mais prend en charge les page-break-*propriétés pour obtenir le même résultat. "
nabrown
3

Le code suivant fonctionne pour empêcher les sauts de colonne à l'intérieur des éléments:

-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
la source
3

En 2019, cela fonctionne pour moi sur Chrome, Firefox et Opera (après de nombreuses autres tentatives infructueuses):

.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
la source
2

Firefox 26 semble nécessiter

page-break-inside: avoid;

Et Chrome 32 a besoin

-webkit-column-break-inside:avoid;
   -moz-column-break-inside:avoid;
        column-break-inside:avoid;
CARTE
la source
2

J'ai eu le même problème, je pense, et j'ai trouvé une solution:

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

Fonctionne également dans FF 38.0.5: http://jsfiddle.net/rkzj8qnv/

dichterDichter
la source
Cette solution m'aide
OzzyCzech
1

Une solution de contournement possible pour Firefox est de définir la propriété CSS "affichage" de l'élément dans lequel vous ne voulez pas de pause à "table". Je ne sais pas si cela fonctionne pour la balise LI (vous perdrez probablement la liste -item-style), mais cela fonctionne pour la balise P.

Christophe
la source
Cette solution supprime l'élément de liste, donc si vous utilisez des listes de commandes par exemple, ce ne serait pas une alternative.
Ricardo Zea
1

Je viens de corriger quelques divs qui se divisaient sur la colonne suivante en ajoutant

overflow: auto

à l'enfant divs.

* Réalisé, il ne le corrige que dans Firefox!

matéostabio
la source
1

J'ai rencontré le même problème lors de l'utilisation des colonnes de carte

je l'ai réparé en utilisant

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

fonctionne parfaitement

Tahir
la source
0

J'ai fait une mise à jour de la réponse réelle.

Cela semble fonctionner sur Firefox et 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 */
}

Remarque: La propriété float semble être celle qui fait le comportement du bloc.

Gatsbimantico
la source
0

Cette réponse pourrait ne s'appliquer qu'à certaines circonstances; Si vous définissez une hauteur pour vos éléments, celle-ci sera respectée par le style des colonnes. Là-bas en gardant tout ce qui est contenu dans cette hauteur à une rangée.

J'avais une liste, comme l'op, mais elle contenait deux éléments, des éléments et des boutons pour agir sur ces éléments. Je l' ai traité comme une table <ul> - table, <li> - table-row, <div> - table-cellmis l'UL dans une mise en page 4 de la colonne. Les colonnes étaient parfois divisées entre l'élément et ses boutons. L'astuce que j'ai utilisée était de donner aux éléments Div une hauteur de ligne pour couvrir les boutons.

Tod
la source