CSS zum Zeilenumbruch vor / nach einem bestimmten "Inline-Block" -Element

202

Angenommen, ich habe diesen HTML-Code:

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

und dieses CSS:

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

Das Ergebnis ist hier zu sehen: http://jsfiddle.net/YMN7U/1/

Stellen Sie sich nun vor, ich möchte dies in drei Spalten aufteilen, was einer Injektion <br>nach der dritten entspricht <li>. (Eigentlich wäre das semantisch und syntaktisch ungültig.)

Ich weiß, wie man den dritten <li>in CSS auswählt , aber wie erzwinge ich einen Zeilenumbruch danach? Das funktioniert nicht:

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

Ich weiß auch, dass dieser spezielle Fall durch Verwenden von floatanstelle von möglich ist inline-block, aber ich bin nicht an Lösungen interessiert, die verwendenfloat . Ich weiß auch, dass dies bei Blöcken mit fester Breite möglich ist, indem die Breite des übergeordneten Elements ulauf etwa das Dreifache dieser Breite eingestellt wird. Diese Lösung interessiert mich nicht. Ich weiß auch, dass ich verwenden könnte, display:table-cellwenn ich echte Spalten wollte; Diese Lösung interessiert mich nicht. Ich bin an der Möglichkeit interessiert, eine Pause in Inline-Inhalten zu erzwingen.

Bearbeiten : Um klar zu sein, ich interessiere mich für "Theorie", nicht die Lösung für ein bestimmtes Problem. Kann CSS einen Zeilenumbruch in die Mitte von display:inline(-block)?Elementen einfügen oder ist dies unmöglich? Wenn Sie sicher sind, dass dies unmöglich ist, ist dies eine akzeptable Antwort.

Phrogz
quelle
2
Die ersten drei und die zweiten drei in zwei verschiedene Listen setzen? Ich gehe davon aus, dass Sie das nicht wollen, aber ich dachte, ich würde es da
rauswerfen
Sie müssen uns anscheinend mitteilen, was Sie hier wirklich erreichen möchten, damit jemand die beste Methode empfehlen kann. Es gibt alle Optionen, die Sie ausgeschlossen haben, um das Problem zu lösen. Warum ist eine andere Lösung erforderlich?
Jake
4
@Jake Ich habe tatsächlich genau das getan, was ich gesagt habe: eine semantische Liste von Elementen verwenden und nach bestimmten umbrechen wollen. In der Praxis habe ich die Breite des Containers festgelegt, dies funktioniert jedoch nur in meinem speziellen Fall, da die Elemente zufällig dieselbe Breite haben und ich wollte, dass sie an einer einheitlichen Kante gewickelt werden. Dies ist möglicherweise nicht immer der Fall. Was ich "wirklich zu erreichen versuche", ist zu erfahren, ob CSS einen Zeilenumbruch mitten im Inline-Fluss erzwingen kann oder nicht. Die zuversichtliche Antwort "Dies ist definitiv nicht möglich" ist akzeptabel (falls richtig).
Phrogz

Antworten:

302

Ich konnte es für Inline-LI-Elemente verwenden. Leider funktioniert es nicht, wenn die LI-Elemente Inline-Block sind:

Live-Demo: http://jsfiddle.net/dWkdp/

Oder die Cliff Notes-Version:

li { 
     display: inline; 
}
li:nth-child(3):after { 
     content: "\A";
     white-space: pre; 
}
Šime Vidas
quelle
2
Sime, warum wird das "\ A" nicht ausgedruckt? Alles, was ich mit dem :afterimmer versucht habe, wird als gerader Text gedruckt.
JakeParis
12
@JMCCreative Das ist ASCII 0x0A, AKA ein LF-Zeichen (Zeilenvorschub). Siehe w3.org/TR/CSS2/syndata.html#strings
Phrogz
5
@JMC \Aist der Zeilenvorschubcharakter ... es ist eine Flucht
Šime Vidas
3
@JMC Offizielle Spezifikation: w3.org/TR/CSS21/syndata.html#strings Sitepoint: reference.sitepoint.com/css/content
Šime Vidas
18
Hier kommentieren, da ich alle paar Monate auf diese Frage zurückkomme ... Es funktioniert nicht bei Inline-Blöcken, da Sie Zeilenumbrüche in etwas hinzufügen, das sich wie ein Blockcontainer in einem Inline-Kontext verhält. Wenn Sie aus dem Kontext ausbrechen könnten, indem Sie den Zeilenumbruch zwischen den <li> einfügen, würde dies funktionieren. Schade eigentlich, denn dies ist nützlich für reaktionsschnelle Design-Haltepunkte. Ich denke, die meiste Zeit ist "Inline" genauso nützlich wie Inline-Block für Listen
user1010892
21

