CSS для переривання рядків до / після конкретного елемента "вбудований блок"


202

Скажімо, у мене є цей HTML:

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

і цей CSS:

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

Результат можна побачити тут: http://jsfiddle.net/YMN7U/1/

Тепер уявіть, що я хочу розбити це на три стовпці, еквівалент введення а <br>після третього <li>. (Насправді це було б семантично і синтаксично недійсно.)

Я знаю, як вибрати третій <li>у CSS, але як змусити переривати рядок після нього? Це не працює:

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

Я також знаю, що цей конкретний випадок можливий за допомогою floatзамість inline-block, але мене не цікавлять рішення, що використовують float. Я також знаю, що з блоками фіксованої ширини це можливо, встановивши ширину на батьківському рівні ulприблизно в 3 рази більше цієї ширини; Мене це рішення не цікавить. Я також знаю, що я міг би використовувати, display:table-cellякби хотів справжні колонки; Мене це рішення не цікавить. Мене цікавить можливість примусити перерву у вбудованому вмісті.

Редагувати : Щоб зрозуміти, мене цікавить «теорія», а не рішення певної проблеми. Чи може CSS ввести рядок розриву посередині display:inline(-block)?елементів, або це неможливо? Якщо ви впевнені, що це неможливо, це прийнятна відповідь.


2
Поставте першу трійку та 2-ю трійку у два різні списки? Я припускаю, що ви цього не хочете робити, але я подумав, що "викину його туди".
JakeParis

Схоже, вам потрібно сказати нам, чого ви насправді намагаєтесь досягти, щоб хтось міг порекомендувати найкращий метод. Усі варіанти, які ви виключили, існують для вирішення проблеми, яка є, чому потрібне інше рішення?
Джейк

4
@Jake Я насправді робив саме те, що я заявив: використовуючи семантичний список елементів і хотів завершити конкретні. На практиці я встановлюю ширину контейнера, але це працює лише в моєму конкретному випадку, тому що елементи трапляються однакової ширини, і я хотів, щоб вони загорталися на однакові краї. Це може бути не завжди так. Те, що я насправді намагаюся досягти, - це дізнатися, чи може CSS примусити переривання лінії посеред потоку вбудованого потоку. Впевнена відповідь «Це точно не можливо» є прийнятною (якщо вона правильною).
Фрогз

Відповіді:


302

Мені вдалося змусити його працювати над вбудованими елементами LI. На жаль, це не працює, якщо елементи LI вбудовані в блок:

Демо-версія: http://jsfiddle.net/dWkdp/

Або версію нот на скелі:

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

2
Сим, чому "\ A" не друкується? Все, що я намагався, :afterзавжди друкує як прямий текст.
JakeParis

12
@JMCCreative Це ASCII 0x0A, AKA - символ LF (лінія каналу). Дивіться w3.org/TR/CSS2/syndata.html#strings
Phrogz

5
@JMC \A- персонаж каналу лінійки ... це втеча
Šime Vidas

3
@JMC Офіційні характеристики: w3.org/TR/CSS21/syndata.html#strings Sitepoint: reference.sitepoint.com/css/content
Šime Vidas

18
коментуючи тут, коли я продовжую повертатися до цього питання кожні кілька місяців ... Він не працюватиме на вбудованому блоці, оскільки ви додаєте розриви рядків у щось таке, що воно діє як контейнер блоків у вбудованому контексті. Якщо ви можете вийти з контексту, вставивши розрив рядка між <li> s, він би спрацював. Ганьба насправді, оскільки це корисно для чуйних точок дизайну. Я думаю, більшість часу "inline" так само корисна, як і вбудований блок для списків
user1010892

21

Вас не цікавить багато «рішень» вашої проблеми. Я не думаю, що дійсно є хороший спосіб зробити те, що ти хочеш робити. Все, що ви вставляєте, використовуючи :afterі contentмає абсолютно таку саму синтаксичну та семантичну дійсність, як це було б, якби ви щойно написали там.

Інструменти CSS забезпечують роботу. Вам слід просто пропустити lis, а потім, clear: leftколи ви хочете почати новий рядок, як ви вже згадували:

Дивіться приклад: http://jsfiddle.net/marcuswhybrow/YMN7U/5/


18
ОП не зацікавлений у вашому рішенні :)
Šime Vidas

2
Ну нічого, що ви можете зробити, скориставшись :afterсинтаксично чи дійсною ідеєю, оскільки для цього вже є інструменти. Звідси відповідь.
Marcus Whybrow

32
Однією з причин не використовувати поплавці є те, що не існує такого поняття як float: center.
безвічність

7
плюс вбудований блок дозволяє здійснювати всі види вертикального вирівнювання, яке плаває не може
user1010892

20
"Все, що ви вставляєте, використовуючи: after та вміст має абсолютно однакову синтаксичну та семантичну дійсність" - запізнюємось на вечірку, але я повністю не погоджуюся з цим - вся суть використання: до та: після - вміти вставляти стилі, які не заважає семантичному значенню Html.
Руперт

4

Коли переписування HTML дозволено, ви можете вкласти гніздо <ul>в межах <ul>і просто дозволити внутрішній <li>дисплей s як вбудований блок. Це також має семантичний сенс IMHO, оскільки групування також відображається в 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; }

Демо

$(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

Найпростіший спосіб розділити списки на рядки - це пропускання окремих елементів списку, а потім елемент, який ви хочете перейти до наступного рядка, ви можете очистити поплавок.

наприклад

<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
Ви повинні помітити, що floatналаштування перевершує inline-blockналаштування. Вони насправді не співіснують разом
Itay

4
якщо ви використовуєте aling text: aling: center; це не спрацює (плаваючий розбиває його)
Павел Иванов

3

Я знаю, що ви не хотіли використовувати поплавці, і питання полягало лише в теорії, але у випадку, якщо хтось вважає це корисним, ось рішення з використанням плавців.

Додайте клас ліворуч до liелементів, які ви хочете плавати:

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

і змініть свій CSS так:

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

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

Вам не потрібно вказувати ширину чи вбудовані блоки та працює так само, як IE6.


1

Я досяг цього, створивши селектор :: перед першим вбудованим елементом у рядку та зробивши цей селектор блоком з верхнім або нижнім полем, щоб трохи розділити рядки.

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

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

.2nd_item
{
  color: blue;
}

-1

Зверніть увагу, що це буде працювати, залежно від того, як ви візуалізуєте сторінку. Але як щодо того, щоб тільки почати новий не упорядкований список?

тобто

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


-2

Краще рішення - використовувати -webkit-колонки: 2;

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

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

У деяких випадках використання це може бути розумним рішенням. У цьому випадку це не дуже вдале рішення, оскільки він повністю переказує вміст переходити вниз-потім-поперек, а не через-потім-вниз.
Фрогз

5
Хто хоче зробити веб-додаток, який працює лише в кількох браузерах?
користувач2867288

-3

Можливо, це цілком можливо лише за допомогою CSS, але я вважаю за краще уникати "плавання" наскільки це можливо, тому що це заважає зростанню батьків.

Якщо ви використовуєте jQuery, ви можете створити простий плагін `wrapN`, схожий на` wrapAll`, за винятком того, що він обертає лише "N" елементи, а потім розбиває та загортає наступні елементи "N" за допомогою циклу. Потім встановіть клас обгортки на "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);
});

Ось JSFiddle готового продукту:

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.