Jak zapobiec rozbiciu kolumny w elemencie?

272

Rozważ następujący kod 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>

oraz następujący CSS:

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

W obecnej formie Firefox renderuje to podobnie do następującego:

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

Zauważ, że czwarty element został podzielony na drugą i trzecią kolumnę. Jak temu zapobiec?

Pożądane renderowanie może wyglądać mniej więcej tak:

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

lub

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

Edycja: szerokość jest określona tylko w celu zademonstrowania niechcianego renderowania. W prawdziwym przypadku oczywiście nie ma stałej szerokości.

Timwi
źródło
próbowałeś nadać temu li samodzielny styl? jak <li style = "width: ??? px"> Liczba czwarta jest nieco dłuższa </li> ??? px = potrzebna szerokość, aby zmieścić się na tej liczbie cztery.
rmagnum2002

Odpowiedzi:

397

Prawidłowym sposobem na to jest włamanie do właściwości CSS :

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

Niestety, od października 2019 r. Nie jest to obsługiwane w przeglądarce Firefox, ale jest obsługiwane przez każdą inną dużą przeglądarkę . W Chrome mogłem użyć powyższego kodu, ale nie mogłem nic zrobić dla Firefoksa ( zobacz Bug 549114 ).

Obejście, które możesz zrobić dla Firefoksa, jeśli to konieczne, polega na owinięciu niełamliwych treści w tabelę, ale jest to naprawdę, naprawdę straszne rozwiązanie, jeśli możesz tego uniknąć.

AKTUALIZACJA

Według wspomnianego wyżej raportu o błędach Firefox 20+ obsługuje page-break-inside: avoidjako mechanizm unikania podziałów kolumn wewnątrz elementu, ale poniższy fragment kodu pokazuje, że nadal nie działa z listami:

Jak inni wspomnieć, można to zrobić overflow: hiddenalbo display: inline-blockale ten usuwa kul widoczne na oryginalne pytanie. Twoje rozwiązanie będzie się różnić w zależności od twoich celów.

AKTUALIZACJA 2 Ponieważ Firefox nie włącza się, display:tablea display:inline-blockniezawodnym, ale nie semantycznym rozwiązaniem byłoby zawinięcie każdego elementu listy do osobnej listy i zastosowanie tam reguły stylu:

.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
źródło
4
Wierzę, że Opera 11.5 obsługujebreak-inside: avoid-column
Alohci
2
Patrząc na komentarz 15, page-break-inside:avoid powinien działać w FF 20.
Brian Nickel
23
W roku 2014 poprawna składnia wydaje się następująca: -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 Nie widać żadnej poprawy w Firefoksie 31. Nie działa podział na kolumny ani podział strony (z prefiksem lub bez).
Brian Nickel
6
Jest trochę późno, ale ponieważ wciąż jest to problem w 2018 r., Może to być przydatne dla innych, którzy tu trafią. Jeśli ktoś nadal ma z tym błędy w przeglądarkach, overflow: hiddento lepsza opcja. display: inline-block;niestety powoduje nowe dziwactwa w Chrome.
SilasOtoko,
170

Dodawanie;

display: inline-block;

do elementów potomnych zapobiegnie ich podziałowi między kolumnami.

