Làm thế nào để hiển thị một danh sách không có thứ tự trong hai cột?


215

Với HTML sau đây, phương pháp dễ nhất để hiển thị danh sách dưới dạng hai cột là gì?

<ul>
    <li>A</li>
    <li>B</li>
    <li>C</li>
    <li>D</li>
    <li>E</li>
</ul>

Hiển thị mong muốn:

A B
C D
E

Giải pháp cần có khả năng hoạt động trên Internet Explorer.


1
Đây là một ví dụ trực tiếp về cách dễ dàng thực hiện trong jquery: jsfiddle.net/EebVF/5 Sử dụng plugin jquery này: github.com/fzondlo/jquery-columns - Tôi thích điều này tốt hơn với CSS vì với giải pháp CSS không phải mọi thứ đều phù hợp theo chiều dọc đến đỉnh.
newUserNameĐây là

Câu trả lời:


371

Trình duyệt hiện đại

tận dụng mô-đun cột css3 để hỗ trợ những gì bạn đang tìm kiếm.

http://www.w3schools.com/cssref/css3_pr_columns.asp

CSS:

ul {
  columns: 2;
  -webkit-columns: 2;
  -moz-columns: 2;
}

http://jsfiddle.net/HP85j/8/

Trình duyệt kế thừa

Thật không may cho hỗ trợ IE, bạn sẽ cần một giải pháp mã liên quan đến thao tác JavaScript và dom. Điều này có nghĩa là bất cứ khi nào nội dung của danh sách thay đổi, bạn sẽ cần thực hiện thao tác sắp xếp lại danh sách thành các cột và in lại. Giải pháp dưới đây sử dụng jQuery cho ngắn gọn.

http://jsfiddle.net/HP85j/19/

HTML:

<div>
    <ul class="columns" data-columns="2">
        <li>A</li>
        <li>B</li>
        <li>C</li>
        <li>D</li>
        <li>E</li>
        <li>F</li>
        <li>G</li>
    </ul>
</div>

JavaScript:

(function($){
    var initialContainer = $('.columns'),
        columnItems = $('.columns li'),
        columns = null,
        column = 1; // account for initial column
    function updateColumns(){
        column = 0;
        columnItems.each(function(idx, el){
            if (idx !== 0 && idx > (columnItems.length / columns.length) + (column * idx)){
                column += 1;
            }
            $(columns.get(column)).append(el);
        });
    }
    function setupColumns(){
        columnItems.detach();
        while (column++ < initialContainer.data('columns')){
            initialContainer.clone().insertBefore(initialContainer);
            column++;
        }
        columns = $('.columns');
    }

    $(function(){
        setupColumns();
        updateColumns();
    });
})(jQuery);

CSS:

.columns{
    float: left;
    position: relative;
    margin-right: 20px;
}

BIÊN TẬP:

Như được chỉ ra dưới đây sẽ sắp xếp các cột như sau:

A  E
B  F
C  G
D

trong khi OP yêu cầu một biến thể khớp với các điều sau:

A  B
C  D
E  F
G

Để thực hiện biến thể, bạn chỉ cần thay đổi mã thành như sau:

function updateColumns(){
    column = 0;
    columnItems.each(function(idx, el){
        if (column > columns.length){
            column = 0;
        }
        $(columns.get(column)).append(el);
        column += 1;
    });
}

2
Bạn không hiển thị các mục theo đúng thứ tự: jsfiddle.net/HP85j/258 Ví dụ: màn hình mong muốn trong dòng đầu tiên là A B(yếu tố thứ hai nên được thêm vào bên phải), nhưng trong ví dụ của bạn là A E.
Paolo Moretti

1
Công việc tuyệt vời, mặc dù logic bị lỗi nếu có nhiều hơn 2 cột, tôi đã tạo bản sửa lỗi ở đây: jsfiddle.net/HP85j/393
Tr1stan

2
những viên đạn bị thiếu
Jaider

1
Có lẽ nhiều khả năng muốn danh sách điền vào cột 1 trước cột 2. Có thể dễ dàng hơn để sắp xếp lại các mục của danh sách để có vẻ như chúng được điền trước khi xuống. Tất nhiên điều đó có thể yêu cầu làm lại nếu danh sách thay đổi. Dù sao, câu trả lời CSS của Gabriel chỉ là những gì tôi cần, cảm ơn bạn!
trừng phạt

