Додайте роздільник труби після елементів у невпорядкованому списку, якщо цей елемент не є останнім у рядку


79

Чи можна стилізувати цей html ...

<ul>
    <li>Dogs</li>
    <li>Cats</li>
    <li>Lions</li>
    <li>Tigers</li>
    <li>Zebras</li>
    <li>Giraffes</li>
    <li>Bears</li>
    <li>Hippopotamuses</li>
    <li>Antelopes</li>
    <li>Unicorns</li>
    <li>Seagulls</li>
</ul>

... подобається це ...

введіть тут опис зображення

... без додавання класів до певних елементів списку чи використання JavaScript? А якщо так, то як?

Розриви рядків не фіксовані; список розширюється, щоб зайняти додатковий простір, а елементи списку вирівнюються по центру.


1
можливий дублікат
розділювачів

1
@danyll Це питання включає багаторядкові списки, це питання не має і має рішення.
twsaef

Відповіді:


66

Це тепер можливо за допомогою flex-box

Ключі до цієї техніки:

  • Елемент контейнера, встановлений у overflow: hidden.
  • Встановіть justify-content: space-betweenна ul(що є гнучкою коробкою), щоб змусити його гнучкі елементи розтягуватися до лівого та правого країв.
  • Встановіть margin-left: -1pxна, ulщоб його лівий край переповнював контейнер.
  • Встановіть border-left: 1pxна liгнучкі елементи.

Контейнер виконує функцію маски, що приховує межі будь-яких гнучких предметів, що торкаються його лівого краю.

.flex-list {
    position: relative;
    margin: 1em;
    overflow: hidden;
}
.flex-list ul {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: space-between;
    margin-left: -1px;
}
.flex-list li {
    flex-grow: 1;
    flex-basis: auto;
    margin: .25em 0;
    padding: 0 1em;
    text-align: center;
    border-left: 1px solid #ccc;
    background-color: #fff;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css" rel="stylesheet"/>
<div class="flex-list">
    <ul>
        <li>Dogs</li>
        <li>Cats</li>
        <li>Lions</li>
        <li>Tigers</li>
        <li>Zebras</li>
        <li>Giraffes</li>
        <li>Bears</li>
        <li>Hippopotamuses</li>
        <li>Antelopes</li>
        <li>Unicorns</li>
        <li>Seagulls</li>
    </ul>
</div>


35
І вам знадобилося лише три роки, щоб отримати відповідь. Тепер ви можете закінчити цей проект! Краще пізно, ніж ніколи. ;)
gfullam

2
Це було чудово. Натомість мені знадобився розділювач символів маркера, і я зміг отримати його за допомогою цього методу та декількох налаштувань. Це може бути використано для будь-якого ефекту, який ви можете стилізувати за допомогою CSS: - відносно розташуйте LI - додайте маркер, використовуючи: after і властивість content - абсолютно розташуйте: after - відрегулюйте властивість left на: after до половини ширини його вміст - відрегулюйте від’ємне поле на UL, щоб приховати маркер - відрегулюйте правий бічний край, щоб виправити інтервал
Blorf

це рішення добре, але посилання в останньому рядку, здається, розтягнуті, чи можна це виправити?
Naveen Kumar PG

@NaveenKumarPG У вбудованому прикладі немає посилань; і додавання прив'язних тегів для створення посилання всередині кожного елемента списку не призводить до розтягування, про що я можу сказати. Я не впевнений, на що ви маєте на увазі.
gfullam

1
У мене була та ж проблема, що і @nilon при використанні Bootstrap. У підсумку я розібрав скидання CSS, поки не знайшов винуватця, і ось що спричинило для мене таке: ul, li { padding: 0; }
LinkXXI

100

Просто

li + li::before {
    content: " | ";
}

Звичайно, це насправді не вирішує проблему ОП. Він хоче вилучити вертикальні смуги на початку та в кінці рядків залежно від того, де вони розбиті. Я вийду на кінцівку і стверджую, що ця проблема не розв'язується за допомогою CSS, і навіть не з JS, якщо хтось не хоче по суті переписати логіку вимірювання тексту / макета / розбиття рядків в браузері.

