Czy istnieje sposób na podzielenie listy na kolumny?

119

Moja strona internetowa ma „wąską” listę: na przykład listę 100 elementów o długości jednego słowa. Aby ograniczyć przewijanie, chcę przedstawić tę listę w dwóch lub nawet czterech kolumnach na stronie. Jak mam to zrobić z CSS?

<ul>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
</ul>

Wolę, aby rozwiązanie było elastyczne, więc jeśli lista powiększy się do 200 pozycji, nie będę musiał wykonywać wielu ręcznych dostosowań, aby dostosować się do nowej listy.

user776676
źródło
Jest biblioteka, która to robi - github.com/yairEO/listBreaker
vsync
Wierzę, że opcja kolumny CSS wystarczy. Ta opcja jest łatwa w użyciu i można ją zmienić, jeśli zajdzie taka potrzeba. Tutaj masz to szczegółowo wyjaśnione - kolosek.com/css-columns
Zoric

Odpowiedzi:

254

Rozwiązanie CSS to: http://www.w3.org/TR/css3-multicol/

Obsługa przeglądarki jest dokładnie tym, czego można się spodziewać.

Działa „wszędzie” z wyjątkiem Internet Explorera 9 lub starszego: http://caniuse.com/multicolumn

ul {
    -moz-column-count: 4;
    -moz-column-gap: 20px;
    -webkit-column-count: 4;
    -webkit-column-gap: 20px;
    column-count: 4;
    column-gap: 20px;
}

Zobacz: http://jsfiddle.net/pdExf/

Jeśli wymagana jest obsługa IE, będziesz musiał użyć JavaScript, na przykład:

http://welcome.totheinter.net/columnizer-jquery-plugin/

Innym rozwiązaniem jest powrót do normalnego tylkofloat: left dla IE . Kolejność będzie błędna, ale przynajmniej będzie wyglądać podobnie:

Zobacz: http://jsfiddle.net/NJ4Hw/

<!--[if lt IE 10]>
<style>
li {
    width: 25%;
    float: left
}
</style>
<![endif]-->

Możesz zastosować tę rezerwę za pomocą Modernizr, jeśli już jej używasz.

trzydzieści kropek
źródło
Czy istnieje sposób na usunięcie górnej granicy na pierwszej liw każdej kolumnie?
Tak Barry,
2
Działa to świetnie w przypadku stałej przestrzeni, ale staje się problemem w przypadku responsywnych projektów, ponieważ kolumny nie zwijają się, jak podczas korzystania z display: inline lub inline-block.
unifiedac
4
Ciekawostka: IE jest jedyną dużą przeglądarką komputerową, która w pełni obsługuje tę funkcję bez prefiksów (od IE10) ... Och, ironia ...
NemoStein
1
W celu lepszej obsługi wielu przeglądarek może być konieczne uwzględnienie tej dodatkowej właściwości, list-style-position: inside;która w szczególności rozwiązuje problem wskazany przez @vsync, jak sądzę.
ThisClark
4
@PrafullaKumarSahu: Spróbuj li { break-inside: avoid; }: jsfiddle.net/thirtydot/pdExf/903 . Nie znam kolumn CSS, więc może być lepszy sposób.
trzydzieści kropek
19

Jeśli szukasz rozwiązania, które działa również w IE, możesz przesunąć elementy listy w lewo. Jednak spowoduje to listę, która wije się wokół, na przykład:

item 1 | item 2 | item 3
item 4 | item 5

Zamiast zgrabnych kolumn, takich jak:

item 1 | item 4
item 2 | 
item 3 | 

Kod, który to zrobi, to:

ul li {
  width:10em;
  float:left;
}

Możesz dodać obramowanie do dołu do lis, aby przepływ elementów od lewej do prawej był bardziej widoczny.

Matt Hampel
źródło
chociaż może to zadziałać dla określonej liczby elementów, wynik nie będzie ładny dla zaledwie 2 elementów.
vsync
Inne działające rozwiązanie CSS dla „schludnych kolumn”: stackoverflow.com/q/54982323/1066234
Kai Noack
10

Jeśli chcesz mieć określoną liczbę kolumn, możesz użyć liczby kolumn i odstępu między kolumnami, jak wspomniano powyżej.

Jeśli jednak potrzebujesz pojedynczej kolumny o ograniczonej wysokości, która w razie potrzeby podzieliłaby się na więcej kolumn, można to osiągnąć w prosty sposób, zmieniając wyświetlanie na flex.

To nie zadziała w IE9 i niektórych innych starszych przeglądarkach. Możesz sprawdzić wsparcie na Czy mogę użyć

<style>
  ul {
    display: -ms-flexbox;           /* IE 10 */
    display: -webkit-flex;          /* Safari 6.1+. iOS 7.1+ */
    display: flex;
    -webkit-flex-flow: wrap column; /* Safari 6.1+ */
    flex-flow: wrap column;
    max-height: 150px;              /* Limit height to whatever you need */
  }
</style>

<ul>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
    <li>Item</li>
</ul>