3
Chỉ là một bản cập nhật muộn, tôi tin rằng tùy chọn đầu tiên sẽ hoạt động trong các trình duyệt IE hiện đại.
Fizz

82

Tôi đã xem xét giải pháp của @ jaider có hiệu quả nhưng tôi đang cung cấp một cách tiếp cận hơi khác mà tôi nghĩ là dễ làm việc hơn và tôi thấy nó tốt trên các trình duyệt.

ul{
    list-style-type: disc;
    -webkit-columns: 2;
    -moz-columns: 2;
    columns: 2;
    list-style-position: inside;//this is important addition
}

Theo mặc định, danh sách không có thứ tự hiển thị vị trí dấu đầu dòng bên ngoài nhưng sau đó trong một số trình duyệt, nó sẽ gây ra một số vấn đề hiển thị dựa trên cách trình bày trang web của trình duyệt.

Để làm cho nó hiển thị ở định dạng:

A B
C D
E

vv sử dụng như sau:

ul li{
    float: left;
    width: 50%;//helps to determine number of columns, for instance 33.3% displays 3 columns
}
ul{
    list-style-type: disc;
}

Điều này sẽ giải quyết tất cả các vấn đề của bạn với việc hiển thị các cột. Tất cả là tốt nhất và cảm ơn @jaider vì phản hồi của bạn đã giúp hướng dẫn tôi khám phá điều này.


3
Có một vấn đề với phương pháp này. Nó hoạt động tuyệt vời để hiển thị các mục danh sách rất ngắn (1 ký tự trong ví dụ này). Tạo một danh sách với các mô tả dài hơn và cột thứ hai chồng lên cột thứ nhất, cũng như chạy ra khỏi thùng chứa ul.
Xù xì

1
Tôi đã tinh chỉnh điều này một chút bằng cách thay đổi float: left để hiển thị: block-inline cho các phần tử li, ngoài ra điều này làm việc kỳ diệu đối với tôi.
ZeRemz

41

Tôi đã cố gắng đăng bài này dưới dạng một bình luận, nhưng không thể để các cột hiển thị đúng (theo câu hỏi của bạn).

Bạn đang yêu cầu:

AB

CD

E

... nhưng câu trả lời được chấp nhận là giải pháp sẽ trả về:

QUẢNG CÁO

C

... Vì vậy, hoặc câu trả lời là không chính xác hoặc câu hỏi là.

Một giải pháp rất đơn giản là đặt chiều rộng của bạn <ul>và sau đó thả nổi và đặt chiều rộng của các <li>mục của bạn như vậy

<ul>
    <li>A</li>
    <li>B</li>
    <li>C</li>
    <li>D</li>
    <li>E</li>
</ul>

ul{
    width:210px;
}
li{
    background:green;
    float:left;
    height:100px;
    margin:0 10px 10px 0;
    width:100px;
}
li:nth-child(even){
    margin-right:0;
}

Ví dụ ở đây http://jsfiddle.net/Jayx/Qbz9S/1/

Nếu câu hỏi của bạn sai, thì các câu trả lời trước sẽ được áp dụng (với bản sửa lỗi JS vì thiếu hỗ trợ IE).


@Gabriel giải pháp của bạn và hành vi là tốt và như mong đợi, vì vậy tôi không cố gắng gõ câu trả lời của bạn này ... Tôi chỉ nghĩ rằng câu hỏi có thể đã bị hiểu sai ... dù bằng cách nào - câu hỏi đã được trả lời bất kể đó là câu hỏi đúng: D
Jayx

16

Tôi thích giải pháp cho các trình duyệt hiện đại, nhưng đạn bị thiếu, vì vậy tôi thêm vào đó một mẹo nhỏ:

http://jsfiddle.net/HP85j/419/

ul {
    list-style-type: none;
    columns: 2;
    -webkit-columns: 2;
    -moz-columns: 2;
}


li:before {
  content: "• ";
}

nhập mô tả hình ảnh ở đây


Ở đây chúng ta có thể thay đổi màu của các vật phẩm mà không thay đổi màu của viên đạn jsfiddle.net/HP85j/444
Jaider