Єдиними шматочками CSS, наскільки я бачу, що "знають" про розрив рядків, по-перше, ::first-lineпсевдоелемент, який нам тут не допомагає - у будь-якому випадку, він обмежений кількома презентаційними атрибутами, і не працює разом із такими речами, як :: before та :: after. Єдиний інший аспект CSS, про який я думаю, який певною мірою виявляє розрив рядків - це перенос. Однак дефіс полягає у додаванні символу (зазвичай тире) до кінця рядків у певних ситуаціях, тоді як тут ми стурбовані видаленням символу (вертикальної лінії), тому я просто не можу зрозуміти, як застосувати будь-який вид логіки, пов’язаної з переносом, навіть за допомогою властивостей, таких як hyphenate-character.

Ми маємо word-spacingвластивість, яка застосовується всередині рядка, але не на початку та закінченні рядка, що здається перспективним, але воно визначає ширину простору між словами, а не символ (и), який буде використано.

Хтось задається питанням, чи є якийсь спосіб використовувати text-overflow властивості, яка має маловідому здатність приймати два значення для відображення тексту переповнення як ліворуч, так і праворуч, як у

text-overflow: '' '';

але, здається, тут ще немає жодного очевидного способу дістатися від А до В.


Так, я впевнений, що це правильна відповідь, доки CSS не буде розширений, щоб знати про розриви рядків.
twsaef

29

Перш ніж показувати код, варто згадати, що IE8 підтримує :first-child але ні :last-child, тому в подібних ситуаціях слід використовувати:first-child псевдо-клас.

Демо

#menu{
    list-style: none;
}
#menu li{
    display: inline;
    padding: 0 10px;
    border-left: solid 1px black;
}
#menu li:first-child{
    border-left: none;
}
<ul id="menu">
    <li>Dogs</li>
    <li>Cats</li>
    <li>Lions</li>
    <li>More animals</li>
</ul>


15

Використовуйте :afterпсевдоселектор. Дивіться http://jsfiddle.net/A52T8/1/

<ul>
    <li>Dogs</li>
    <li>Cats</li>
    <li>Lions</li>
    <li>Tigers</li>
    <li>Zebras</li>
    <li>Giraffes</li>
    <li>Bears</li>
    <li>Hippopotamuses</li>
    <li>Antelopes</li>
    <li>Unicorns</li>
    <li>Seagulls</li>
</ul>

ul li { float: left; }
ul li:after { content: "|"; padding: 0 .5em; }

РЕДАГУВАТИ:

Рішення jQuery:

html:

<div>
    <ul id="animals">
        <li>Dogs</li>
        <li>Cats</li>
        <li>Lions</li>
        <li>Tigers</li>
        <li>Zebras</li>
        <li>Giraffes</li>
        <li>Bears</li>
        <li>Hippopotamuses</li>
        <li>Antelopes</li>
        <li>Unicorns</li>
        <li>Seagulls</li>
        <li>Monkey</li>
        <li>Hedgehog</li>
        <li>Chicken</li>
        <li>Rabbit</li>
        <li>Gorilla</li>
    </ul>
</div>

css:

div { width: 300px; }
ul li { float: left; border-right: 1px solid black; padding: 0 .5em; }
ul li:last-child { border: 0; }

jQuery

var maxWidth = 300, // Your div max-width
    totalWidth = 0;
$('#animals li').each(function(){
    var currentWidth = $(this).outerWidth(),
        nextWidth = $(this).next().outerWidth();
    totalWidth += currentWidth;
    if ( (totalWidth + nextWidth) > maxWidth ) {
        $(this).css('border', 'none');
        totalWidth = 0;
    }
});

Погляньте тут. Я також додав ще кілька тварин. http://jsfiddle.net/A52T8/10/


2
Це звичайно не вирішить проблему з кінцевою
twsaef

@Dan, це в основному, як працює відповідь кінакути, але навпаки, і вона має недоліки з тієї ж причини.
twsaef

Оскільки мені це також було цікаво, я створив для вас рішення, я відредагував свою оригінальну відповідь. Це працює.
elclanrs

На жаль, забув додати divширину. Виправлено. Не потрібно голосування проти. lol my bad jsfiddle.net/A52T8/9
elclanrs

1
Ну, це поки що єдина відповідь з правильним результатом, але, на жаль, для цього потрібен javascript.
twsaef

3

Я знаю, що я трохи запізнився на вечірку, але якщо ви можете змиритися з вирівнюванням ліворуч, один хак - поставити труби перед елементами, а потім нанести маску над лівим краєм, в основному так:

