web-dev-qa-db-fra.com

CSS pour les sauts de ligne avant / après un élément `inline-block` particulier

Disons que j'ai ce code 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>

et ce CSS:

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

Le résultat peut être vu ici: http://jsfiddle.net/YMN7U/1/

Maintenant, imaginez que je veuille diviser cela en trois colonnes, l’équivalent d’injecter un <br> après le troisième <li>. (En fait, ce serait sémantiquement et syntaxiquement invalide.)

Je sais comment sélectionner le troisième <li> en CSS, mais comment puis-je forcer un saut de ligne après celui-ci? Cela ne fonctionne pas:

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

Je sais aussi que ce cas particulier est possible en utilisant float au lieu de inline-block, mais les solutions utilisant float ne m'intéressent pas. Je sais aussi que, avec des blocs de largeur fixe, cela est possible en définissant la largeur du parent ul sur environ 3x cette largeur; Je ne suis pas intéressé par cette solution. Je sais aussi que je pourrais utiliser display:table-cell si je voulais de vraies colonnes; Je ne suis pas intéressé par cette solution. Je suis intéressé par la possibilité de forcer une pause dans le contenu en ligne.

Edit : Pour être clair, je m'intéresse à la "théorie", pas à la solution à un problème particulier. CSS peut-il injecter un saut de ligne au milieu de display:inline(-block)? éléments, ou est-ce impossible? Si vous êtes certain que cela est impossible, la réponse est acceptable.

198
Phrogz

J'ai pu le faire fonctionner sur des éléments LI intégrés. Malheureusement, cela ne fonctionne pas si les éléments LI sont inline-block:

Démonstration en direct: http://jsfiddle.net/dWkdp/

Ou la version notes de falaise:

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

Vous n'êtes pas intéressé par beaucoup de "solutions" à votre problème. Je ne pense pas qu'il y ait vraiment un bon moyen de faire ce que vous voulez faire. Tout ce que vous insérez avec :after et content a exactement la même validité syntaxique et sémantique que si vous veniez de l'écrire vous-même.

Les outils CSS fournissent du travail. Vous devriez juste laisser flotter les lis puis clear: left lorsque vous voulez commencer une nouvelle ligne, comme vous l'avez mentionné:

Voir un exemple: http://jsfiddle.net/marcuswhybrow/YMN7U/5/

21
Marcus Whybrow

Lorsque la réécriture du code HTML est autorisée, vous pouvez imbriquer <ul>s dans le <ul> et laisser simplement le <li>s intérieur s'afficher sous la forme d'un bloc en ligne. Cela aurait également un sens sémantiquement logique à mon humble avis, étant donné que le regroupement est également reflété dans le code 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; }

Démo

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

Un moyen simple de scinder les listes en lignes consiste à faire flotter les éléments individuels de la liste, puis l'élément que vous souhaitez accéder à la ligne suivante permet d'effacer le flottant.

par exemple

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

Je sais que vous ne vouliez pas utiliser de flotteurs et que la question n'était que théorique, mais si quelqu'un trouve cela utile, voici une solution utilisant des flotteurs.

Ajoutez une classe de left à vos éléments li que vous souhaitez faire flotter:

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

et modifiez votre CSS comme suit:

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

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

Vous n'avez pas besoin de spécifier des largeurs ni des blocs en ligne et fonctionne aussi loin que IE6.

3
chut319

Pour ce faire, j'ai créé un sélecteur :: before pour le premier élément en ligne de la ligne et fait de ce sélecteur un bloc avec une marge supérieure ou inférieure pour séparer un peu les lignes.

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

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

.2nd_item
{
  color: blue;
}
1
Deji