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.
3 réponses
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>
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>
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>
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
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>
Questions connexes
Questions liées
De nouvelles questions
css
CSS (Cascading Style Sheets) est un langage de feuille de style de représentation utilisé pour décrire l'apparence et la mise en forme des documents HTML (HyperText Markup Language), XML (Extensible Markup Language) et des éléments SVG, y compris (mais sans s'y limiter) les couleurs, la mise en page, les polices, et animations. Il décrit également comment les éléments doivent être affichés à l'écran, sur papier, dans un discours ou sur d'autres supports.