J'ai récemment rencontré des problèmes de chevauchement de disposition avec un conteneur css float, et j'ai commencé à envisager d'utiliser display: inline-block à la place. Jusqu'ici, tout va bien ... sauf que j'ai besoin de pouvoir ajouter des sauts de ligne, comme clear le fait pour les flottants. Quelques exemples de texte ...

.ib {
  border: 1px solid #333;
  display: inline-block;
  padding: 3px;
}
.block-start {
  border: 1px solid #0cc;
  display: inline-block;
  padding: 3px;
}
<div class="container">
      <div class="block-start">block-start</div>
      <div class="ib">inline-block</div>
      <div class="ib">inline-block</div>
      <div class="ib">inline-block</div>
      <div class="ib">inline-block</div>
      <div class="block-start">block-start</div>
      <div class="ib">inline-block</div>
      <div class="ib">inline-block</div>
      <div class="ib">inline-block</div>
      <div class="ib">inline-block</div>
</div>

Est-il possible que mes éléments .block-start <div> commencent une nouvelle ligne?

MODIFIER : je dois mentionner que chaque élément .block-start doit être en ligne avec les autres blocs ib, comme un numéro de chapitre.

css
2
eb1 19 juin 2019 à 19:27

3 réponses

Meilleure réponse

Une idée hacky est d'ajouter une nouvelle ligne en utilisant un pseudo élément et de créer l'élément inline de sorte que le saut de ligne affecte les éléments inline-block. L'inconvénient est que vous ne pourrez pas styliser un élément inline comme vous le faites avec un élément inline-block

.ib {
  border: 1px solid #333;
  display: inline-block;
  padding: 3px;
}

.block-start {
  display: inline;
  padding: 3px;
  white-space: pre-wrap;
}
/* Create the break line */
.block-start:not(:first-child):before {
  content: "\A";
}

/* to rectify the position of the first one*/
.block-start:first-child {
  padding-left: 0;
}
<div class="container">
  <div class="block-start">block-start</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="block-start">block-start</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="block-start">block-start</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
</div>

Pour conserver le style (la bordure dans ce cas), nous pouvons envisager plus de hacks:

.ib {
  border: 1px solid #333;
  display: inline-block;
  padding: 3px;
}

.block-start {
  display: inline;
  padding: 3px 3px 4px;
  white-space: pre-wrap;
}
/* Create the break line */
.block-start:not(:first-child):before {
  content: "\A";
}

/* to rectify the position of the first one*/
.block-start:first-child {
  padding-left: 0;
  border:1px solid red;
}

.block-start:not(:first-child) {
  border:1px solid transparent;
  border-right-color:red; /*the right is not an issue*/
  background:
    linear-gradient(red,red) top    right   / calc(100% - 3px) 1px,
    linear-gradient(red,red) bottom right   / calc(100% - 3px) 1px,
    linear-gradient(red,red) left 4px top 0 / 1px 100%;
  background-repeat:no-repeat;  
  background-origin:border-box;
  padding-right:4px;  
}
<div class="container">
  <div class="block-start">block-start</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="block-start">block-start</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="block-start">block-start</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
</div>

Comme nous pouvons le voir, le padding-left est le problème ici car il est appliqué au pseudo élément créant le saut de ligne. Une idée pour résoudre ce problème consiste à envisager {{X1} } mais nous aurons un petit inconvénient à la fin de chaque ligne:

.ib {
  border: 1px solid #333;
  display: inline-block;
  padding: 3px;
}

.block-start {
  display: inline;
  padding: 3px 3px 4px;
  white-space: pre-wrap;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone; 
  border:1px solid red;
}
/* Create the break line */
.block-start:not(:first-child):before {
  content: "\A";
}
<div class="container">
  <div class="block-start">block-start</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="block-start">block-start</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="block-start">block-start</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
</div>

Nous pouvons toujours corriger cela en ajoutant une marge négative afin de la cacher derrière les autres éléments (nous devrions également ajouter une couleur de fond)

.ib {
  border: 1px solid #333;
  display: inline-block;
  padding: 3px;
  background:#fff;
  position:relative;
}

.block-start {
  display: inline;
  padding: 3px 3px 4px;
  white-space: pre-wrap;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone; 
  border:1px solid red;
  
  margin-left:-15px;
  
}
.container {
  padding-left:15px;
}
/* Create the break line */
.block-start:not(:first-child):before {
  content: "\A";
}
<div class="container">
  <div class="block-start">block-start</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="block-start">block-start</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="block-start">block-start</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
</div>

Nous pouvons également considérer l'autre pseudo élément et attribut de données pour avoir plus de contrôle sur le style sans aucun piratage. C'est la solution que je recommande

