CSS ngắt dòng trước / sau một mục `inline-block` cụ thể


202

Hãy nói rằng tôi có HTML này:

<h3>Features</h3>
<ul>
    <li><img src="alphaball.png">Smells Good</li>
    <li><img src="alphaball.png">Tastes Great</li>
    <li><img src="alphaball.png">Delicious</li>
    <li><img src="alphaball.png">Wholesome</li>
    <li><img src="alphaball.png">Eats Children</li>
    <li><img src="alphaball.png">Yo' Mama</li>
</ul>

và CSS này:

li { text-align:center; display:inline-block; padding:0.1em 1em }
img { width:64px; display:block; margin:0 auto }

Kết quả có thể xem tại đây: http://jsfiddle.net/YMN7U/1/

Bây giờ hãy tưởng tượng rằng tôi muốn chia nó thành ba cột, tương đương với việc tiêm a <br>sau cột thứ ba <li>. (Trên thực tế, việc đó sẽ không hợp lệ về mặt ngữ nghĩa và cú pháp.)

Tôi biết cách chọn thứ ba <li>trong CSS, nhưng làm cách nào để buộc ngắt dòng sau nó? Điều này không hoạt động:

li:nth-child(4):after { content:"xxx"; display:block }

Tôi cũng biết rằng trường hợp cụ thể này có thể bằng cách sử dụng floatthay vì inline-block, nhưng tôi không quan tâm đến các giải pháp sử dụng float. Tôi cũng biết rằng với các khối có chiều rộng cố định, điều này có thể thực hiện được bằng cách đặt chiều rộng trên bố mẹ ulthành khoảng 3x chiều rộng đó; Tôi không quan tâm đến giải pháp này. Tôi cũng biết rằng tôi có thể sử dụng display:table-cellnếu tôi muốn các cột thực sự; Tôi không quan tâm đến giải pháp này. Tôi quan tâm đến khả năng buộc phải nghỉ trong nội dung nội tuyến.

Chỉnh sửa : Để rõ ràng, tôi quan tâm đến 'lý thuyết', không phải là giải pháp cho một vấn đề cụ thể. CSS có thể tạo ra một ngắt dòng ở giữa các display:inline(-block)?phần tử, hoặc là không thể? Nếu bạn chắc chắn rằng điều đó là không thể, đó là một câu trả lời chấp nhận được.


2
Đặt ba thứ nhất và thứ ba thứ ba trong hai danh sách khác nhau? Tôi cho rằng bạn không muốn làm điều này, nhưng tôi nghĩ tôi sẽ ném nó ra khỏi đó.
JakeParis

Có vẻ như bạn cần cho chúng tôi biết những gì bạn đang thực sự cố gắng đạt được ở đây để ai đó có thể đề xuất phương pháp tốt nhất. Tất cả các tùy chọn bạn loại trừ tồn tại để giải quyết vấn đề bạn có, tại sao lại cần một giải pháp khác?
Jake

4
@Jake Tôi thực tế đã làm chính xác những gì tôi đã nêu: sử dụng một danh sách các yếu tố ngữ nghĩa và muốn bọc sau các yếu tố cụ thể. Trong thực tế tôi đặt chiều rộng của container, nhưng điều này chỉ hoạt động trong trường hợp cụ thể của tôi bởi vì các mục xảy ra có cùng chiều rộng và tôi muốn chúng được bọc ở một cạnh nhất quán. Điều này có thể không phải luôn luôn là trường hợp. Những gì tôi "thực sự đang cố gắng để đạt được" là tìm hiểu xem liệu CSS có thể buộc ngắt dòng ở giữa dòng nội tuyến hay không. Câu trả lời tự tin "Điều này chắc chắn là không thể" được chấp nhận (nếu đúng).
Phrogz

Câu trả lời:


302

Tôi đã có thể làm cho nó hoạt động trên các phần tử LI nội tuyến. Thật không may, nó không hoạt động nếu các phần tử LI là khối nội tuyến:

Bản demo trực tiếp: http://jsfiddle.net/dWkdp/

Hoặc phiên bản ghi chú trên vách đá:

li { 
     display: inline; 
}
li:nth-child(3):after { 
     content: "\A";
     white-space: pre; 
}

2
Sime, tại sao "\ A" không được in ra? Mọi thứ tôi đã thử với :afterbản in luôn là văn bản thẳng.
JakeParis