3
Tôi nghĩ list-style-position: inside;là một giải pháp tốt hơn cho những viên đạn xuất hiện đúng cách.
Alexis Wilke

11

Đây là một giải pháp khả thi:

Đoạn trích:

ul {
  width: 760px;
  margin-bottom: 20px;
  overflow: hidden;
  border-top: 1px solid #ccc;
}
li {
  line-height: 1.5em;
  border-bottom: 1px solid #ccc;
  float: left;
  display: inline;
}
#double li {
  width: 50%;
}
<ul id="double">
  <li>first</li>
  <li>second</li>
  <li>third</li>
  <li>fourth</li>
</ul>

Và nó đã được thực hiện.
Đối với 3 cột sử dụng lichiều rộng là 33%, đối với 4 cột sử dụng 25%, v.v.


5

Đây là cách đơn giản nhất để làm điều đó. Chỉ CSS.

  1. thêm chiều rộng cho phần tử ul.
  2. thêm hiển thị: khối nội tuyến và chiều rộng của cột mới (nên nhỏ hơn một nửa chiều rộng ul).
ul.list {
  width: 300px;  
}

ul.list li{
  display:inline-block;
  width: 100px;
}
<ul class="list">
    <li>A</li>
    <li>B</li>
    <li>C</li>
    <li>D</li>
    <li>E</li>
</ul>

2
Thêm một số giải thích với câu trả lời về cách câu trả lời này giúp OP khắc phục vấn đề hiện tại
ρяσѕρєя K

4

Bạn chỉ có thể sử dụng CSS để đặt hai cột trở lên

AE

B

C

D

 <ul class="columns">
    <li>A</li>
    <li>B</li>
    <li>C</li>
    <li>D</li>
    <li>E</li>
</ul>

ul.columns  {
   -webkit-columns: 60px 2;
   -moz-columns: 60px 2;
    columns: 60px 2;
   -moz-column-fill: auto;
   column-fill: auto;
 }

3

Điều này có thể đạt được bằng cách sử dụng thuộc tính css đếm cột trên div cha

giống

 column-count:2;

kiểm tra này để biết thêm chi tiết

Cách làm cho danh sách DIV nổi xuất hiện trong các cột, không phải hàng


1
column-countsẽ không hiển thị các mục theo đúng thứ tự. Ví dụ, màn hình mong muốn trong dòng đầu tiên là A B(phần tử thứ hai sẽ được thêm vào bên phải), nhưng nếu bạn sử dụng column-countthì nó sẽ như vậy A E.
Paolo Moretti

2

Ví dụ, bạn có thể thực hiện việc này một cách dễ dàng với Plugin jQuery-Cột để phân chia một ul với một lớp .mylist bạn sẽ làm

$('.mylist').cols(2);

Đây là một ví dụ trực tiếp trên jsfiddle

Tôi thích điều này tốt hơn với CSS bởi vì với giải pháp CSS, không phải mọi thứ đều thẳng hàng với nhau.


Thú vị, nhưng nó thực sự phá vỡ <ul>danh sách trong nhiều danh sách ... Điều đó có thể làm phức tạp những thứ khác.
Alexis Wilke

Đây thực sự là giải pháp tôi đã cảm ơn, với người đánh giá thấp câu trả lời này là hợp lệ nếu bạn đọc câu hỏi của OP và không cần DV.
Tricky

2

Thêm một câu trả lời sau một vài năm!

trong bài viết này: http://csswizardry.com/2010/02/mutipl-column-lists-USE-one-ul/

HTML:

<ul id="double"> <!-- Alter ID accordingly -->
  <li>CSS</li>
  <li>XHTML</li>
  <li>Semantics</li>
  <li>Accessibility</li>
  <li>Usability</li>
  <li>Web Standards</li>
  <li>PHP</li>
  <li>Typography</li>
  <li>Grids</li>
  <li>CSS3</li>
  <li>HTML5</li>
  <li>UI</li>
</ul>

CSS:

ul{
  width:760px;
  margin-bottom:20px;
  overflow:hidden;
  border-top:1px solid #ccc;
}
li{
  line-height:1.5em;
  border-bottom:1px solid #ccc;
  float:left;
  display:inline;
}
#double li  { width:50%;}
#triple li  { width:33.333%; }
#quad li    { width:25%; }
#six li     { width:16.666%; }