J'ai utilisé l'attribut class mais vous pouvez envisager un attribut personnalisé au cas où vous voudriez un contenu différent.

.ib {
  border: 1px solid #333;
  display: inline-block;
  padding: 3px;
}

.block-start {
  display: inline;
  white-space: pre-wrap;
}

/* Create the break line */
.block-start:not(:first-child):before {
  content: "\A";
}

.block-start:after {
  content: attr(class);
  display:inline-block;
  border:1px solid red;
  padding: 3px;
}
<div class="container">
  <div class="block-start"></div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="block-start"></div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="block-start"></div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
</div>

CSS break line with inline-block


La même astuce peut également fonctionner si vous souhaitez effacer après

.ib {
  border: 1px solid #333;
  display: inline-block;
  padding: 3px;
}

.block-end {
  display: inline;
  white-space: pre-wrap;
  
}

/* Create the break line */
.block-end:not(:first-child):after {
  content: "\A";
}

.block-end:before {
  content: attr(class);
  display: inline-block;
  padding: 3px;
  border:1px solid red;
}
<div class="container">
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="block-end"></div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="block-end"></div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="block-end"></div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
</div>

multiline inline-block css


Voici une variante de la même idée qui peut être utile dans d'autres situations

Avec flexbox:

.container {
 display:flex;
 flex-wrap:wrap;
 align-items:center;
}

.ib {
  border: 1px solid #333;
  padding: 3px;
  background:#fff;
  position:relative;
  margin:0 3px 0;
}
.ib + .ib {
   margin-left:0;
}

.block-start {
  display: contents;
  
}
.container {
  padding-left:15px;
}
/* Create the break line */
.block-start:not(:first-child):before {
  content: "";
  flex-basis:100%;
  height:1px;
}
/* Will replace the content*/
.block-start:after {
  content: attr(class);
  border:1px solid red;
  padding: 3px;
}
<div class="container">
  <div class="block-start"></div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="block-start"></div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="block-start"></div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
</div>

Avec grille CSS:

.container {
 display:grid;
 grid-template-columns:repeat(auto-fill,minmax(90px,1fr));
 grid-gap:2px;
 align-items:center;
}

.ib {
  border: 1px solid #333;
  padding: 3px;
  background:#fff;
  position:relative;
}

.block-start {
  display: contents;
  
}
.container {
  padding-left:15px;
}
/* Create the break line */
.block-start:not(:first-child):before {
  content: "";
  grid-column:1/-1;
}
/* Will replace the content*/
.block-start:after {
  content: attr(class);
  border:1px solid red;
  padding: 3px;
}
<div class="container">
  <div class="block-start"></div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="block-start"></div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
  <div class="block-start"></div>
  <div class="ib">inline-block</div>
  <div class="ib">inline-block</div>
</div>
6
Temani Afif 23 mars 2020 à 13:28

Ce que vous décrivez ressemble à une mise en page de rodage:

Une boîte de rodage est une boîte qui fusionne dans un bloc qui vient après elle, s'insérant au début du contenu de niveau en ligne de ce bloc. Ceci est utile pour mettre en forme des titres compacts, des définitions et d'autres choses similaires, où la structure DOM appropriée doit avoir un titre précédant la prose suivante, mais l'affichage souhaité est un titre en ligne disposé avec le texte. [1]

Cependant, la prise en charge des navigateurs est actuellement très médiocre et, dans certains cas, a régressé [2]. Si vous avez le contrôle sur le balisage, encapsuler chaque groupe d'éléments .ib et .block-start dans une nouvelle balise de niveau bloc est probablement votre meilleur choix.

[1] https://drafts.csswg.org/css-display/ # run-in-layout

[2] https://caniuse.com/#feat=run-in

0
Nate Whittaker 26 juin 2019 à 18:17

Dans le sélecteur .block-start, changez simplement la propriété display:inline-block en display:block. Et modifiez également le html <div> comme indiqué ci-dessous

J'espère que cela fonctionnera.

.ib {
  border: 1px solid #333;
  display: inline-block;
  padding: 3px;
}
.block-start {
  border: 1px solid #0cc;
  display: block;
  padding: 3px;
}
<div class="container">
   <div class="block-start">block-start
          <div class="ib">inline-block</div>
          <div class="ib">inline-block</div>
          <div class="ib">inline-block</div>
          <div class="ib">inline-block</div>
   </div>
   <div class="block-start">block-start
          <div class="ib">inline-block</div>
          <div class="ib">inline-block</div>
          <div class="ib">inline-block</div>
          <div class="ib">inline-block</div>
    </div>
</div>
-2
Dhiraj Mehta 24 juin 2019 à 08:23