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.


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>


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.


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;

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;

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.


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

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>


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;

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

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;


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.


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!


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

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

działa świetnie


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.


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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.