วิธีแสดงรายการที่ไม่เรียงลำดับในสองคอลัมน์


215

ด้วย HTML ต่อไปนี้วิธีที่ง่ายที่สุดในการแสดงรายการเป็นสองคอลัมน์คืออะไร?

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

จอแสดงผลที่ต้องการ:

A B
C D
E

การแก้ปัญหาจะต้องสามารถทำงานได้บน Internet Explorer


1
นี่คือตัวอย่างจริงของวิธีการทำ jquery อย่างง่าย: jsfiddle.net/EebVF/5 การใช้ jquery plugin นี้: github.com/fzondlo/jquery-columns - ฉันชอบสิ่งนี้ดีกว่าด้วย CSS เพราะทุกอย่างอยู่ใน CSS แนวตั้งขึ้นไปด้านบน
newUserName ที่นี่

คำตอบ:


371

เบราว์เซอร์ที่ทันสมัย

ใช้ประโยชน์จากโมดูลคอลัมน์ css3 เพื่อสนับสนุนสิ่งที่คุณกำลังมองหา

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

CSS:

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

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

เบราว์เซอร์ดั้งเดิม

น่าเสียดายสำหรับการสนับสนุน IE คุณจะต้องใช้โซลูชันรหัสที่เกี่ยวข้องกับการจัดการ JavaScript และ dom ซึ่งหมายความว่าเมื่อใดก็ตามที่เนื้อหาของรายการเปลี่ยนแปลงคุณจะต้องดำเนินการเพื่อจัดลำดับรายการใหม่ลงในคอลัมน์และพิมพ์ซ้ำ การแก้ปัญหาด้านล่างใช้ jQuery เพื่อความกระชับ

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

แก้ไข:

ดังที่อธิบายไว้ด้านล่างนี้จะเรียงลำดับคอลัมน์ดังต่อไปนี้:

A  E
B  F
C  G
D

ในขณะที่ OP ขอตัวแปรที่ตรงกับต่อไปนี้:

A  B
C  D
E  F
G

ในการทำให้ชุดตัวเลือกสำเร็จคุณเพียงแค่เปลี่ยนรหัสเป็นดังต่อไปนี้:

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

2
คุณไม่ได้แสดงรายการในลำดับที่ถูกต้อง: jsfiddle.net/HP85j/258ตัวอย่างเช่นการแสดงผลที่ต้องการในบรรทัดแรกA B(องค์ประกอบที่สองควรจะต่อท้ายด้านขวา) A Eแต่ในตัวอย่างของคุณ
เปาโล Moretti

1
ทำงานได้ดีแม้ว่าตรรกะจะมีข้อบกพร่องหากมีมากกว่า 2 คอลัมน์ฉันได้สร้างการแก้ไขที่นี่: jsfiddle.net/HP85j/393
Tr1stan

2
กระสุนหายไป
Jaider

1
มีแนวโน้มที่จะต้องการให้รายการเติมคอลัมน์ 1 ก่อนคอลัมน์ 2 อาจจะง่ายกว่าในการจัดลำดับรายการในรายการใหม่เพื่อให้ปรากฏว่ารายการเหล่านั้นเติมเต็มก่อนลงมา แน่นอนว่าอาจต้องมีการทำซ้ำหากรายการเปลี่ยนแปลง อย่างไรก็ตามคำตอบ CSS ของ Gabriel เป็นเพียงสิ่งที่ฉันต้องการขอบคุณ!
punstress

3
เพิ่งได้รับการปรับปรุงล่าช้าฉันเชื่อว่าตัวเลือกแรกจะทำงานบนเบราว์เซอร์ IE สมัยใหม่
Fizz

82

ฉันกำลังดูโซลูชันของ @ jaider ซึ่งใช้ได้ แต่ฉันเสนอวิธีที่แตกต่างออกไปเล็กน้อยซึ่งฉันคิดว่าง่ายกว่าที่จะทำงานด้วยและที่ฉันเห็นว่าดีในเบราว์เซอร์

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

ตามค่าเริ่มต้นรายการที่ไม่ได้สั่งซื้อจะแสดงตำแหน่งหัวกระสุนด้านนอก แต่ในบางเบราว์เซอร์จะทำให้เกิดปัญหาการแสดงผลตามวิธีการวางโครงสร้างเว็บไซต์ของเบราว์เซอร์

หากต้องการให้แสดงในรูปแบบ:

A B
C D
E

ฯลฯ ใช้ต่อไปนี้:

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

