Voici cinq options pour réaliser cette mise en page:
- Positionnement CSS
- Flexbox avec élément DOM invisible
- Flexbox avec pseudo-élément invisible
- Flexbox avec
flex: 1
- Disposition de la grille CSS
Méthode n ° 1: Propriétés de positionnement CSS
Appliquer position: relativesur le conteneur flexible.
Appliquer position: absoluteà l'article D.
Cet élément est désormais positionné de manière absolue dans le conteneur flexible.
Plus spécifiquement, l'élément D est supprimé du flux de documents mais reste dans les limites de l' ancêtre positionné le plus proche .
Utilisez les propriétés de décalage CSS topet rightpour déplacer cet élément en position.
li:last-child {
position: absolute;
top: 0;
right: 0;
background: #ddd;
}
ul {
position: relative;
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
li {
display: flex;
margin: 1px;
padding: 5px;
background: #aaa;
}
p {
text-align: center;
margin-top: 0;
}
span {
background-color: aqua;
}
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>true center</span></p>
Une mise en garde à cette méthode est que certains navigateurs peuvent ne pas supprimer complètement un élément flex positionné de manière absolue du flux normal. Cela modifie l'alignement d'une manière non standard et inattendue. Plus de détails: L'élément flex positionné de manière absolue n'est pas supprimé du flux normal dans IE11
Méthode n ° 2: marges automatiques flexibles et élément flexible invisible (élément DOM)
Avec une combinaison de automarges et un nouvel élément flexible invisible, la mise en page peut être obtenue.
Le nouvel élément flexible est identique à l'élément D et est placé à l'extrémité opposée (le bord gauche).
Plus précisément, étant donné que l'alignement flexible est basé sur la répartition de l'espace libre, le nouvel élément est un contrepoids nécessaire pour maintenir les trois cases du milieu centrées horizontalement. Le nouvel élément doit avoir la même largeur que l'élément D existant, sinon les cases du milieu ne seront pas précisément centrées.
Le nouvel élément est supprimé de la vue avec visibility: hidden.
En bref:
- Créez un double de l'
Délément.
- Placez-le au début de la liste.
- Utilisation fléchir les
automarges pour maintenir A, Bet Ccentrée, avec les deux Déléments créant un équilibre égal des deux extrémités.
- Appliquer
visibility: hiddenau duplicataD
li:first-child {
margin-right: auto;
visibility: hidden;
}
li:last-child {
margin-left: auto;
background: #ddd;
}
ul {
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
li {
display: flex;
margin: 1px;
padding: 5px;
background: #aaa;
}
p { text-align: center; margin-top: 0; }
span { background-color: aqua; }
<ul>
<li>D</li><!-- new; invisible spacer item -->
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>true center</span></p>
Méthode n ° 3: marges automatiques flexibles et élément flexible invisible (pseudo-élément)
Cette méthode est similaire à # 2, sauf qu'elle est plus sémantique et que la largeur de Ddoit être connue.
- Créez un pseudo-élément de même largeur que
D.
- Placez-le au début du conteneur avec
::before.
- Utilisez les
automarges flexibles pour garder A, Bet Cparfaitement centré, le pseudo et les Déléments créant un équilibre égal des deux extrémités.
ul::before {
content:"D";
margin: 1px auto 1px 1px;
visibility: hidden;
padding: 5px;
background: #ddd;
}
li:last-child {
margin-left: auto;
background: #ddd;
}
ul {
padding: 0;
margin: 0;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
li {
display: flex;
margin: 1px;
padding: 5px;
background: #aaa;
}
p { text-align: center; margin-top: 0; }
span { background-color: aqua; }
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>true center</span></p>
Méthode n ° 4: Ajouter flex: 1aux éléments de gauche et de droite
En commençant par la méthode n ° 2 ou n ° 3 ci-dessus, au lieu de vous soucier de la largeur égale des éléments gauche et droit pour maintenir un équilibre égal, donnez simplement chacun flex: 1. Cela les forcera tous les deux à consommer de l'espace disponible, centrant ainsi l'élément du milieu.
Vous pouvez ensuite ajouter display: flexdes éléments individuels afin d'aligner leur contenu.
REMARQUE sur l'utilisation de cette méthode avec min-height: Actuellement dans Chrome, Firefox, Edge et éventuellement d'autres navigateurs, la règle abrégéeflex: 1se résume à ceci:
flex-grow: 1
flex-shrink: 1
flex-basis: 0%
Cette unité de pourcentage (%) sur flex-basisprovoque la rupture de cette méthode lorsqu'elle min-heightest utilisée sur le conteneur. En effet, en règle générale, les hauteurs en pourcentage sur les enfants nécessitent un heightparamètre de propriété explicite sur le parent.
Il s'agit d'une ancienne règle CSS datant de 1998 ( CSS niveau 2 ) qui est toujours en vigueur dans de nombreux navigateurs à un degré ou à un autre. Pour plus de détails, voir ici et ici .
Voici une illustration du problème posté dans les commentaires de user2651804 :
#flex-container {
display: flex;
flex-direction: column;
background: teal;
width: 150px;
min-height: 80vh;
justify-content: space-between;
}
#flex-container>div {
background: orange;
margin: 5px;
}
#flex-container>div:first-child {
flex: 1;
}
#flex-container::after {
content: "";
flex: 1;
}
<div id="flex-container">
<div>very long annoying text that will add on top of the height of its parent</div>
<div>center</div>
</div>
La solution est de ne pas utiliser l'unité de pourcentage. Essayez pxou tout simplement rien du tout ( c'est ce que la spécification recommande en fait , malgré le fait qu'au moins certains des principaux navigateurs ont ajouté une unité de pourcentage pour une raison quelconque).
#flex-container {
display: flex;
flex-direction: column;
background: teal;
width: 150px;
min-height: 80vh;
justify-content: space-between;
}
#flex-container > div {
background: orange;
margin: 5px;
}
/* OVERRIDE THE BROWSER SETTING IN THE FLEX PROPERTY */
#flex-container > div:first-child {
flex: 1;
flex-basis: 0;
}
#flex-container::after {
content: "";
flex: 1;
flex-basis: 0;
}
/* OR... JUST SET THE LONG-HAND PROPERTIES INDIVIDUALLY
#flex-container > div:first-child {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0;
}
#flex-container::after {
content: "";
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0;
}
*/
<div id="flex-container">
<div>very long annoying text that will add on top of the height of its parent</div>
<div>center</div>
</div>
Méthode n ° 5: disposition de la grille CSS
C'est peut-être la méthode la plus propre et la plus efficace. Il n'y a pas besoin de positionnement absolu, de faux éléments ou d'autres piratages.
Créez simplement une grille avec plusieurs colonnes. Positionnez ensuite vos articles dans les colonnes du milieu et de la fin. En gros, laissez simplement la première colonne vide.
ul {
display: grid;
grid-template-columns: 1fr repeat(3, auto) 1fr;
grid-column-gap: 5px;
justify-items: center;
}
li:nth-child(1) { grid-column-start: 2; }
li:nth-child(4) { margin-left: auto; }
/* for demo only */
ul { padding: 0; margin: 0; list-style: none; }
li { padding: 5px; background: #aaa; }
p { text-align: center; }
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
<p><span>| true center |</span></p>