Considérez l’axe principal et l’axe transversal d’un conteneur flexible:
Source: W3C
Pour aligner les éléments flexibles le long de l’axe principal, il existe une propriété:
Pour aligner les éléments flexibles le long de l’axe transversal, il existe trois propriétés:
Dans l'image ci-dessus, l'axe principal est horizontal et l'axe transversal est vertical. Ce sont les directions par défaut d'un conteneur Flex.
Cependant, ces directions peuvent être facilement échangées avec la propriété flex-direction
.
_/* main axis is horizontal, cross axis is vertical */
flex-direction: row;
flex-direction: row-reverse;
/* main axis is vertical, cross axis is horizontal */
flex-direction: column;
flex-direction: column-reverse;
_
(L’axe transversal est toujours perpendiculaire à l’axe principal.)
Mon propos en décrivant le fonctionnement des axes est qu’il ne semble y avoir de particularité dans aucune des directions. Axe principal, axe transversal, ils sont égaux en importance et _flex-direction
_ facilite les échanges.
Alors pourquoi l'axe transversal obtient-il deux propriétés d'alignement supplémentaires?
Pourquoi _align-content
_ et _align-items
_ sont-ils consolidés dans une propriété unique pour l'axe principal?
Pourquoi l'axe principal n'a-t-il pas une propriété _justify-self
_?
Scénarios où ces propriétés seraient utiles:
placer un article flexible dans le coin du conteneur flexible
_#box3 { align-self: flex-end; justify-self: flex-end; }
_
aligner un groupe d'éléments flexibles à droite (_justify-content: flex-end
_) mais faire en sorte que le premier élément s'aligne à gauche (_justify-self: flex-start
_)
Considérons une section d'en-tête avec un groupe d'éléments de navigation et un logo. Avec _justify-self
_, le logo peut être aligné à gauche, tandis que les éléments de navigation restent tout à fait à droite, et le tout s’ajuste sans à-coups ("fléchit") à différentes tailles d’écran.
dans une rangée de trois éléments flexibles, fixez l'élément central au centre du conteneur (_justify-content: center
_) et alignez les éléments adjacents sur les bords du conteneur (_justify-self: flex-start
_ et _justify-self: flex-end
_).
Notez que les valeurs _space-around
_ et _space-between
_ sur _justify-content
_ ne garderont pas l'élément du milieu centré par rapport au conteneur si les éléments adjacents ont des largeurs différentes.
_#container {
display: flex;
justify-content: space-between;
background-color: lightyellow;
}
.box {
height: 50px;
width: 75px;
background-color: springgreen;
}
.box1 {
width: 100px;
}
.box3 {
width: 200px;
}
#center {
text-align: center;
margin-bottom: 5px;
}
#center > span {
background-color: aqua;
padding: 2px;
}
_
_<div id="center">
<span>TRUE CENTER</span>
</div>
<div id="container">
<div class="box box1"></div>
<div class="box box2"></div>
<div class="box box3"></div>
</div>
<p>note that the middle box will only be truly centered if adjacent boxes are equal width</p>
_
Au moment de la rédaction de ce document, il n’est fait aucune mention de _justify-self
_ ou _justify-items
_ dans le flexbox spec .
Cependant, dans le CSS Box Alignment Module , proposition du W3C inachevée visant à établir un ensemble commun de propriétés d'alignement à utiliser dans tous les modèles de boîte, présente les éléments suivants:
Source: W3C
Vous remarquerez que _justify-self
_ et _justify-items
_ sont à l'étude ... mais pas pour flexbox .
Je terminerai en réitérant la question principale:
Pourquoi n'y a-t-il pas de propriétés "justifier-éléments" et "justifier-soi"?
Comme indiqué dans la question:
Pour aligner les éléments flexibles le long de l'axe principal, il existe une propriété:
justify-content
Pour aligner les éléments flexibles le long de l'axe transversal, il existe trois propriétés:
align-content
,align-items
_ ET _align-self
.
La question demande alors:
Pourquoi n'y a-t-il pas de propriétés _
justify-items
_ et _justify-self
_?
Une réponse peut être: car elles ne sont pas nécessaires.
La spécification flexbox fournit deux méthodes pour aligner les éléments flexibles le long de l'axe principal:
justify-content
_, etauto
margesLa propriété justify-content
aligne les éléments flexibles le long de l'axe principal du conteneur flex.
Il s'applique au conteneur Flex mais n'affecte que les éléments Flex.
Il y a cinq options d'alignement:
flex-start
~ Les éléments Flex sont regroupés au début de la ligne.
flex-end
~ Les éléments Flex sont regroupés vers la fin de la ligne.
center
~ Les éléments Flex sont regroupés vers le centre de la ligne.
space-between
~ Les éléments Flex sont espacés régulièrement, le premier élément étant aligné sur un bord du conteneur et le dernier élément sur le bord opposé. Les arêtes utilisées par les premier et dernier éléments dépendent de flex-direction
et mode écriture (ltr
ou rtl
).
space-around
~ Identique à _space-between
_ sauf avec des espaces demi-taille aux deux extrémités.
Avec auto
margin , les éléments flexibles peuvent être centrés, espacés ou regroupés en sous-groupes.
Contrairement à _justify-content
_, qui est appliqué au conteneur flexible, les marges auto
s'appliquent aux éléments flexibles.
Ils travaillent en consommant tout l’espace libre dans la direction spécifiée.
Scénario de la question:
aligner un groupe d'éléments flexibles à droite (_
justify-content: flex-end
_) mais faire en sorte que le premier élément s'aligne à gauche (_justify-self: flex-start
_)Considérons une section d'en-tête avec un groupe d'éléments de navigation et un logo. Avec _
justify-self
_, le logo peut être aligné à gauche, tandis que les éléments de navigation restent tout à fait à droite, et le tout s’ajuste sans à-coups ("fléchit") à différentes tailles d’écran.
Autres scénarios utiles:
Scénario de la question:
- placer un article flexible dans un coin _
.box { align-self: flex-end; justify-self: flex-end; }
_
_margin: auto
_ est une alternative à _justify-content: center
_ et _align-items: center
_.
Au lieu de ce code sur le conteneur flex:
_.container {
justify-content: center;
align-items: center;
}
_
Vous pouvez l’utiliser sur l’article flex:
_.box56 {
margin: auto;
}
_
Cette alternative est utile lorsque [centrant un élément flexible qui déborde du conteneur] .
Un conteneur Flex aligne les éléments Flex en répartissant l’espace libre.
Par conséquent, afin de créer un solde égal , afin qu'un élément du milieu puisse être centré dans le conteneur avec un seul élément à côté, un contrepoids doit être introduit.
Dans les exemples ci-dessous, des articles de troisième flex invisible (cases 61 et 68) sont introduits pour équilibrer les "vrais" articles (cases 63 et 66).
Bien sûr, cette méthode n’a rien de bien en termes de sémantique.
Vous pouvez également utiliser un pseudo-élément au lieu d'un élément DOM réel. Ou vous pouvez utiliser le positionnement absolu. Les trois méthodes sont décrites ici: éléments flex centraux et alignés vers le bas
REMARQUE: Les exemples ci-dessus ne fonctionneront - en termes de centrage réel - que lorsque les éléments les plus externes auront la même hauteur/largeur. Si les éléments flexibles ont des longueurs différentes, voir l'exemple suivant.
Scénario de la question:
dans une rangée de trois éléments flexibles, fixez l'élément central au centre du conteneur (_
justify-content: center
_) et alignez les éléments adjacents sur les bords du conteneur (_justify-self: flex-start
_ et _justify-self: flex-end
_).Notez que les valeurs _
space-around
_ et _space-between
_ sur _justify-content
_ ne maintiendront pas l'élément du milieu centré par rapport au conteneur si les éléments adjacents ont des largeurs différentes (- voir la démo ).
Comme indiqué, à moins que tous les éléments flexibles aient une largeur ou une hauteur égales (selon _flex-direction
_), l'élément central ne peut pas être véritablement centré. Ce problème constitue un cas solide pour une propriété _justify-self
_ (conçue pour gérer la tâche, bien sûr).
_#container {
display: flex;
justify-content: space-between;
background-color: lightyellow;
}
.box {
height: 50px;
width: 75px;
background-color: springgreen;
}
.box1 {
width: 100px;
}
.box3 {
width: 200px;
}
#center {
text-align: center;
margin-bottom: 5px;
}
#center > span {
background-color: aqua;
padding: 2px;
}
_
_<div id="center">
<span>TRUE CENTER</span>
</div>
<div id="container">
<div class="box box1"></div>
<div class="box box2"></div>
<div class="box box3"></div>
</div>
<p>The middle box will be truly centered only if adjacent boxes are equal width.</p>
_
Voici deux méthodes pour résoudre ce problème:
Solution n ° 1: Positionnement absolu
La spécification flexbox permet positionnement absolu des éléments flex . Cela permet à l'élément du milieu d'être parfaitement centré quelle que soit la taille de ses frères et sœurs.
N'oubliez pas que, comme tous les éléments à positionnement absolu, les éléments sont supprimés de flux de documents . Cela signifie qu'ils ne prennent pas de place dans le conteneur et peuvent chevaucher leurs frères et soeurs.
Dans les exemples ci-dessous, l'élément central est centré avec le positionnement absolu et les éléments extérieurs restent entrants. Mais la même disposition peut être obtenue de manière inversée: Centrez l'élément du milieu avec _justify-content: center
_ et positionnez les éléments les plus à l'extérieur.
Solution n ° 2: Conteneurs Flex imbriqués (pas de positionnement absolu)
_.container {
display: flex;
}
.box {
flex: 1;
display: flex;
justify-content: center;
}
.box71 > span { margin-right: auto; }
.box73 > span { margin-left: auto; }
/* non-essential */
.box {
align-items: center;
border: 1px solid #ccc;
background-color: lightgreen;
height: 40px;
}
_
_<div class="container">
<div class="box box71"><span>71 short</span></div>
<div class="box box72"><span>72 centered</span></div>
<div class="box box73"><span>73 loooooooooooooooong</span></div>
</div>
_
Voilà comment cela fonctionne:
.container
_) est un conteneur flexible..box
_) est maintenant un élément flexible..box
_ reçoit _flex: 1
_ afin de répartir équitablement l'espace conteneur.justify-content: center
_.span
est un élément flex centré.auto
flexibles pour déplacer les span
s extérieurs vers la gauche et vers la droite.Vous pouvez également renoncer à _justify-content
_ et utiliser exclusivement les marges auto
.
Mais _justify-content
_ peut fonctionner ici car les marges auto
sont toujours prioritaires. De la spec:
8.1. Alignement sur les marges
auto
Avant l'alignement via _
justify-content
_ et _align-self
_, tout espace libre positif est distribué aux marges automatiques dans cette dimension.
Pour revenir à justify-content
pendant une minute, voici une idée pour une option supplémentaire.
space-same
~ Un hybride de _space-between
_ et _space-around
_. Les éléments flexibles sont régulièrement espacés (comme _space-between
_), à la place d'espaces demi-taille aux deux extrémités (comme _space-around
_), il y a des espaces en taille réelle aux deux extrémités.Cet agencement peut être réalisé avec ::before
et ::after
pseudo-éléments sur le conteneur flex.
(crédit: @ oriol pour le code et @ crl pour l'étiquette)
PDATE: Les navigateurs ont commencé à implémenter space-evenly
, ce qui permet de réaliser ce qui précède. Voir ce post pour plus de détails: Espace égal entre les éléments flexibles
PLAYGROUND (inclut le code pour tous les exemples ci-dessus)
Je sais que ce n’est pas une réponse, mais j’aimerais apporter ma contribution à ce sujet. Ce serait bien s'ils pouvaient publier justify-self
pour flexbox afin de le rendre vraiment flexible.
Je suis convaincu que lorsqu'il y a plusieurs éléments sur l'axe, le moyen le plus logique de se comporter de justify-self
est de s'aligner sur ses voisins les plus proches (ou Edge), comme illustré ci-dessous.
J'espère sincèrement que le W3C en prendra bonne note et l'examinera au moins. =)
De cette façon, vous pouvez avoir un article véritablement centré, quelle que soit la taille des cases gauche et droite. Lorsque l'une des boîtes atteint le point de la boîte centrale, il suffit simplement de la pousser jusqu'à ce qu'il n'y ait plus d'espace à distribuer.
La facilité de création de superbes mises en page est infinie, jetez un coup d'œil à cet exemple "complexe".
Cela a été demandé sur la liste de style www, et Tab Atkins (éditeur de spécifications) a fourni une réponse expliquant pourquoi . Je vais élaborer un peu là-dessus.
Pour commencer, supposons tout d'abord que notre conteneur flex est composé d'une seule ligne (flex-wrap: nowrap
). Dans ce cas, il existe clairement une différence d'alignement entre l'axe principal et l'axe transversal: plusieurs éléments sont empilés dans l'axe principal, mais un seul élément est empilé dans l'axe transversal. Il est donc logique d’avoir un "align-self" personnalisable par élément dans l’axe transversal (puisque chaque élément est aligné séparément), alors qu’il n’a pas de sens dans l’axe principal (car, le les articles sont alignés collectivement).
Pour les flexbox multilignes, la même logique s'applique à chaque "ligne flex". Dans une ligne donnée, les éléments sont alignés individuellement dans l'axe transversal (puisqu'il n'y a qu'un seul élément par ligne, dans l'axe transversal), par opposition à collectivement dans l'axe principal.
Voici une autre façon de le formuler: ainsi, toutes les propriétés des propriétés *-self
et *-content
expliquent comment répartir un espace supplémentaire autour d'objets. Mais la différence principale est que les versions *-self
sont destinées aux cas où ne contient qu'une seule chose dans cet axe , et les versions *-content
sont destinées aux cas où il existe potentiellement beaucoup de choses dans cet axe . Les scénarios "une chose contre plusieurs choses" correspondent à différents types de problèmes. Ils ont donc différents types d'options disponibles. Par exemple, les valeurs space-around
/space-between
ont un sens pour *-content
, mais pas pour *-self
.
SO: Dans l'axe principal d'une flexbox, il y a beaucoup de choses pour répartir l'espace. Donc, une propriété *-content
a un sens ici, mais pas une propriété *-self
.
En revanche, dans l’axe transversal, nous avons à la fois une propriété *-self
et une *-content
. L’un détermine la manière dont nous répartirons l’espace autour des nombreuses lignes flexibles (align-content
), tandis que l’autre (align-self
) détermine la répartition de l’espace individuel éléments flex dans l’axe transversal, au sein d’une même ligne flex.
(J'ignore les propriétés *-items
ici, car elles établissent simplement les valeurs par défaut pour *-self
.)
Je sais que cela n'utilise pas flexbox, mais pour le cas d'utilisation simple de trois éléments (un à gauche, un au centre, un à droite), ceci peut être facilement réalisé en utilisant display: grid
sur le parent, grid-area: 1/1/1/1;
sur les enfants et justify-self
pour le positionnement de ces enfants.
<div style="border: 1px solid red; display: grid; width: 100px; height: 25px;">
<div style="border: 1px solid blue; width: 25px; grid-area: 1/1/1/1; justify-self: left;"></div>
<div style="border: 1px solid blue; width: 25px; grid-area: 1/1/1/1; justify-self: center;"></div>
<div style="border: 1px solid blue; width: 25px; grid-area: 1/1/1/1; justify-self: right;"></div>
</div>
Il y a justify-self
, mais dans Chrome Canary, pas dans Chrome version stable. Il y a même justify-items
:
Mais pour autant que je sache, ces propriétés ne fonctionnent pas non plus. Il est donc probable que Google l’a enregistré à l’avance pour les futures versions CSS. Je ne peux qu’espérer qu’ils ajouteront bientôt les propriétés.