วิธีนี้จะช่วยแก้ปัญหาทั้งหมดของคุณด้วยการแสดงคอลัมน์ ทั้งหมดที่ดีที่สุดและขอบคุณ @jaider เป็นคำตอบของคุณช่วยแนะนำให้ฉันค้นพบนี้


3
มีปัญหากับวิธีนี้ มันใช้งานได้ดีสำหรับการแสดงรายการในรายการสั้น ๆ (1 ตัวอักษรในตัวอย่างนี้) สร้างรายการที่มีคำอธิบายที่ยาวขึ้นและคอลัมน์ที่สองทับซ้อนกับคอลัมน์แรกเช่นเดียวกับกรณีที่ไม่มีคอนเทนเนอร์ ul
Shaggy

1
ฉัน tweaked นี้เล็กน้อยโดยการเปลี่ยนลอย: ซ้ายเพื่อแสดง: บล็อกแบบอินไลน์สำหรับองค์ประกอบ li อื่น ๆ นอกเหนือจากนี้ทำงานได้มหัศจรรย์สำหรับฉัน
ZeRemz

41

ฉันพยายามโพสต์สิ่งนี้เป็นความคิดเห็น แต่ไม่สามารถแสดงคอลัมน์ได้ถูกต้อง (ตามคำถามของคุณ)

คุณกำลังขอ:

AB

ซีดี

E

... แต่คำตอบที่ได้รับการยอมรับในฐานะโซลูชันจะกลับมา

AD

พ.ศ.

... ดังนั้นคำตอบไม่ถูกต้องหรือเป็นคำถาม

วิธีแก้ปัญหาที่ง่ายมากคือการตั้งค่าความกว้างของคุณ<ul>แล้วลอยและตั้งค่าความกว้างของ<li>รายการของคุณ

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

ตัวอย่างที่นี่http://jsfiddle.net/Jayx/Qbz9S/1/

หากคำถามของคุณไม่ถูกต้องคำตอบก่อนหน้านี้จะนำไปใช้ (พร้อมกับการแก้ไข JS สำหรับการขาดการสนับสนุน IE)


@ Gabriel ทางออกและพฤติกรรมของคุณดีและเป็นไปตามคาดดังนั้นฉันจึงไม่พยายามที่จะตอบคำถามของคุณเฮ้ ... ฉันแค่คิดว่าคำถามอาจถูกตีความผิด ... ไม่ทางใดก็ทางหนึ่ง - คำถามได้รับการตอบแล้วไม่ว่า ซึ่งเป็นคำถามที่ถูกต้อง: D
Jayx

16

ฉันชอบวิธีแก้ปัญหาสำหรับเบราว์เซอร์ที่ทันสมัย ​​แต่กระสุนหายไปดังนั้นฉันจึงเพิ่มมันเล็กน้อย:

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

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


li:before {
  content: "• ";
}

ป้อนคำอธิบายรูปภาพที่นี่


ที่นี่เราสามารถเปลี่ยนสีของรายการโดยไม่ต้องเปลี่ยนสีของกระสุนjsfiddle.net/HP85j/444
Jaider

3
ฉันคิดว่าlist-style-position: inside;เป็นวิธีที่ดีกว่าสำหรับกระสุนที่จะแสดงอย่างถูกต้อง
Alexis Wilke

11

นี่คือทางออกที่เป็นไปได้:

ตัวอย่างข้อมูล:

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>

และมันก็ทำ
สำหรับ 3 คอลัมน์ใช้liความกว้างเป็น 33% สำหรับ 4 คอลัมน์ใช้ 25% และอื่น ๆ


5