Sie interessieren sich nicht für viele "Lösungen" für Ihr Problem. Ich glaube nicht, dass es wirklich einen guten Weg gibt, das zu tun, was Sie tun möchten. Alles, was Sie mit :afterund einfügencontent hat genau die gleiche syntaktische und semantische Gültigkeit, die es getan hätte, wenn Sie es gerade selbst dort geschrieben hätten.

Die Tools CSS bieten Arbeit. Sie sollten einfach das lis schweben lassen und dann, clear: leftwenn Sie eine neue Zeile beginnen möchten, wie Sie erwähnt haben:

Siehe ein Beispiel: http://jsfiddle.net/marcuswhybrow/YMN7U/5/

Marcus Whybrow
quelle
18
Das OP ist nicht an Ihrer Lösung interessiert :)
Šime Vidas
2
Nun, nichts, was Sie mit verwenden :afterkönnen, ist syntaktisch gültig oder eine gute Idee, da bereits Tools vorhanden sind, um dies zu tun. Daher die Antwort.
Marcus Whybrow
32
Ein Grund, keine Floats zu verwenden, ist, dass es keine gibt float: center.
Augenlidlosigkeit
7
plus Inline-Block ermöglicht alle Arten von vertikaler Ausrichtung, die nicht
schweben
20
"Alles, was Sie mit: after und content einfügen, hat genau die gleiche syntaktische und semantische Gültigkeit" - kommt zu spät zur Party, aber ich bin damit nicht einverstanden - der springende Punkt bei der Verwendung von: before und: after ist, in der Lage zu sein, das Styling einzufügen stört nicht die semantische Bedeutung des HTML.
Rupert
4

Wenn das Umschreiben des HTML-Codes zulässig ist, können Sie <ul>s innerhalb von verschachteln <ul>und das innere <li>s einfach als Inline-Block anzeigen lassen . Dies wäre meiner Meinung nach auch semantisch sinnvoll, da sich die Gruppierung auch im HTML widerspiegelt.


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

Demo

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

fabb
quelle
3

Eine einfache Möglichkeit, Listen in Zeilen aufzuteilen, besteht darin, die einzelnen Listenelemente zu verschieben und dann das Element, das Sie in die nächste Zeile verschieben möchten, zu löschen.

beispielsweise

<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>
matt
quelle
17
Sie sollten beachten, dass die floatEinstellung die Einstellung überschreibt inline-block. Sie koexistieren nicht wirklich zusammen
Itay
4
Wenn Sie Text-Aling verwenden: center; es wird nicht funktionieren (Floating bricht es)
Павел Иванов
3

Ich weiß, dass Sie keine Floats verwenden wollten und die Frage war nur Theorie, aber falls jemand dies nützlich findet, ist hier eine Lösung mit Floats.

Fügen liSie Ihren Elementen, die Sie schweben möchten, eine Klasse von Links hinzu :

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

und ändern Sie Ihr CSS wie folgt:

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

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

Sie müssen keine Breiten oder Inline-Blöcke angeben und arbeiten bereits im IE6.

chut319
quelle
1

Ich habe dies erreicht, indem ich einen :: before-Selektor für das erste Inline-Element in der Zeile erstellt und diesen Selektor zu einem Block mit einem oberen oder unteren Rand gemacht habe, um die Zeilen ein wenig zu trennen.

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

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

.2nd_item
{
  color: blue;
}
Deji
quelle
-1

Beachten Sie, dass dies funktioniert, je nachdem, wie Sie die Seite rendern. Aber wie wäre es einfach mit dem Starten einer neuen ungeordneten Liste?

dh

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

Phil LaNasa
quelle
-2

Eine bessere Lösung ist die Verwendung von -webkit-Spalten: 2;

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

 ul { margin:0.5em auto;
-webkit-columns:2;
}
Vivekraj KR
quelle
In einigen Anwendungsfällen kann dies eine vernünftige Lösung sein. In diesem Fall ist dies keine gute Lösung, da der Inhalt vollständig neu angeordnet wird, damit er nach unten und nicht nach unten und nicht nach unten geht.
Phrogz
5
Wer möchte eine Webanwendung erstellen, die nur in wenigen Browsern funktioniert?
user2867288
-3

Vielleicht ist es nur mit CSS völlig möglich, aber ich ziehe es vor, "float" so weit wie möglich zu vermeiden, weil es die Größe der Eltern beeinträchtigt.

Wenn Sie jQuery verwenden, können Sie ein einfaches "wrapN" -Plugin erstellen, das "wrapAll" ähnelt, außer dass es nur "N" -Elemente umschließt und dann die nächsten "N" -Elemente mit einer Schleife bricht und umschließt. Setzen Sie dann Ihre Wrapper-Klasse auf `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);
});

Hier ist eine JSFiddle des fertigen Produkts:

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

Dustin Poissant
quelle