Steve
źródło
1
To jest dobre. Możliwym sposobem, aby zapobiec złemu zachowaniu bloku wstawiania, który powoduje, że rzeczy są teraz ściśnięte w jednej linii (jeśli są zbyt krótkie), jest dalsze zawinięcie tego display:blockelementu. Prawdopodobnie będzie to na razie solidne obejście Firefoksa.
Steven Lu
To rozwiązanie usuwa element listy, więc jeśli na przykład korzystasz z list zamówień, nie byłoby to alternatywą.
Ricardo Zea,
Działa idealnie do dzielenia akapitów na kolumny.
ChrisC
w przypadku elementów listy może to działać, jeśli osadzisz zawartość elementu listy (li) w zestawie elementów „span” za pomocą „display: inline-block”. Sytuacja jest znacznie bardziej złożona, jeśli chcesz kontrolować, gdzie podzielić strony lub kolumny w tabelach: chcesz uniknąć przerw w wierszach tabeli (tr). Naprawdę układy z wieloma kolumnami są nadal trudne do skonfigurowania, ale potrzebujemy go, aby umożliwić witrynom dostosowanie się do bardzo wąskich ekranów (takich jak smartfony) i do szerokich wyświetlaczy (gdzie bardzo wąskie kolumny są naprawdę niesprawiedliwe.
verdy_p
7
Działa dla mnie, <li>ale musiałem dodać, width:100%;aby zapobiec układaniu ich w poziomie.
Justin
47

ustaw styl elementu, którego nie chcesz łamać:

overflow: hidden; /* fix for Firefox */
break-inside: avoid-column;
-webkit-column-break-inside: avoid;
użytkownik2540794
źródło
1
Dziękuję Ci!! Miałem problem z FF i to naprawiłem!
Francis Perron,
Ja też. Powyższe rozwiązania nie działały dla mnie, ale twoje działały. Sława!
Maxx
Działa to na FF i nie ukrywa mojej zawartości!
Justin
miły. działa również dla akapitu tekstu colum. Dodano przepełnienie: ukryte w <p> ind <div> z kolumnami. Działa dla FF.
dichterDichter
1
Faktycznie, overflow:hiddenzasada ta nie jest poprawka dla innych przepisów, to jest to, co powoduje, że układ twardą ...
Gras Pokój
23

Od października 2014 włamanie nadal wydaje się być wadliwe w Firefoksie i IE 10-11. Jednak dodanie przepełnienia: ukrytego do elementu wraz z włamaniem: unikaj, wydaje się, że działa w Firefox i IE 10-11. Obecnie używam:

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
źródło
To wydaje się być najbardziej wyczerpująca lista
binaryfunt
12

Firefox obsługuje teraz to:

page-break-inside: avoid;

Rozwiązuje to problem z podziałem elementów na kolumny.

Paul Haine
źródło
Czy to działa? Patrzę na to skrzypce w FF 22 i to nie działa: jsfiddle.net/bnickel/5qwMf
Brian Nickel
Tak samo tutaj, nie działa w Firefox 22. Również tylko Firebug wyświetlaczy page-break-before:czy page-break-after:jednak niepage-break-inside:
Ricardo Zea
Wersja 28 przeglądarki Firefox. To jedyny, który dla mnie działa, dzięki!
Sander Verhagen
9

Akceptowana odpowiedź ma teraz dwa lata i wydaje się, że wszystko się zmieniło.

W tym artykule wyjaśniono korzystanie z column-break-insidewłaściwości. Nie mogę powiedzieć, w jaki sposób i dlaczego to się różni break-inside, ponieważ tylko ta ostatnia wydaje się być udokumentowana w specyfikacji W3. Jednak Chrome i Firefox obsługują następujące funkcje:

li {
    -webkit-column-break-inside:avoid;
       -moz-column-break-inside:avoid;
            column-break-inside:avoid;
}
keithjgrant
źródło
Nie działa to dla ogólnego <div class = "a">, gdzie „a” zastępuje twoje „Li” powyżej. Div wciąż włamał się do środka. FF 26
Nasser
To nie błąd. powyższy kod jest poprawny dla opisywanej funkcji, nawet jeśli jego selektor dotyczy tylko elementu li. W tym przykładzie nadal możesz użyć innego selektora CSS „div.a {...}” zamiast „li {...}”.
verdy_p
Jednak Chrome nadal nie obsługuje opcji -webkit-column-break-inside: unikaj; w wierszu tabeli: to nie działa i nadal nie możemy uniknąć dzielenia tabel w złych pozycjach (zwłaszcza jeśli komórka bajki zawiera nie tylko tekst, ale ikony; ale Chrome również wydaje się rozdzielać w dowolnym pionowym położeniu na środku linii tekstu , dzieląc tekst górną częścią glifów tekstowych u dołu pierwszej kolumny, a dolną część glifów tekstowych u góry następnej kolumny !!! Wynik jest absolutnie nieczytelny !!!
verdy_p
Począwszy od 2017 r., Łamanie kolumn nie wydaje się być prawidłową właściwością css. MDN mówi tylko: „Edge obsługuje również niestandardowy wariant -webkit-column-break-inside-inside”.
Jacob C. mówi Przywróć Monikę
9

To działa dla mnie w 2015 roku:

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
źródło
To działa na mnie na ulelementach, jest zamieszczona na sztuczki CSS: css-tricks.com/almanac/properties/b/break-inside i wydaje się poprawne na podstawie notatek z kompatybilnością caniuse: „Częściowe wsparcie dotyczy nie wspieranie break-before, break-after, break-insidewłaściwości . Przeglądarki oparte na WebKit i Blink mają równoważne wsparcie dla niestandardowych -webkit-column-break-*właściwości, aby osiągnąć ten sam wynik (ale tylko wartości autoi always). Firefox nie obsługuje, break-*ale obsługuje page-break-*właściwości dla osiągnięcia tego samego wyniku. ”
nabrown
3

Poniższy kod działa, aby zapobiec łamaniu kolumn wewnątrz elementów:

-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
źródło
3

W 2019 roku to działa dla mnie w Chrome, Firefox i Opera (po wielu innych nieudanych próbach):

.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
źródło
2

Wydaje się, że Firefox 26 wymaga

page-break-inside: avoid;

I potrzebuje Chrome 32

-webkit-column-break-inside:avoid;
   -moz-column-break-inside:avoid;
        column-break-inside:avoid;
MAPA
źródło
2

Myślę, że miałem ten sam problem i znalazłem rozwiązanie w tym:

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

Działa również w FF 38.0.5: http://jsfiddle.net/rkzj8qnv/

dichterDichter
źródło
To rozwiązanie pomaga mi
OzzyCzech,
1

Możliwym obejściem dla Firefoksa jest ustawienie właściwości CSS „display” elementu, w którym nie chcesz mieć przerwy, na „table”. Nie wiem, czy to działa dla tagu LI (prawdopodobnie stracisz styl listy -item), ale działa dla tagu P.

Krzysztof
źródło
To rozwiązanie usuwa element listy, więc jeśli na przykład korzystasz z list zamówień, nie byłoby to alternatywą.
Ricardo Zea,
1

Właśnie naprawiłem niektóre divs, które dzieliły się na następną kolumnę, dodając

overflow: auto

dla dziecka divs.

* Zrozumiałem, że to naprawia tylko w Firefoksie!

mateostabio
źródło
1

Napotkałem ten sam problem podczas korzystania z kolumn kart

naprawiłem to za pomocą

 display: inline-flex ;
 column-break-inside: avoid;
 width:100%;
Mysterious_Anny
źródło
1
<style>
ul li{display: table;}  
</style>

działa świetnie

Tahir
źródło
0

Dokonałem aktualizacji faktycznej odpowiedzi.

Wydaje się, że działa to na Firefox i 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 */
}

Uwaga: Właściwość float wydaje się być tą, która powoduje zachowanie bloku.

Gatsbimantico
źródło
0

Ta odpowiedź może dotyczyć tylko niektórych okoliczności; Jeśli ustawisz wysokość swoich elementów, będzie to zgodne ze stylem kolumny. Tam utrzymując wszystko, co jest zawarte na tej wysokości, w jednym rzędzie.

Miałem listę, taką jak operacja, ale zawierała dwa elementy, elementy i przyciski do działania na te elementy. Traktowałem go jak stół <ul> - table, <li> - table-row, <div> - table-cellumieścić UL w układzie 4 kolumny. Czasami kolumny były dzielone między przedmiot a przyciski. Sztuczka, której użyłem, polegała na nadaniu elementom Div wysokości linii pokrywającej przyciski.

Tod
źródło