C'est ce que je veux:
Le plus proche que j'ai. Application de la marge sur flexbox, puis suppression de la moitié de celle-ci des premier et dernier enfants.
Le problème est que :first-child
n'est pas toujours le premier visuellement, car je peux modifier l'ordre de présentation ( exemple ).
Existe-t-il un moyen de prendre en compte l'ordre visuel lors de l'application de la marge?
Vous pouvez essayer de définir la même marge pour toutes les boîtes, puis inverser cette valeur sur le conteneur:
Alors remplacez ceci:
.flex > * { margin: 0 10px; }
.flex > :first-child { margin-left: 0; }
.flex > :last-child { margin-right: 0; }
.flex.vertical > :first-child { margin-top: 0; }
.flex.vertical > :last-child { margin-bottom: 0; }
Avec ça:
.flex.vertical { margin: -20px 0 0 -20px; }
.flex > * { margin: 0 0 0 20px; }
.flex.vertical > * { margin: 20px 0 0 0; }
voici une autre façon d'obtenir la même chose.
.vertical > div{ margin-bottom: 10px; }
.vertical > div:last-child{ margin-bottom: 0; }
.box + .box{ margin-left: 10px; }
Bien que Rejoy answer fonctionne parfaitement, il n'est pas prêt à répondre, car les lignes sont verrouillées.
flex-flow
est ton nouvel ami. Cependant, flex n'est pas sans bugs. L'astuce de la marge négative que nous connaissons dans divers cadres de grille fonctionne, sauf si vous êtes sur IE, où les éléments sont encapsulés trop tôt car ils utilisent content-box en tant que box-size. Mais il existe une solution de contournement facile.
Exemple de travail: https://jsfiddle.net/ys7w1786/
.flex {
display: flex;
flex-direction: row; /* let the content flow to the next row */
flex-wrap: wrap;
justify-content: flex-start;
align-items: flex-start;
margin: -4px -4px; /* grid trick, has to match box margin */
}
Les boîtes viennent avec flex-basis: auto
, à cause d'IE. Mais nous pouvons simplement utiliser width
à la place:
.box {
flex: 0 0 auto; /* auto is important because of an IE bug with box-size */
height: 100px;
display: inline-block;
background-color: black;
margin: 4px; /* spacing between boxes, matches parent element */
}
.s1-2{
width: calc(50% - 8px);
}
.s1-4{
width: calc(25% - 8px);
}
Ce que j’ai fait pour aborder cela, étant donné que je n’étais pas sûr du nombre d’éléments que je pourrais avoir dans chaque espace flexible. Par exemple, je construis un thème Drupal) et quatre régions alignées côte à côte, mais je souhaite que toute la largeur soit occupée, même si le contenu ne figure que dans trois les régions.
HTML ressemble à ceci:
<div class="flexy">
<div class="region">
<div class="region-inner">
</div>
</div>
</div>
CSS ressemble à ceci:
.flexy {
display: flex;
flex-wrap: wrap;
}
.flexy .region {
box-sizing: border-box;
flex-grow: 1;
flex-basis: 0;
padding: 10px;
}
Cela me laisse avec une mise en page comme ça (ignorer la laideur, les couleurs ne sont que pour démontrer):
Il existe d'autres classes ajoutées telles que "moitiés", "tiers" et "trimestres" pour aider à rendre les choses réactives sur des écrans plus petits et/ou plus grands.
Un autre point fort de l'utilisation de Flex est que vous pouvez spécifier la stratégie à utiliser pour l'espace restant:
.container {
justify-content: space-between;
}
Essayer de coller à votre question:
Existe-t-il un moyen de prendre en compte l'ordre visuel lors de l'application de la marge?
Je dirais non, de la même manière que vous ne pouvez pas styler un élément en fonction de la valeur, disons, de sa couleur d'arrière-plan. Pour ce faire, vous pouvez écrire des classes personnalisées pour définir l'ordre de flex, puis créer des sous-classes basées sur celles-ci.
S'il vous plaît consulter ce fil intéressant où j'ai posté ma solution sur l'espacement: n meilleur moyen de définir la distance entre flexbox items
La mise en page désirée peut être obtenue en utilisant un div wrapper avec une marge négative
.flex-wrapper{
margin: -20px;
}
Code de travail http://jsfiddle.net/8cju5jpd/