12
@JMCCreative Đó là nhân vật ASCII 0x0A, AKA, một nhân vật (dòng cấp dữ liệu). Xem w3.org/TR/CSS2/syndata.html#strings
Phrogz

5
@JMC \Alà nhân vật nguồn cấp dữ liệu ... đó là một lối thoát
Šime Vidas


18
bình luận ở đây khi tôi tiếp tục quay lại câu hỏi này vài tháng một lần ... Nó sẽ không hoạt động trên khối nội tuyến vì bạn đang thêm ngắt dòng trong một cái gì đó mà nó hoạt động như một thùng chứa khối trong bối cảnh nội tuyến. Nếu bạn có thể thoát ra khỏi bối cảnh bằng cách chèn ngắt dòng giữa <li> thì nó sẽ hoạt động. Thật xấu hổ vì điều này rất hữu ích cho các điểm dừng thiết kế đáp ứng. Tôi đoán phần lớn thời gian "nội tuyến" cũng hữu ích như chặn nội tuyến cho danh sách
user1010892

21

Bạn không quan tâm đến nhiều "giải pháp" cho vấn đề của mình. Tôi không nghĩ rằng thực sự có một cách tốt để làm những gì bạn muốn làm. Bất cứ điều gì bạn chèn bằng cách sử dụng :aftercontentcó chính xác cú pháp và hiệu lực ngữ nghĩa giống như nó sẽ được thực hiện nếu bạn vừa tự viết nó vào đó.

Các công cụ CSS cung cấp công việc. Bạn chỉ nên thả nổi livà sau đó clear: leftkhi bạn muốn bắt đầu một dòng mới, như bạn đã đề cập:

Xem một ví dụ: http://jsfiddle.net/marcuswhybrow/YMN7U/5/


18
OP không quan tâm đến giải pháp của bạn :)
Vidime Vidas

2
Không có gì bạn có thể làm bằng cách sử dụng :aftersẽ có giá trị cú pháp hoặc một ý tưởng tốt, vì đã có sẵn các công cụ để làm điều này. Do đó câu trả lời.
Marcus Whybrow

32
Một lý do để không sử dụng phao là không có những thứ như vậy float: center.
Mí mắt

7
cộng với khối nội tuyến cho phép tất cả các loại căn chỉnh dọc không thể nổi
user1010892

20
"Bất cứ điều gì bạn chèn bằng cách sử dụng: sau và nội dung có chính xác cú pháp và hiệu lực ngữ nghĩa giống nhau" - đến bữa tiệc muộn, nhưng tôi hoàn toàn không đồng ý với điều này - toàn bộ quan điểm sử dụng: trước và: sau là có thể chèn kiểu dáng đó không can thiệp vào ý nghĩa ngữ nghĩa của Html.
Rupert

4

Khi viết lại html được cho phép, bạn có thể lồng <ul>s vào trong <ul>và chỉ để <li>màn hình bên trong hiển thị dưới dạng khối nội tuyến. Điều này cũng có nghĩa về mặt ngữ nghĩa IMHO, vì việc phân nhóm cũng được phản ánh trong html.


<ul>
    <li>
        <ul>
            <li>Item 1</li>
            <li>Item 2</li>
            <li>Item 3</li>
        </ul>
    </li>
    <li>
        <ul>
            <li>Item 4</li>
            <li>Item 5</li>
            <li>Item 6</li>
        </ul>
    </li>
</ul>

li li { display:inline-block; }

Bản giới thiệu