1

Trong updateColumns()nhu cầu if (column >= columns.length)chứ không phải if (column > columns.length)liệt kê tất cả các yếu tố (C được bỏ qua ví dụ) như vậy:

function updateColumns(){
    column = 0;
    columnItems.each(function(idx, el){
        if (column >= columns.length){
            column = 0;
        }
        console.log(column, el, idx);
        $(columns.get(column)).append(el);
        column += 1;
    });
}

http://jsfiddle.net/e2vH9/1/



1

Giải pháp kế thừa trong câu trả lời hàng đầu không hiệu quả với tôi vì tôi muốn ảnh hưởng đến nhiều danh sách trên trang và câu trả lời giả định một danh sách duy nhất cộng với nó sử dụng một chút trạng thái toàn cầu. Trong trường hợp này tôi muốn thay đổi mọi danh sách bên trong <section class="list-content">:

const columns = 2;
$("section.list-content").each(function (index, element) {
    let section = $(element);
    let items = section.find("ul li").detach();
    section.find("ul").detach();
    for (let i = 0; i < columns; i++) {
        section.append("<ul></ul>");
    }
    let lists = section.find("ul");
    for (let i = 0; i < items.length; i++) {
        lists.get(i % columns).append(items[i]);
    }
});

làm thế nào có thể ví dụ tạo hai cột, một cột chỉ chứa ô và cột còn lại là một danh sách không có thứ tự?
Dalek

Không hoàn toàn chắc chắn những gì bạn có ý nghĩa. Nếu bạn có một loạt các mục có tiêu đề, bạn có thể đặt chúng vào một danh sách duy nhất tiêu đề, mục, tiêu đề, mục và sau đó điều này sẽ làm việc cho bạn.
Tom

1

Mặc dù tôi đã tìm thấy câu trả lời của Gabriel để làm việc ở một mức độ nào đó, tôi đã tìm thấy những điều sau đây khi cố gắng sắp xếp danh sách theo chiều dọc (lần đầu tiên ul AD và lần thứ hai ul EG):

  • Khi ul có số li chẵn trong đó, nó không trải đều trên ul
  • sử dụng cột dữ liệu trong ul dường như không hoạt động tốt, tôi đã phải đặt 4 cho 3 cột và thậm chí sau đó nó vẫn chỉ lan truyền li vào 2 trong số ul do JS tạo ra

Tôi đã sửa đổi JQuery để hy vọng điều đó không xảy ra.

(function ($) {
    var initialContainer = $('.customcolumns'),
        columnItems = $('.customcolumns li'),
        columns = null,
        column = 0;
    function updateColumns() {
        column = 0;
        columnItems.each(function (idx, el) {
            if ($(columns.get(column)).find('li').length >= (columnItems.length / initialContainer.data('columns'))) {
                column += 1;
            }
            $(columns.get(column)).append(el);
        });
    }
    function setupColumns() {
        columnItems.detach();
        while (column++ < initialContainer.data('columns')) {
            initialContainer.clone().insertBefore(initialContainer);
            column++;
        }
        columns = $('.customcolumns');
        updateColumns();
    }

    $(setupColumns);
})(jQuery);
.customcolumns {
  float: left;
  position: relative;
  margin-right: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <ul class="customcolumns" data-columns="3">
    <li>A</li>
    <li>B</li>
    <li>C</li>
    <li>D</li>
    <li>E</li>
    <li>F</li>
    <li>G</li>
    <li>H</li>
    <li>I</li>
    <li>J</li>
    <li>K</li>
    <li>L</li>
    <li>M</li>
  </ul>
</div>

-1

Đây là một giải pháp hoàn hảo cho tôi, tìm kiếm nó trong nhiều năm:

http://css-tricks.com/forums/topic/two-column-unordered-list/


3
"Luôn trích dẫn phần có liên quan nhất của một liên kết quan trọng, trong trường hợp trang đích không thể truy cập được hoặc ngoại tuyến vĩnh viễn" - stackoverflow.com/help/how-to-answer
Sk8erPeter

Không cần - đó là liên kết / tham chiếu cho mã được sử dụng Abdultrong câu trả lời của anh ấy, giống hệt với chiều rộng và ID được sử dụng.
cssyphus
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.