li::before {
  content: " | ";
  white-space: nowrap;
}

ul, li {
  display: inline;
}

.mask {
  width:4px;
  position: absolute;
  top:8px; //position as needed
}

більш повний приклад: http://jsbin.com/hoyaduxi/1/edit


2

Одним із варіантів є стиль лівої межі таким чином:

li { display: inline; }
li + li {
  border-left: 1px solid;
  margin-left:.5em;
  padding-left:.5em;
}

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

foo | bar | baz
 | bob | bill
 | judy

Так, саме в цьому проблема. Чи немає рішення для цього?
twsaef

1
Думаю, вам знадобиться якесь js-рішення
elclanrs

1

Сьогодні я натрапив на рішення, яке, здається, ще не було тут і яке, схоже, працює досі непогано. Прийнята відповідь не працює як є на IE10, але ця працює. http://codepen.io/vithun/pen/yDsjf/ автору звісно!

.pipe-separated-list-container {
  overflow-x: hidden;
}
.pipe-separated-list-container ul {
  list-style-type: none;
  position: relative;
  left: -1px;
  padding: 0;
}
.pipe-separated-list-container ul li {
  display: inline-block;
  line-height: 1;
  padding: 0 1em;
  margin-bottom: 1em;
  border-left: 1px solid;
}
<div class="pipe-separated-list-container">
  <ul>
    <li>One</li>
    <li>Two</li>
    <li>Three</li>
    <li>Four</li>
    <li>Five</li>
    <li>Six</li>
    <li>Seven</li>
    <li>Eight</li>
    <li>Nine</li>
    <li>Ten</li>
    <li>Eleven</li>
    <li>Twelve</li>
    <li>Thirteen</li>
    <li>Fourteen</li>
    <li>Fifteen</li>
    <li>Sixteen</li>
    <li>Seventeen</li>
    <li>Eighteen</li>
    <li>Nineteen</li>
    <li>Twenty</li>
    <li>Twenty One</li>
    <li>Twenty Two</li>
    <li>Twenty Three</li>
    <li>Twenty Four</li>
    <li>Twenty Five</li>
    <li>Twenty Six</li>
    <li>Twenty Seven</li>
    <li>Twenty Eight</li>
    <li>Twenty Nine</li>
    <li>Thirty</li>
  </ul>
</div>


Цікаво. Як це працює, і чи впливають на це зміни розміру батьківського шрифту? Крім того, це рішення не вирівнює елементи по центру :)
twsaef

О, ви праві, це працює лише тоді, коли вирівняно за лівим краєм! Мені це не спало на думку, оскільки це насправді було тим, чим я займався у моєму конкретному випадку.
brahnp

0

Трохи модифікована версія SCSS, яка дає вам можливість контролювати |розмір труби та усуває заповнення першого та останнього елементів списку, одночасно дотримуючись кордонів.


$pipe-list-height: 20px;
$pipe-list-padding: 15px;

.pipe-list {
    position: relative;
    overflow: hidden;
    height: $pipe-list-height;

    > ul {
        display: flex;
        flex-direction: row;

        > li {
            position: relative;
            padding: 0 $pipe-list-padding;

            &:after {
                content: " ";
                position: absolute;
                border-right: 1px solid gray;
                top: 10%;
                right: 0;
                height: 75%;
                margin-top: auto;
                margin-bottom: auto;
            }

            &:first-child {
                padding-left: 0;
            }

            &:last-child {
                padding-right: 0;

                &:after {
                    border-right: none;
                }
            }
        }
    }
}
<div class="pipe-list">
  <ul>
    <li>Link</li>
    <li>Link</li>
    <li>Link</li>
  </ul>
</div>

-1

Так, вам потрібно буде використовувати псевдоелементи І псевдоселектори: http://jsfiddle.net/cYky9/


Майже. Це видаляє кінець списку один, але не кінець рядка - jsfiddle.net/cYky9/4
twsaef

1
ах, не розумів, що це була вимога - я не можу подумати, як це можливо без певної логіки, а це означає сервер або js.
kinakuta

-1

Ви можете використовувати наступний CSS для вирішення.

ul li { float: left; }
ul li:before { content: "|"; padding: 0 .5em; }
ul li:first-child:before { content: ""; padding: 0; }

Повинна працювати і на IE8 +.


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