นี่เป็นวิธีที่ง่ายที่สุดที่จะทำ CSS เท่านั้น

  1. เพิ่มความกว้างให้กับองค์ประกอบ ul
  2. เพิ่ม display: inline-block และ width ของคอลัมน์ใหม่ (ควรน้อยกว่าครึ่งหนึ่งของความกว้าง 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
เพิ่มคำอธิบายพร้อมคำตอบสำหรับวิธีที่คำตอบนี้ช่วย OP ในการแก้ไขปัญหาปัจจุบัน
Kяσѕρєя K

4

คุณสามารถใช้CSSเพื่อตั้งสองคอลัมน์หรือมากกว่าเท่านั้น

AE

B

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

สิ่งนี้สามารถทำได้โดยใช้คุณสมบัติการนับคอลัมน์จาก css บน div parent

ชอบ

 column-count:2;

ตรวจสอบรายละเอียดเพิ่มเติมจากนี้

วิธีสร้างรายการ DIV แบบลอยปรากฏในคอลัมน์ไม่ใช่แถว


1
column-countจะไม่แสดงรายการในลำดับที่ถูกต้อง ยกตัวอย่างเช่นการแสดงผลที่ต้องการในบรรทัดแรกคือA B(องค์ประกอบที่สองควรจะต่อท้ายด้านขวา) แต่ถ้าคุณใช้มันจะเป็นcolumn-count A E
เปาโล Moretti

2

คุณสามารถทำสิ่งนี้ได้อย่างง่ายดายด้วยปลั๊กอิน jQuery-Columnsเพื่อแบ่ง ul ด้วยคลาส. mylist ที่คุณจะทำ

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

นี่คือตัวอย่างสดของ jsfiddle

ฉันชอบสิ่งนี้ดีกว่าด้วย CSS เพราะด้วยโซลูชัน CSS ไม่ใช่ทุกสิ่งที่จัดแนวตั้งขึ้นไปด้านบน


ที่น่าสนใจ แต่จริง ๆ แล้วแบ่ง<ul>รายชื่อในหลายรายการ ... ที่อาจซับซ้อนสิ่งอื่น ๆ
Alexis Wilke

นี่เป็นวิธีการแก้ปัญหาที่ฉันหลังจากขอบคุณไปยัง downvoter คำตอบนี้ถูกต้องถ้าคุณอ่านคำถามของ OP และไม่จำเป็นต้องมี DV
Tricky

2

อีกหนึ่งคำตอบหลังจากไม่กี่ปี!

ในบทความนี้: http://csswizardry.com/2010/02/mutiple-column-lists-using-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

ในupdateColumns()ความต้องการif (column >= columns.length)มากกว่าif (column > columns.length)ที่จะแสดงรายการองค์ประกอบทั้งหมด (C จะข้ามตัวอย่าง) ดังนั้น:

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

โซลูชันแบบดั้งเดิมในคำตอบอันดับต้นไม่ได้ผลสำหรับฉันเพราะฉันต้องการส่งผลต่อหลายรายการในหน้าและคำตอบจะถือว่าเป็นรายการเดียวรวมถึงใช้บิตของสถานะทั่วโลก ในกรณีนี้ฉันต้องการแก้ไขทุกรายการภายใน<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]);
    }
});

เป็นไปได้อย่างไรที่อินสแตนซ์จะสร้างสองคอลัมน์คอลัมน์หนึ่งเพิ่งมีไทล์และอีกอันเป็นรายการที่ไม่เรียงลำดับ
Dalek

ไม่แน่ใจว่าคุณหมายถึงอะไร หากคุณมีชุดรายการที่มีชื่อเรื่องคุณสามารถใส่รายการเหล่านั้นไว้ในรายการเดียวที่ชื่อหัวเรื่องรายการชื่อเรื่องรายการแล้วสิ่งนี้น่าจะเหมาะกับคุณ
Tom

1

แม้ว่าฉันจะพบคำตอบของ Gabriel ในการทำงานในระดับหนึ่ง แต่ฉันก็พบสิ่งต่อไปนี้เมื่อพยายามสั่งรายการในแนวตั้ง (ul ul แรกและ ul ul EG ที่สอง):

  • เมื่อ ul มีจำนวน li อยู่ในนั้นมันก็ไม่ได้กระจายไปทั่วทั้ง ul
  • การใช้ data-column ใน ul ไม่ได้ผลดีมากฉันต้องวาง 4 สำหรับ 3 คอลัมน์และแม้กระทั่งจากนั้นมันก็ยังคงแพร่กระจาย li ไปเป็น 2 ของ ul ที่สร้างโดย JS

ฉันได้แก้ไข JQuery แล้วหวังว่าจะไม่เกิดขึ้น

(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

นี่เป็นโซลูชั่นที่สมบูรณ์แบบสำหรับฉันดูมาหลายปี:

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


3
"อ้างอิงส่วนที่เกี่ยวข้องที่สุดของลิงก์สำคัญเสมอในกรณีที่ไซต์เป้าหมายไม่สามารถเข้าถึงหรือออฟไลน์ถาวร" - stackoverflow.com/help/how-to-answer
Sk8erPeter

ไม่จำเป็น - เป็นลิงค์ / อ้างอิงสำหรับรหัสที่ใช้Abdulในคำตอบของเขาซึ่งเหมือนกับความกว้างและ ID ที่ใช้
cssyphus
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.