$(function() { $('img').attr('src', 'http://phrogz.net/tmp/alphaball.png'); });
h3 {
  border-bottom: 1px solid #ccc;
  font-family: sans-serif;
  font-weight: bold;
}
ul {
  margin: 0.5em auto;
  list-style-type: none;
}
li li {
  text-align: center;
  display: inline-block;
  padding: 0.1em 1em;
}
img {
  width: 64px;
  display: block;
  margin: 0 auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<h3>Features</h3>
<ul>
  <li>
    <ul>
      <li><img />Smells Good</li>
      <li><img />Tastes Great</li>
      <li><img />Delicious</li>
    </ul>
  </li>
  <li>
    <ul>
      <li><img />Wholesome</li>
      <li><img />Eats Children</li>
      <li><img />Yo' Mama</li>
    </ul>
  </li>
</ul>


3

Một cách dễ dàng để phân chia danh sách thành các hàng là bằng cách thả các mục danh sách riêng lẻ và sau đó mục bạn muốn chuyển đến dòng tiếp theo bạn có thể xóa dấu phẩy.

ví dụ

<li style="float: left; display: inline-block"></li>
<li style="float: left; display: inline-block"></li>
<li style="float: left; display: inline-block"></li>

<li style="float: left; display: inline-block; clear: both"></li> --- this will start on a new line
<li style="float: left; display: inline-block"></li>
<li style="float: left; display: inline-block"></li>

17
Bạn nên chú ý rằng floatcài đặt sẽ ghi đè inline-blockcài đặt. Họ không thực sự cùng tồn tại với nhau
Itay

4
nếu bạn sử dụng text-aling: centre; nó sẽ không hoạt động (nổi phá vỡ nó)
Павел Иванов

3

Tôi biết bạn không muốn sử dụng phao và câu hỏi chỉ là lý thuyết nhưng trong trường hợp bất cứ ai thấy điều này hữu ích, đây là một giải pháp sử dụng phao.

Thêm một lớp bên trái cho các liyếu tố của bạn mà bạn muốn nổi:

<li class="left"><img src="http://phrogz.net/tmp/alphaball.png">Smells Good</li>

và sửa đổi CSS của bạn như sau:

li { text-align:center; float: left; clear: left; padding:0.1em 1em }
.left {float: left; clear: none;}

http://jsfiddle.net/chut319/xJ3pe/

Bạn không cần chỉ định chiều rộng hoặc khối nội tuyến và hoạt động xa như IE6.


1

Tôi đã thực hiện điều này bằng cách tạo một :: trước bộ chọn cho phần tử nội tuyến đầu tiên trong hàng và làm cho bộ chọn đó thành một khối có lề trên hoặc dưới để tách các hàng một chút.

.1st_item::before
{
  content:"";
  display:block;
  margin-top: 5px;
}

.1st_item
{
  color:orange;
  font-weight: bold;
  margin-right: 1em;
}

.2nd_item
{
  color: blue;
}

-1

Lưu ý rằng điều này sẽ hoạt động, tùy thuộc vào cách bạn kết xuất trang. Nhưng làm thế nào về việc chỉ bắt đầu một danh sách không có thứ tự mới?

I E

<ul>
<li>
<li>
<li>
</ul>
<!-- start a new ul to line break it -->
<ul>


-2

Một giải pháp tốt hơn là sử dụng -webkit-cột: 2;

http://jsfiddle.net/YMN7U/889/

 ul { margin:0.5em auto;
-webkit-columns:2;
}

Đối với một số trường hợp sử dụng, đây có thể là một giải pháp hợp lý. Nó không phải là một giải pháp tốt trong trường hợp này, bởi vì nó hoàn toàn sắp xếp lại nội dung để đi xuống thay vì xuyên suốt thay vì xuyên suốt.
Phrogz 20/07/2015

5
Ai sẽ muốn tạo một ứng dụng web chỉ hoạt động trong một vài trình duyệt?
dùng2867288

-3

Có lẽ điều đó là hoàn toàn có thể chỉ với CSS nhưng tôi thích tránh "nổi" hết mức có thể vì nó cản trở chiều cao của cha mẹ.

Nếu bạn đang sử dụng jQuery, bạn có thể tạo một plugin `quấnN` đơn giản tương tự như` quấn ALL` ngoại trừ nó chỉ bao bọc các phần tử" N ", sau đó ngắt và bọc các phần tử" N "tiếp theo bằng một vòng lặp. Sau đó, đặt lớp bao bọc của bạn thành `display: block;`.

(function ($) {
    $.fn.wrapN = function (wrapper, n, start) {
        if (wrapper === undefined || n === undefined) return false;
        if (start === undefined) start = 0;
        for (var i = start; i < $(this).size(); i += n)
           $(this).slice(i, i + n).wrapAll(wrapper);
        return this;
    };
}(jQuery));

$(document).ready(function () {
    $("li").wrapN("<span class='break' />", 3);
});

Đây là một JSFiddle của sản phẩm đã hoàn thành:

http://jsfiddle.net/dustinpoissant/L79ahLoz/

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.