Pour définir la distance minimale entre les éléments flexbox, j'utilise margin: 0 5px
sur .item
et margin: 0 -5px
sur le conteneur. Pour moi, cela ressemble à un bidouillage, mais je ne peux pas trouver un meilleur moyen de le faire.
#box {
display: flex;
width: 100px;
margin: 0 -5px;
}
.item {
background: gray;
width: 50px;
height: 50px;
margin: 0 5px;
}
<div id='box'>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
</div>
border-spacing
pour les tables.Par conséquent, atteindre ce que vous demandez est un peu plus difficile.
D'après mon expérience, le moyen le plus "propre" de ne pas utiliser :first-child
/:last-child
et fonctionner sans modification sur flex-wrap:wrap
consiste à définir padding:5px
sur le conteneur et margin:5px
sur les enfants. Cela produira un écart de 10px
entre chaque enfant et entre chaque enfant et son parent.
.upper
{
margin:30px;
display:flex;
flex-direction:row;
width:300px;
height:80px;
border:1px red solid;
padding:5px; /* this */
}
.upper > div
{
flex:1 1 auto;
border:1px red solid;
text-align:center;
margin:5px; /* and that, will result in a 10px gap */
}
.upper.mc /* multicol test */
{flex-direction:column;flex-wrap:wrap;width:200px;height:200px;}
<div class="upper">
<div>aaa<br/>aaa</div>
<div>aaa</div>
<div>aaa<br/>aaa</div>
<div>aaa<br/>aaa<br/>aaa</div>
<div>aaa</div>
<div>aaa</div>
</div>
<div class="upper mc">
<div>aaa<br/>aaa</div>
<div>aaa</div>
<div>aaa<br/>aaa</div>
<div>aaa<br/>aaa<br/>aaa</div>
<div>aaa</div>
<div>aaa</div>
</div>
Ce n'est pas un hack ... La même technique est également utilisée par bootstrap et sa grille, bien que, au lieu de margin, bootstrap utilise un padding pour ses colonnes.
.row {
margin:0 -15px;
}
.col-xx-xx {
padding:0 15px;
}
Vous pouvez utiliser des bordures transparentes.
J'ai envisagé ce problème tout en essayant de construire un modèle de grille flexible qui peut se replier sur un modèle tables + cellules-tables pour les anciens navigateurs. Et Border pour les gouttières de colonnes me semblait le meilleur choix. c'est-à-dire que les cellules de tableau n'ont pas de marges.
par exemple.
.column{
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-bottom: 10px solid transparent;
}
Notez également que vous avez besoin de min-width: 50px;
pour flexbox. Le modèle flex ne gérera pas les tailles fixes à moins que vous ne fassiez flex: none;
sur l'élément enfant particulier que vous voulez comme étant fixé et donc exclu d'être "flexi"
. http://jsfiddle.net/GLpUp/4/ Mais toutes les colonnes avec flex:none;
ne sont plus un modèle flex . Voici quelque chose de plus proche d'un modèle flex: http: // jsfiddle.net/GLpUp/5/
Vous pouvez donc utiliser les marges normalement si vous n’avez pas besoin de la solution de secours pour les anciens navigateurs. http://jsfiddle.net/GLpUp/3/
Il est nécessaire de définir background-clip: padding-box;
lorsqu’on utilise un arrière-plan, sinon l’arrière-plan s’écoulera dans la zone de bordure transparente.
Bonjour, voici ma solution de travail pour tous les navigateurs prenant en charge flexbox. Pas de marges négatives, pas de hacks, pas de solutions de contournement, de la pure CSS.
.flexbox {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
}
.flexbox > div {
/*
1/3 - 3 columns per row
10px - spacing between columns
*/
box-sizing: border-box;
margin-bottom: 10px;
width: calc(1/3*100% - (1 - 1/3)*10px);
}
<div class="flexbox">
<div>col</div>
<div>col</div>
<div>col</div>
<div>col</div>
<div>col</div>
<div>col</div>
</div>
Cela fonctionnera pour tous les cas, même s'il y a plusieurs lignes ou un nombre quelconque d'éléments.
Nous utilisons display: grid;
et ses propriétés.
#box {
display: grid;
width: 100px;
grid-gap: 5px;
/* Space between items */
grid-template-columns: 1fr 1fr 1fr 1fr;
/* Decide the number of columns and size */
}
.item {
background: gray;
width: 100%;
/* width is not necessary only added this to understand that width works as 100% to the grid template allocated space **DEFAULT WIDTH WILL BE 100%** */
height: 50px;
}
<div id='box'>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
</div>
Les inconvénients de cette méthode dans Mobile Opera Mini ne seront pas pris en charge et sur PC, cela ne fonctionne qu'après IE11.
ANCIENNE RÉPONSE
Si vous le souhaitez, vous pouvez toujours utiliser combinaison de frères CSS:
.item+.item{
margin-left: 5px;
}
Le code ci-dessus fera l'affaire. Dans cette méthode, il n'est pas nécessaire de donner margin: 0 -5px;
au wrapper #box
.
Un échantillon de travail pour vous:
#box {
display: flex;
width: 100px;
}
.item {
background: gray;
width: 50px;
height: 50px;
}
.item+.item{
margin-left: 5px;
}
<div id='box'>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
</div>
J'ai trouvé une solution basée sur le sélecteur css preceded by
et ~
, qui permet une imbrication non définie.
Voir ce stylo code pour un exemple de travail
Fondamentalement, à l'intérieur des conteneurs de colonnes, chaque enfant précédé d'un autre enfant obtient une marge supérieure. De même, à l'intérieur de chaque conteneur de lignes, chaque enfant précédé d'un autre se voit attribuer une marge gauche.
.box {
display: flex;
flex-grow: 1;
flex-shrink: 1;
}
.box.columns {
flex-direction: row;
}
.box.columns>.box~.box {
margin-left: 5px;
}
.box.rows {
flex-direction: column;
}
.box.rows>.box~.box {
margin-top: 5px;
}
<div class="box columns">
<div class="box" style="background-color: red;"></div>
<div class="box rows">
<div class="box rows">
<div class="box" style="background-color: blue;"></div>
<div class="box" style="background-color: orange;"></div>
<div class="box columns">
<div class="box" style="background-color: yellow;"></div>
<div class="box" style="background-color: pink;"></div>
</div>
</div>
<div class="box" style="background-color: green;"></div>
</div>
</div>
Passant à la réponse de sawa, voici une version légèrement améliorée qui vous permet de définir un espacement fixe entre les éléments sans la marge environnante.
http://jsfiddle.net/chris00/s52wmgtq/49/
La version "-webkit-flex" de Safari est également incluse.
.outer1 {
background-color: orange;
padding: 10px;
}
.outer0 {
background-color: green;
overflow: hidden;
}
.container
{
display: flex;
display: -webkit-flex;
flex-wrap: wrap;
-webkit-flex-wrap: wrap;
background-color: rgba(0, 0, 255, 0.5);
margin-left: -10px;
margin-top: -10px;
}
.item
{
flex-grow: 1;
-webkit-flex-grow: 1;
background-color: rgba(255, 0, 0, 0.5);
width: 100px;
padding: 10px;
margin-left: 10px;
margin-top: 10px;
text-align: center;
color: white;
}
<div class="outer1">
<div class="outer0">
<div class="container">
<div class="item">text</div>
<div class="item">text</div>
<div class="item">text</div>
<div class="item">text</div>
<div class="item">text</div>
<div class="item">text</div>
</div>
</div>
</div>
Supposons que si vous souhaitez définir un espace 10px
entre les éléments, vous pouvez simplement définir .item {margin-right:10px;}
pour tous et le réinitialiser sur le dernier .item:last-child {margin-right:0;}
.
Vous pouvez également utiliser le sélecteur de frère ~
ou le sélecteur de frère +
suivant pour définir la marge gauche des éléments, à l'exception du premier .item ~ .item {margin-left:10px;}
, ou utiliser .item:not(:last-child) {margin-right: 10px;}
Flexbox est tellement intelligent qu'il recalcule et distribue automatiquement la grille de manière égale.
body {
margin: 0;
}
.container {
display: flex;
}
.item {
flex: 1;
background: gray;
height: 50px;
}
.item:not(:last-child) {
margin-right: 10px;
}
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
Si vous souhaitez autoriser flex wrap , reportez-vous à l'exemple suivant.
body {
margin: 0;
}
.container {
display: flex;
flex-wrap: wrap;
margin-left: -10px;
}
.item {
flex: 0 0 calc(50% - 10px);
background: gray;
height: 50px;
margin: 0 0 10px 10px;
}
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
Vous pouvez utiliser& > * + *
selector pour émuler un flex-gap
(pour une seule ligne):
#box { display: flex; width: 230px; outline: 1px solid blue; }
.item { background: gray; width: 50px; height: 100px; }
/* ----- Flexbox gap: ----- */
#box > * + * {
margin-left: 10px;
}
<div id='box'>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
</div>
Si vous avez besoin de supporter flex wrapping , vous pouvez utiliser un élément wrapper:
.flex { display: flex; flex-wrap: wrap; }
.box { background: gray; height: 100px; min-width: 100px; flex: auto; }
.flex-wrapper {outline: 1px solid red; }
/* ----- Flex gap 10px: ----- */
.flex > * {
margin: 5px;
}
.flex {
margin: -5px;
}
.flex-wrapper {
width: 400px; /* optional */
overflow: hidden; /* optional */
}
<div class='flex-wrapper'>
<div class='flex'>
<div class='box'></div>
<div class='box'></div>
<div class='box'></div>
<div class='box'></div>
<div class='box'></div>
</div>
</div>
J'ai utilisé cela pour les colonnes enveloppées et à largeur fixe. La clé ici est calc()
Exemple SCSS
$gap: 10px;
dl {
display: flex;
flex-wrap: wrap;
padding: $gap/2;
dt, dd {
margin: $gap/2;}
dt { // full width, acts as header
flex: 0 0 calc(100% - #{$gap});}
dd { // default grid: four columns
flex: 0 0 calc(25% - #{$gap});}
.half { // hall width columns
flex: 0 0 calc(50% - #{$gap});}
}
Un conteneur flexible avec marge -x (négative) et éléments flexibles avec marge x (positive) ou padding les deux conduit au résultat visuel souhaité: les éléments Flex ont un espace fixe de 2x uniquement entreles uns des autres.
Il semble que ce soit simplement une question de préférence, qu’il s’agisse d’utiliser une marge ou un rembourrage sur les éléments flexibles.
Dans cet exemple, les éléments flexibles sont mis à l’échelle de manière dynamique afin de préserver l’espace fixe:
.flex-container {
margin: 0 -5px;
display: flex;
flex-flow: row wrap;
justify-content: space-between;
}
.flex-item {
margin: 0 5px; // Alternatively: padding: 0 5px;
flex: 1 0 auto;
}
Finalement, ils ajouteront la propriété gap
à flexbox. Jusque-là, vous pourriez utiliser la grille CSS à la place, qui possède déjà la propriété gap
, et ne disposer que d’une seule ligne. Plus agréable que de traiter avec des marges.
Pourquoi ne pas le faire comme ça:
.item + .item {
margin-left: 5px;
}
Ceci utilise le sélecteur frère adjacent , pour donner à tous les éléments .item
, à l'exception du premier, un margin-left
. Grâce à la flexbox, cela donne même des éléments de même largeur. Cela pourrait également être fait avec des éléments positionnés verticalement et margin-top
, bien sûr.
Utilisation de Flexbox dans ma solution J'ai utilisé la propriété justify-content
pour l'élément parent (conteneur) et j'ai spécifié les marges à l'intérieur de la propriété flex-basis
des éléments . Vérifiez l'extrait de code ci-dessous:
.container {
display: flex;
flex-flow: row wrap;
justify-content: space-around;
margin-bottom: 10px;
}
.item {
height: 50px;
display: flex;
justify-content: center;
align-items: center;
background-color: #999;
}
.item-1-4 {
flex-basis: calc(25% - 10px);
}
.item-1-3 {
flex-basis: calc(33.33333% - 10px);
}
.item-1-2 {
flex-basis: calc(50% - 10px);
}
<div class="container">
<div class="item item-1-4">1</div>
<div class="item item-1-4">2</div>
<div class="item item-1-4">3</div>
<div class="item item-1-4">4</div>
</div>
<div class="container">
<div class="item item-1-3">1</div>
<div class="item item-1-3">2</div>
<div class="item item-1-3">3</div>
</div>
<div class="container">
<div class="item item-1-2">1</div>
<div class="item item-1-2">2</div>
</div>
J'utilise souvent l'opérateur + pour de tels cas
#box {
display: flex;
width: 100px;
}
.item {
background: gray;
width: 50px;
height: 50px;
}
.item + .item {
margin-left: 5px;
}
<div id='box'>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
</div>
Voici ma solution, cela ne nécessite pas la définition de classes sur les éléments enfants:
.flex-inline-row {
display: inline-flex;
flex-direction: row;
}
.flex-inline-row.flex-spacing-4px > :not(:last-child) {
margin-right: 4px;
}
Usage:
<div class="flex-inline-row flex-spacing-4px">
<span>Testing</span>
<span>123</span>
</div>
La même technique peut être utilisée pour les rangées et colonnes flexibles normales en plus de l'exemple en ligne donné ci-dessus, et étendue avec des classes d'espacement autres que 4px.
Avec Flexbox, créer des gouttières est une douleur, en particulier lorsque l’emballage est impliqué.
Vous devez utiliser des marges négatives ( comme indiqué dans la question ):
#box {
display: flex;
width: 100px;
margin: 0 -5px;
}
... ou modifiez le code HTML ( comme indiqué dans une autre réponse _):
<div class='flex-wrapper'>
<div class='flex'>
<div class='box'></div>
<div class='box'></div>
...
</div>
</div>
... ou autre chose.
Dans tous les cas, vous avez besoin d'un bidouillage laid pour que cela fonctionne, car flexbox ne fournit pas de fonctionnalité "flex-gap
" ( Au moins pour le moment ).
La question des gouttières est cependant simple et facile avec CSS Grid Layout.
La spécification Grid fournit des propriétés qui créent un espace entre les éléments de la grille, tout en ignorant l'espace entre les éléments et le conteneur. Ces propriétés sont:
grid-column-gap
grid-row-gap
grid-gap
(le raccourci pour les deux propriétés ci-dessus)Récemment, la spécification a été mise à jour pour se conformer au module d'alignement de la boîte CSS , qui fournit un ensemble de propriétés d'alignement à utiliser dans tous les modèles de boîte. Donc, les propriétés sont maintenant:
column-gap
row-gap
gap
(sténographie)Cependant, tous les navigateurs prenant en charge la grille ne prennent pas en charge les nouvelles propriétés. Je vais donc utiliser les versions originales de la démo ci-dessous.
De plus, si un espacement est nécessaire entre les éléments et le conteneur, padding
sur le conteneur fonctionne parfaitement (voir le troisième exemple de la démonstration ci-dessous).
De la spécification:
10.1. Gouttières: les
row-gap
,column-gap
etgap
PropertiesLes propriétés
row-gap
etcolumn-gap
(et leur raccourcigap
), lorsque spécifié sur un conteneur de grille, définissez les gouttières entre les grilles lignes et colonnes de la grille. Leur syntaxe est définie dans Alignement de la boîte CSS 3 §8 Espace entre les cases .L’effet de ces propriétés est comme si les lignes de la grille concernées Épaisseur acquise: le chemin de la grille entre deux lignes est l’espace entre les gouttières qui les représentent.
.box {
display: inline-grid;
grid-auto-rows: 50px;
grid-template-columns: repeat(4, 50px);
border: 1px solid black;
}
.one {
grid-column-gap: 5px;
}
.two {
grid-column-gap: 10px;
grid-row-gap: 10px;
}
.three {
grid-gap: 10px;
padding: 10px;
}
.item {
background: lightgray;
}
<div class='box one'>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
</div>
<hr>
<div class='box two'>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
</div>
<hr>
<div class='box three'>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
</div>
Plus d'information:
.columnify {
display: flex;
> * {
flex: 1;
&:not(:first-child) {
margin-left: 2rem;
}
}
}
.columnify {
display: flex;
}
.columnify > * {
flex: 1;
}
.columnify > *:not(:first-child) {
margin-left: 2rem;
}
<div class="columnify">
<div style="display: inline-block; height: 20px; background-color: blue;"></div>
<div style="display: inline-block; height: 20px; background-color: blue"></div>
<div style="display: inline-block; height: 20px; background-color: blue"></div>
</div>
Jouez avec sur JSFiddle .
Il suffit d'utiliser .item + .item
dans le sélecteur pour faire correspondre le deuxième .item
#box {
display: inline-flex;
margin: 0 -5px;
}
.item {
background: gray;
width: 10px;
height: 50px;
}
#box .item + .item {
margin-left: 10px;
}
<div id='box'>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
</div>
Voici une grille d'éléments d'interface utilisateur de carte avec espacement complété à l'aide de la boîte flexible:
J'étais frustré par l'espacement manuel des cartes en manipulant le remplissage et les marges avec des résultats douteux. Voici donc les combinaisons d'attributs CSS que j'ai trouvées très efficaces:
.card-container {
width: 100%;
height: 900px;
overflow-y: scroll;
max-width: inherit;
background-color: #ffffff;
/*Here's the relevant flexbox stuff*/
display: flex;
flex-direction: row;
justify-content: center;
align-items: flex-start;
flex-wrap: wrap;
}
/*Supplementary styles for .card element*/
.card {
width: 120px;
height: 120px;
background-color: #ffeb3b;
border-radius: 3px;
margin: 20px 10px 20px 10px;
}
<section class="card-container">
<div class="card">
</div>
<div class="card">
</div>
<div class="card">
</div>
<div class="card">
</div>
</section>
J'espère que cela aide les gens, présents et futurs.
En supposant:
Définissez une marge gauche pour chaque élément sauf les 1er, 5ème, 9ème et ainsi de suite; et définir une largeur fixe sur chaque article. Si la marge de gauche est de 10 pixels, chaque ligne aura une marge de 30 pixels entre 4 éléments. La largeur en pourcentage de l'élément peut être calculée comme suit:
100% / 4 - horizontal-border - horizontal-padding - left-margin * (4 - 1) / 4
Il s'agit d'une solution de contournement décente pour les problèmes liés à la dernière rangée de flexbox.
.flex {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin: 1em 0;
background-color: peachpuff;
}
.item {
margin-left: 10px;
border: 1px solid;
padding: 10px;
width: calc(100% / 4 - 2px - 20px - 10px * (4 - 1) / 4);
background-color: papayawhip;
}
.item:nth-child(4n + 1) {
margin-left: 0;
}
.item:nth-child(n + 5) {
margin-top: 10px;
}
<div class="flex">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
<div class="flex">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
</div>
<div class="flex">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
Il existe en effet un moyen agréable, ordonné et uniquement CSS de le faire (que l’on peut considérer comme "meilleur").
De toutes les réponses postées ici, je n’en ai trouvé qu’une qui utilise calc () avec succès (par Dariusz Sikorski). Mais lorsque posé avec: "mais cela échoue s'il n'y a que 2 éléments dans la dernière rangée", aucune solution n'a été développée.
Cette solution répond à la question du PO avec une alternative aux marges négatives et au problème posé à Dariusz.
remarques:
calc()
pour permettre au navigateur d’effectuer les opérations mathématiques de la façon dont il le souhaite --100%/3
(bien que 33,3333% fonctionne aussi bien), et (1em/3)*2
(bien que .66em devrait également bien fonctionner).::after
pour remplir la dernière ligne s'il y a moins d'éléments que de colonnes.flex-container {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.flex-container:after {
content: "";
}
.flex-container > div,
.flex-container:after {
box-sizing: border-box;
width: calc((100%/3) - ((1em/3)*2));
}
.flex-container > :nth-child(n + 4) {
margin-top: 1em;
}
/* the following is just to visualize the items */
.flex-container > div,
.flex-container:after {
font-size: 2em;
}
.flex-container {
margin-bottom:4em;
}
.flex-container > div {
text-align: center;
background-color: #aaa;
padding: 1em;
}
.flex-container:after {
border: 1px dashed red;
}
<h2>Example 1 (2 elements)</h2>
<div class="flex-container">
<div>1</div>
<div>2</div>
</div>
<h2>Example 2 (3 elements)</h2>
<div class="flex-container">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
Également sur https://codepen.io/anon/pen/rqWagE
Je trouve que le moyen le plus simple de le faire est d'utiliser des pourcentages et de simplement laisser la marge correspondre à votre largeur.
Cela signifie que vous vous retrouvez avec quelque chose comme ceci si vous utilisez votre exemple
#box {
display: flex;
}
.item {
flex: 1 1 23%;
margin: 0 1%;
}
Cela signifie-t-il que vos valeurs sont basées sur la largeur, ce qui peut ne pas convenir à tout le monde?.
Je suis tombé sur le même problème plus tôt, puis suis tombé sur la réponse pour cela. J'espère que cela aidera les autres pour référence future.
longue réponse bref, ajoutez une bordure à votre enfant flex-items . alors vous pouvez spécifier des marges entre les flex-items de ce que vous voulez . ' si tu veux.
#box {
display: flex;
width: 100px;
/* margin: 0 -5px; *remove this*/
}
.item {
background: gray;
width: 50px;
height: 50px;
/* margin: 0 5px; *remove this*/
border: 1px solid black; /* add this */
}
.item.special{ margin: 0 10px; }
<div id='box'>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item special'></div>
</div>
L'astuce de la marge négative sur le conteneur de boîte fonctionne parfaitement. Voici un autre exemple qui fonctionne très bien avec l'ordre, l'emballage et tout le reste.
.container {
border: 1px solid green;
width: 200px;
display: inline-block;
}
#box {
display: flex;
flex-wrap: wrap-reverse;
margin: -10px;
border: 1px solid red;
}
.item {
flex: 1 1 auto;
order: 1;
background: gray;
width: 50px;
height: 50px;
margin: 10px;
border: 1px solid blue;
}
.first {
order: 0;
}
<div class=container>
<div id='box'>
<div class='item'>1</div>
<div class='item'>2</div>
<div class='item first'>3*</div>
<div class='item'>4</div>
<div class='item'>5</div>
</div>
</div>
#box {
display: flex;
width: 100px;
}
.item {
background: gray;
width: 50px;
height: 50px;
}
/* u mean utility */
.u-gap-10 > *:not(:last-child) {
margin-right: 10px;
}
<div id='box' class="u-gap-10">
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
<div class='item'></div>
</div>
Cela ne fonctionnera pas dans tous les cas, mais si vous avez une largeur d'enfant flexible (%) et que vous connaissez le nombre d'éléments par ligne, vous pouvez spécifier très proprement les marges des éléments nécessaires à l'aide de nth-child
selector/s.
Cela dépend en grande partie de ce que vous entendez par "meilleur". Cette méthode ne nécessite pas de balisage supplémentaire pour les éléments enfants ou les éléments négatifs, mais ces deux éléments ont leur place.
section {
display: block
width: 100vw;
}
.container {
align-content: flex-start;
align-items: stretch;
background-color: #ccc;
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
width: 100%;
}
.child-item {
background-color: #c00;
margin-bottom: 2%;
min-height: 5em;
width: 32%;
}
.child-item:nth-child(3n-1) {
margin-left: 2%;
margin-right: 2%;
}
<html>
<body>
<div class="container">
<div class="child-item"></div>
<div class="child-item"></div>
<div class="child-item"></div>
<div class="child-item"></div>
<div class="child-item"></div>
<div class="child-item"></div>
<div class="child-item"></div>
</div>
</body>
</html>
J'ai trouvé un hack parce que j'ai vraiment besoin de ça moi-même.
/* grid */
.container {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
}
.container::after, /* this makes sure odd element goes left and not space between */
.item {
content:"";
width: calc(33.3333% - 20px);
margin-bottom: 40px;
}
/* extra styling - not important */
.item {
height: 100px;
background: #787878;
}
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
Voici une grille de messages avec les catégories de Nice flex grow également . Je pense que vous l'aimeriez bien . Voir Codepen
Je règle l'espacement sur les articles flexibles uniquement dans la direction indiquée par leur conteneur . si un conteneur flex est configuré pour s'écouler de gauche à droite (flex-direction:row
), je ne définirai que la marge right sur ses enfants, à l'exception du dernier:
.flex-lr{
display:flex;
flex-direction:row;
}
.flex-lr > *:not(:last-child){
margin-right:5px;
}
Cela peut sembler fonctionner au premier abord mais attendez! cela ne devrait pas être fait lorsque justify-content
est défini sur une valeur autre que start
ou end
, car toutes les autres valeurs distribuent déjà l'espace par elles-mêmes.
Et si les objets sont emballés? Ensuite, nous devrions également ajouter de l’espace au côté de l’axe transversal approprié. Mais comment savoir si un conteneur permet à ses enfants de s’envelopper? Et que dire de wrap-reverse
?
Toutes ces considérations m'ont fait penser que ce n'était pas une tâche triviale et qu'il fallait un petit pas en avant.
Mon approche est basée sur la construction d'un bref ensemble de classes qui agit comme un wrapper de flexbox. Cela a quelques avantages:
J'ai fini par créer un concepteur de flexbox pour jouer avec tout cela, pour aider à comprendre moi-même (et les autres) comment fonctionne la flexbox et à réaliser à quel point la flexbox est merveilleuse.
http://algid.com/Flex-Designer
Vous trouverez ci-dessous un résumé des classes que j’utilise et de l’utlity spacing (margin) pour un sens de flux. Vous pourrez en déduire les autres ou les trouver dans le lien fourni ci-dessus. Les préfixes de vendeurs ont été omis ici par souci de concision.
/* Flex container definition */
.flex-lr{display:flex; flex-direction:row;}
.flex-tb{display:flex; flex-direction:column;}
.flex-rl{display:flex; flex-direction:row-reverse;}
.flex-bt{display:flex; flex-direction:column-reverse;}
/* Wrapping */
.wrap{flex-wrap:wrap;}
.nowrap{flex-wrap:nowrap;}
.wrap-rev{flex-wrap:wrap-reverse;}
/* Main axis alignment */
.align-start{justify-content:flex-start;}
.align-end{justify-content:flex-end;}
.align-center{justify-content:center;}
.align-between{justify-content:space-between;}
.align-around{justify-content:space-around;}
.align-evenly{justify-content:space-evenly;}
/* Cross axis alignment */
.cross-align-start{align-items:flex-start;}
.cross-align-end{align-items:flex-end;}
.cross-align-center{align-items:center;}
.cross-align-stretch{align-items:stretch;}
.cross-align-baseline{align-items:baseline;}
/* Cross axis alignment when content is wrapped */
.wrap-align-start{align-content:flex-start;}
.wrap-align-end{align-content:flex-end;}
.wrap-align-center{align-content:center;}
.wrap-align-stretch{align-content:stretch;}
.wrap-align-between{align-content:space-between;}
.wrap-align-around{align-content:space-around;}
/* Item alignment */
.item-cross-align-start{align-self:flex-start;}
.item-cross-align-end{align-self:flex-end;}
.item-cross-align-center{align-self:center;}
.item-cross-align-stretch{align-self:stretch;}
.item-cross-align-baseline{align-self:baseline;}
.item-cross-align-auto{align-self:auto;}
Et maintenant, la chose qui nous a amenés ici: l'espace entre les éléments:
/* Flow margin (left to right) */
.flex-lr.fm-0 > *:not(:last-child){margin-right:0;}
.flex-lr.fm-1 > *:not(:last-child){margin-right:3px;}
.flex-lr.fm-2 > *:not(:last-child){margin-right:7px;}
.flex-lr.fm-3 > *:not(:last-child){margin-right:15px;}
.flex-lr.fm-4 > *:not(:last-child){margin-right:32px;}
/* Cross axis */
.flex-lr.wrap.fm-0:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap.fm-0.wrap-align-stretch.cross-align-stretch > * {margin-bottom:0;}
.flex-lr.wrap.fm-1:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap.fm-1.wrap-align-stretch.cross-align-stretch > * {margin-bottom:3px;}
.flex-lr.wrap.fm-2:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap.fm-2.wrap-align-stretch.cross-align-stretch > * {margin-bottom:7px;}
.flex-lr.wrap.fm-3:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap.fm-3.wrap-align-stretch.cross-align-stretch > * {margin-bottom:15px;}
.flex-lr.wrap.fm-4:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap.fm-4.wrap-align-stretch.cross-align-stretch > * {margin-bottom:32px;}
/* wrap reverse */
.flex-lr.wrap-rev.fm-0:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap-rev.fm-0.wrap-align-stretch.cross-align-stretch > * {margin-top:0;}
.flex-lr.wrap-rev.fm-1:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap-rev.fm-1.wrap-align-stretch.cross-align-stretch > * {margin-top:3px;}
.flex-lr.wrap-rev.fm-2:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap-rev.fm-2.wrap-align-stretch.cross-align-stretch > * {margin-top:7px;}
.flex-lr.wrap-rev.fm-3:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap-rev.fm-3.wrap-align-stretch.cross-align-stretch > * {margin-top:15px;}
.flex-lr.wrap-rev.fm-4:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap-rev.fm-4.wrap-align-stretch.cross-align-stretch > * {margin-top:32px;}
Enfin, voici à quoi ressemblerait le balisage:
<div class="flex-lr cross-align-center fm-3">
<div>
Some content here...
</div>
<div>
A bit more stuff here...
</div>
<div class="flex-tb fm-3">
<div>
Now vertical content
</div>
<div>
etc.
</div>
</div>
</div>
C'est ce que j'appelle le code à haute voix.