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.


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>


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.


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;

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;

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.


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

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>


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;

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

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;

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/


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.


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!


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

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

fonctionne parfaitement


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.


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.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.