Fügen Sie nach Elementen in einer ungeordneten Liste ein Rohrtrennzeichen hinzu, es sei denn, dieses Element ist das letzte in einer Zeile

76

Ist es möglich, dieses HTML zu stylen ...

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

... so was ...

Geben Sie hier die Bildbeschreibung ein

... ohne Klassen zu bestimmten Listenelementen hinzuzufügen oder auf Javascript zurückzugreifen? Und wenn ja wie?

Die Zeilenumbrüche sind nicht festgelegt. Die Liste wird erweitert, um zusätzlichen Platz zu beanspruchen, und Listenelemente werden mittig ausgerichtet.

twsaef
quelle
1
mögliches Duplikat von Separatoren für die Navigation
d4nyll
1
@danyll Diese Frage beinhaltet mehrzeilige Listen, diese Frage nicht und hat eine Lösung.
Twsaef

Antworten:

65

Dies ist jetzt mit möglich flex-box

Die Schlüssel zu dieser Technik:

  • Ein Containerelement, das auf gesetzt ist overflow: hidden.
  • Setzen Sie justify-content: space-betweenauf die ul(die eine Flex-Box ist), um die Flex-Elemente zu zwingen, sich zum linken und rechten Rand zu dehnen.
  • Stellen Sie margin-left: -1pxauf, damit der ullinke Rand den Behälter überläuft.
  • Setze border-left: 1pxauf die liFlex-Items.

Der Container fungiert als Maske, die die Ränder von Flex-Elementen verbirgt, die den linken Rand berühren.

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

Gfullam
quelle
34
Und Sie haben nur drei Jahre gebraucht, um die Antwort zu bekommen. Jetzt können Sie das Projekt beenden! Besser spät als nie. ;)
Gfullam
2
Das war großartig. Ich brauchte stattdessen einen Aufzählungszeichen-Teiler und konnte ihn mit dieser Methode und einigen Optimierungen erhalten. Dies kann für jeden Effekt verwendet werden, den Sie mit CSS gestalten können: - Positionieren Sie den LI relativ - fügen Sie das Aufzählungszeichen mit: after und der content-Eigenschaft hinzu - positionieren Sie das: after unbedingt - passen Sie die linke Eigenschaft auf dem: after auf die halbe Breite an Inhalt - passen Sie den negativen Rand auf der UL an, um die Kugel zu verbergen - passen Sie den rechten Rand an, um den Abstand zu fixieren
Blorf
Diese Lösung ist gut, aber die Links in der letzten Zeile scheinen gedehnt zu sein. Ist es möglich, sie zu reparieren?
Naveen Kumar PG
@NaveenKumarPG Das eingebettete Beispiel enthält keine Links. Das Hinzufügen von Ankertags zum Erstellen eines Links in jedem Listenelement führt nicht zu einer Dehnung, die ich erkennen kann. Ich bin mir nicht sicher, worauf Sie sich beziehen.
Gfullam
1
Ich hatte das gleiche Problem wie @nilon bei der Verwendung von Bootstrap. ul, li { padding: 0; }
Am
99

Gerade

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

Dies löst natürlich nicht das Problem des OP. Er möchte die vertikalen Balken am Anfang und Ende der Zeilen entfernen, je nachdem, wo sie unterbrochen sind. Ich werde mich auf die Probe stellen und behaupten, dass dieses Problem mit CSS und nicht einmal mit JS nicht lösbar ist, es sei denn, man möchte die Textmess- / Layout- / Zeilenumbruchlogik der Browser-Engine im Wesentlichen neu schreiben.

Die einzigen Teile von CSS, die, soweit ich sehen kann, über Zeilenumbrüche "Bescheid wissen", sind zunächst das ::first-linePseudoelement, das uns hier nicht hilft - auf jeden Fall ist es auf einige Präsentationsattribute beschränkt, und funktioniert nicht zusammen mit Dingen wie :: vorher und :: nachher. Der einzige andere Aspekt von CSS, an den ich denken kann, der bis zu einem gewissen Grad Zeilenumbrüche aufdeckt, ist die Silbentrennung. Beim Silbentrennen geht es jedoch darum , in bestimmten Situationen ein Zeichen (normalerweise einen Bindestrich) am Zeilenende hinzuzufügen , während es hier darum geht , ein Zeichen (die vertikale Linie) zu entfernen , sodass ich einfach nicht sehen kann, wie man irgendeine Art anwendet der Silbentrennungslogik, auch mit Hilfe von Eigenschaften wie hyphenate-character.

Wir haben die word-spacingEigenschaft, die innerhalb einer Zeile angewendet wird, aber nicht an Zeilenanfängen und -enden, was vielversprechend erscheint, aber die Breite des Raums zwischen Wörtern definiert, nicht die zu verwendenden Zeichen.