Maciej Poleski
źródło
2
Bardzo blisko tego, do czego zmierzam. Jedynym minusem jest to, że szerokość kolumn nie dostosowuje się do treści (spróbuj z elementami o różnej długości). Nie wiem, jak zdefiniowano szerokość kolumny. Może z pierwszym elementem? W każdym razie jakieś wskazówki, jak temu zaradzić?
Jorgeh
Czy byłoby możliwe ograniczenie liczby kolumn zamiast wysokości? Potrzebuję elementów do wypełnienia w czterech kolumnach, a css column-countzrobi nierówną liczbę wierszy w kolumnach. Jak 6 pozycji w pierwszej kolumnie, potem 4, potem 6, potem 5.
Virge Assault
Byłoby miło, gdybyś
oznaczył
3

Ta odpowiedź niekoniecznie jest skalowana, ale wymaga jedynie niewielkich korekt w miarę powiększania się listy. Semantycznie może się to wydawać trochę sprzeczne z intuicją, ponieważ są to dwie listy, ale poza tym będzie wyglądać tak, jak chcesz w każdej przeglądarce.

ul {
  float: left;
}

ul > li {
  width: 6em;
}
<!-- Column 1 -->
<ul>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>
<!-- Column 2 -->
<ul>
  <li>Item 4</li>
  <li>Item 5</li>
  <li>Item 6</li>
</ul>

Alan Hape
źródło
2

2020 - nie komplikuj, używaj siatki CSS

Wiele z tych odpowiedzi jest nieaktualnych, jest rok 2020 i nie powinniśmy włączać osób, które nadal używają IE9. O wiele prostsze jest użycie siatki CSS .

Kod jest bardzo prosty i możesz łatwo dostosować liczbę kolumn za pomocą grid-template-columns. Zobacz to, a następnie pobaw się tymi skrzypcami, aby dopasować je do swoich potrzeb.

.grid-list {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
}
<ul class="grid-list">
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
  <li>item</li>
</ul>

maxshuty
źródło
1
To dla mnie najlepsze rozwiązanie.
Patee Gutee
1

Zauważyłem, że (obecnie) Chrome ( Version 52.0.2743.116 m) ma mnóstwo dziwactw i problemów z css column-countdotyczących elementów przepełnionych i elementów pozycjonowanych bezwzględnie w elementach, szczególnie w przypadku niektórych przejść wymiarów.

to totalny bałagan i nie można go naprawić, więc próbowałem rozwiązać ten problem za pomocą prostego javascript i utworzyłem bibliotekę, która to robi - https://github.com/yairEO/listBreaker

Strona demonstracyjna

vsync
źródło
Wolę wtyczkę jQuery columnizer, moim zdaniem miała lepszą funkcjonalność w stosunku do tego, co robiłem (był w stanie sortować alfabetycznie, malejąco lub rosnąco, liczbę kolumn, szerokość kolumn i więcej). jQuery Columnizer - WelcomeToTheInter.Net
Brandito
@Brandito - cóż, kod Columnizer z pewnością ma więcej opcji, ponieważ zawiera prawie 1000 linii kodu, w porównaniu do mojego, który ma około 120 linii ... ale działa dobrze
vsync
tak, ale mój problem wymagał, aby lista pozostała jako jedna lista, co jest bardziej przydatne / potrzebne, zależy od przypadku użycia.
Brandito
0

Jeśli możesz to wesprzeć Siatka CSS jest prawdopodobnie najczystszym sposobem na utworzenie jednowymiarowej listy w układzie dwóch kolumn z responsywnymi wnętrzami.

ul {
  max-width: 400px;
  display: grid;
  grid-template-columns: 50% 50%;
  padding-left: 0;
  border: 1px solid blue;
}

li {
  list-style: inside;
  border: 1px dashed red;
  padding: 10px;
}
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
  <li>6</li>
  <li>7</li>
  <li>8</li>
  <li>9</li>
<ul>

To są dwie kluczowe linie, które dadzą ci układ 2 kolumn

display: grid;
grid-template-columns: 50% 50%;
mattLummus
źródło
0

Pierwszy sposób na urządzenia mobilne polega na użyciu kolumn CSS do tworzenia wrażeń na mniejszych ekranach, a następnie za pomocą zapytań o media w celu zwiększenia liczby kolumn w każdym ze zdefiniowanych punktów przerwania układu.

ul {
  column-count: 2;
  column-gap: 2rem;
}
@media screen and (min-width: 768px)) {
  ul {
    column-count: 3;
    column-gap: 5rem;
  }
}
<ul>
  <li>Item</li>
  <li>Item</li>
  <li>Item</li>
  <li>Item</li>
  <li>Item</li>
  <li>Item</li>
  <li>Item</li>
  <li>Item</li>
  <li>Item</li>
  <li>Item</li>
</ul>

Josh Habdas
źródło
0

Oto co zrobiłem

ul {
      display: block;
      width: 100%;
}

ul li{
    display: block;
    min-width: calc(30% - 10px);
    float: left;
}

ul li:nth-child(2n + 1){
    clear: left;
}
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
  <li>6</li>
  <li>7</li>
  <li>8</li>
  <li>9</li>
  <li>0</li>
</ul>

GuruKay
źródło