207 votes

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

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

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

Je sais comment sélectionner le troisième <li> en CSS, mais comment faire pour imposer 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 je ne suis pas intéressé par les solutions utilisant float . Je sais également qu'avec les blocs à largeur fixe, cela est possible en définissant la largeur du parent. ul à environ 3x cette largeur ; cette solution ne m'intéresse pas. Je sais également que je pourrais utiliser display:table-cell si je voulais de vraies colonnes ; cette solution ne m'intéresse pas. Je suis intéressé par la possibilité de forcer une rupture à l'intérieur du contenu en ligne.

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

2 votes

Mettre les trois premiers et les trois seconds dans deux listes différentes ? Je suppose que vous ne voulez pas faire ça, mais j'ai pensé que je devais le faire.

0 votes

Il semble que vous deviez nous dire ce que vous essayez réellement d'obtenir afin que quelqu'un puisse vous recommander la meilleure méthode. Toutes les options que vous avez exclues existent pour résoudre le problème que vous avez, pourquoi une autre solution est-elle nécessaire ?

5 votes

@Jake Je faisais en fait exactement ce que j'ai dit : j'utilisais une liste sémantique d'éléments et je voulais que les éléments soient placés après certains d'entre eux. En pratique, j'ai défini la largeur du conteneur, mais cela ne fonctionne que dans mon cas particulier, car les éléments étaient de la même largeur et je voulais qu'ils s'enroulent sur un bord cohérent. Ce n'est peut-être pas toujours le cas. Ce que je fais "essayant vraiment d'atteindre" est d'apprendre si CSS peut ou non forcer un saut de ligne au milieu d'un flux en ligne. La réponse assurée "Ce n'est certainement pas possible" est acceptable (si elle est correcte).

304voto

Šime Vidas Points 59994

J'ai réussi à le faire fonctionner sur des éléments LI en ligne. Malheureusement, cela ne fonctionne pas si les éléments LI sont inline-block :

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

Ou la version courte :

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

2 votes

Sime, pourquoi le " \A "ne s'imprime pas ? Tout ce que j'ai essayé avec l'option :after s'imprime toujours sous forme de texte brut.

12 votes

@JMCCreative C'est ASCII 0x0A, alias un caractère LF (line feed). Voir w3.org/TR/CSS2/syndata.html#strings

5 votes

@JMC \A est le caractère de saut de ligne... c'est un échappement.

20voto

Marcus Whybrow Points 8427

Vous n'êtes pas intéressé par un grand nombre de "solutions" à votre problème. Je ne pense pas qu'il y ait vraiment une bonne façon de faire ce que vous voulez faire. Tout ce que vous insérez en utilisant :after y content a exactement la même validité syntaxique et sémantique que si vous l'aviez écrit vous-même.

Les outils fournis par le CSS fonctionnent. Vous devriez simplement faire flotter le li et ensuite clear: left lorsque vous voulez commencer une nouvelle ligne, comme vous l'avez mentionné :

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

18 votes

Le PO n'est pas intéressé par votre solution :)

2 votes

Il n'y a rien que vous puissiez faire en utilisant :after sera syntaxiquement valide ou une bonne idée, puisqu'il existe déjà des outils pour le faire. D'où la réponse.

0 votes

Il a dit "pas de flotteurs" même si la réponse de @Marcus est probablement la meilleure solution. La propriété "float" est vraiment malmenée par ici, n'est-ce pas ?

4voto

fabb Points 3471

Lorsque la réécriture du html est autorisée, vous pouvez imbriquer <ul> au sein de la <ul> et laisser l'intérieur <li> s s'affichent comme inline-block. Cela aurait également un sens sur le plan sémantique, puisque 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>

3voto

matt Points 57

Une façon simple de diviser des listes en lignes est de faire flotter les éléments individuels de la liste, puis d'effacer le flottement de l'élément que vous voulez faire passer à la ligne suivante.

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>

17 votes

Vous devriez remarquer que le float remplace le paramètre inline-block réglage. Ils ne coexistent pas vraiment ensemble

4 votes

Si vous utilisez text-aling : center ; cela ne fonctionnera pas (le flottement le casse)

3voto

chut319 Points 30

Je sais que vous ne souhaitiez pas utiliser de flottants et que la question n'était que théorique, mais au cas où quelqu'un trouverait cela utile, voici une solution utilisant des flottants.

Ajoutez une classe de gauche à votre li les éléments que vous voulez 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 les largeurs ou les blocs inline et il fonctionne dès IE6.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X