Man fragt sich, ob es eine Möglichkeit gibt, die text-overflowEigenschaft zu verwenden, die die wenig bekannte Fähigkeit hat, zwei Werte für die Anzeige von Überlauftext sowohl links als auch rechts zu verwenden, wie in

text-overflow: '' '';

aber es scheint immer noch keinen offensichtlichen Weg zu geben, hier von A nach B zu gelangen.


quelle
Ja, ich bin mir ziemlich sicher, dass dies die richtige Antwort ist, bis CSS erweitert wird, um Zeilenumbrüche zu erkennen.
Twsaef
28

Bevor Sie den Code anzeigen, sollten Sie erwähnen, dass IE8 dies unterstützt, :first-childjedoch nicht :last-child. In ähnlichen Situationen sollten Sie die :first-childPseudoklasse verwenden.

Demo

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

Nabil Kadimi
quelle
15

Verwenden Sie den :afterPseudo-Selektor. Schauen Sie 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; }

BEARBEITEN:

jQuery-Lösung:

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

Schauen Sie hier. Ich habe auch noch ein paar Tiere hinzugefügt. http://jsfiddle.net/A52T8/10/

elclanrs
quelle
2
Dies wird das Problem des nachlaufenden Rohrs bei Leitungsbrüchen jedoch nicht lösen - jsfiddle.net/A52T8/3
twsaef
@Dan so funktioniert im Grunde die Antwort von Kinakuta, aber umgekehrt, und sie ist aus demselben Grund fehlerhaft.
Twsaef
Da ich auch neugierig war, habe ich eine Lösung für Sie entwickelt und meine ursprüngliche Antwort bearbeitet. Es klappt.
Elclanrs
Hoppla, ich habe vergessen, die divBreite hinzuzufügen . Fest. Keine Abstimmung erforderlich. lol mein schlechtes jsfiddle.net/A52T8/9
elclanrs
1
Nun, das ist die einzige Antwort mit der richtigen Ausgabe, aber leider erfordert es Javascript.
Twsaef
3

Ich weiß, dass ich etwas spät zur Party komme, aber wenn Sie es ertragen können, die Zeilen linksbündig zu haben, besteht ein Hack darin, die Pfeifen vor die Gegenstände zu stellen und dann eine Maske über den linken Rand zu legen, im Grunde wie folgt:

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

ul, li {
  display: inline;
}

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

vollständigeres Beispiel: http://jsbin.com/hoyaduxi/1/edit

user2020056
quelle
2

Eine Lösung besteht darin, den linken Rand wie folgt zu gestalten:

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

Dies führt jedoch möglicherweise nicht zu den gewünschten Ergebnissen, wenn die gesamte Liste wie in Ihrem Beispiel umbrochen wird. Dh es würde so etwas geben wie:

foo | bar | baz
 | bob | bill
 | judy
greim
quelle
Ja, das ist genau das Problem. Gibt es dafür keine Lösung?
Twsaef
1
Ich denke, Sie werden eine js-Lösung brauchen
elclanrs
1

Ich bin heute auf eine Lösung gestoßen, die noch nicht hier zu sein scheint und die bisher recht gut zu funktionieren scheint. Die akzeptierte Antwort funktioniert nicht wie sie ist auf IE10, aber diese funktioniert. http://codepen.io/vithun/pen/yDsjf/ Gutschrift an den Autor natürlich!

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

brahnp
quelle
Interessant. Wie funktioniert es und ist es von Änderungen der übergeordneten Schriftgröße betroffen? Auch diese Lösung
zentriert
Oh du hast recht, es funktioniert nur wenn links ausgerichtet! Mir ist das nicht in den Sinn gekommen, denn genau danach habe ich in meinem speziellen Fall gesucht.
Brahnp
0

Leicht modifizierte SCSS-Version, mit der Sie die Rohrgröße steuern |und das Auffüllen der ersten und letzten Listenelemente unter Berücksichtigung der Ränder vermeiden können.


$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>
User_coder
quelle
-1

Ja, Sie müssen Pseudoelemente UND Pseudoselektoren verwenden: http://jsfiddle.net/cYky9/

Kinakuta
quelle
Fast. Das entfernt das Ende von Liste eins, aber nicht das Ende von Zeile eins - jsfiddle.net/cYky9/4
twsaef
1
ah, wusste nicht, dass dies eine Anforderung war - ich kann mir nicht vorstellen, wie dies ohne Logik möglich ist, und das bedeutet Server oder js.
Kinakuta
-1

Sie können das folgende CSS zum Lösen verwenden.

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

Sollte auch auf IE8 + funktionieren.

Bijoy Anupam
quelle
Die Balken werden jedoch nicht vor jeder Zeile entfernt, sondern nur in der ersten Zeile.
Acme