Centre et bas-alignent les éléments flex
j'ai un conteneur souple (le carré bleu) avec les propriétés suivantes:
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
par conséquent, ses enfants (les carrés bleu clair) s'organisent comme vous voyez ci-dessous. Cependant, j'aimerais ajouter un autre enfant (le carré vert) hors du flux normal et le positionner par rapport à son parent. Pour le positionner comme vous le voyez ci-dessous, j'écrirais idéalement quelque chose comme bottom: 20px;
et margin: auto;
.
j'ai essayé de jouer avec z-index
en vain. Comment devrais-je m'approche de cela? Dois-je recourir à la création d'un autre élément parent?
3 réponses
on trouvera ci-dessous cinq options pour réaliser cette disposition:
- Positionnement CSS
- Flexbox avec élément DOM Invisible
- Flexbox avec un Pseudo-élément Invisible
- Flexbox avec
flex: 1
- Grille CSS de Mise en page
méthode no 1: Propriétés de positionnement CSS
appliquer position: relative
au conteneur souple.
Appliquer position: absolute
au vert flex élément.
maintenant le carré vert est absolument positionné dans le conteneur flex.
plus précisément, le carré vert est retiré du flux de documents mais reste dans les limites du ancêtre le plus proche positionné .
utiliser les propriétés d'offset CSS top
, bottom
, left
et right
pour déplacer le carré vert autour.
flex-container {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
position: relative;
border: 4px solid blue;
height: 300px;
width: 300px;
}
flex-container > flex-item:first-child {
display: flex;
}
flex-container > flex-item:first-child > flex-item {
border: 4px solid aqua;
height: 50px;
width: 50px;
margin: 0 5px;
}
flex-container > flex-item:last-child {
position: absolute;
bottom: 40px;
left: 50%;
transform: translateX(-50%); /* fine tune horizontal centering */
border: 4px solid chartreuse;
height: 50px;
width: 50px;
}
<flex-container>
<flex-item><!-- also flex container -->
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</flex-item>
<flex-item></flex-item>
</flex-container>
une mise en garde: certains navigateurs peuvent ne pas supprimer complètement un élément flex positionné absolument du flux normal. Cela change l'alignement d'une manière non standard et inattendue. Plus de détails: absolument l'article flex positionné N'est pas retiré de l'écoulement normal en Firefox & IE11
Méthode #2: Flex Auto Margins & Invisible Flex Item (DOM element)
avec une combinaison de auto
marges et un nouvel élément flex invisible la mise en page peut être réalisée.
le nouvel article flex est identique à l'article du bas et est placé à l'extrémité opposée (le haut).
plus spécifiquement, parce que l'alignement flex est basé sur la distribution de l'espace libre, le nouvel article est un contrepoids nécessaire pour garder les trois boîtes bleues verticalement centrées. Le nouvel article doit avoir la même hauteur que l'article Vert existant, sinon les boîtes bleues ne seront pas exactement centrées.
le nouvel article est supprimé de la vue avec visibility: hidden
.
en bref:
- boîte verte.
- le Placer au début de la liste.
- utilisez flex
auto
marges pour garder les boîtes bleues centrées, avec les deux boîtes vertes créant l'équilibre égal des deux extrémités. - appliquer
visibility: hidden
à la boîte verte en double.
flex-container {
display: flex;
flex-direction: column;
align-items: center;
border: 4px solid blue;
height: 300px;
width: 300px;
}
flex-container > flex-item:first-child {
margin-top: auto;
visibility: hidden;
}
flex-container > flex-item:nth-child(2) {
margin-top: auto;
display: flex;
}
flex-container > flex-item:last-child {
margin-top: auto;
margin-bottom: auto;
}
flex-container > flex-item:first-child,
flex-container > flex-item:last-child {
border: 4px solid chartreuse;
height: 50px;
width: 50px;
}
flex-container > flex-item:nth-child(2) > flex-item {
border: 4px solid aqua;
height: 50px;
width: 50px;
margin: 0 5px;
}
<flex-container>
<flex-item></flex-item>
<flex-item><!-- also flex container -->
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</flex-item>
<flex-item></flex-item>
</flex-container>
Méthode #3: Flex Auto Margins & Invisible Flex Item (pseudo-élément)
cette méthode est similaire à la méthode #2, sauf qu'elle est plus propre sur le plan sémantique et que la hauteur de la boîte verte doit être connue.
- créer un pseudo-élément avec la même hauteur que la boîte verte existante.
- le placer au début du conteneur avec
::before
. - utilisez flex
auto
marges pour garder les boîtes bleues centrées, avec les éléments verts pseudo et DOM créer un équilibre égal des deux côtés.
flex-container {
display: flex;
flex-direction: column;
align-items: center;
border: 4px solid blue;
height: 300px;
width: 300px;
}
flex-container::before {
content: "";
margin-top: auto;
height: calc(50px + 8px); /* height + borders */
visibility: hidden;
}
flex-container > flex-item:first-child {
margin-top: auto;
display: flex;
}
flex-container > flex-item:last-child {
margin-top: auto;
margin-bottom: auto;
border: 4px solid chartreuse;
height: 50px;
width: 50px;
}
flex-container > flex-item:first-child > flex-item {
border: 4px solid aqua;
height: 50px;
width: 50px;
margin: 0 5px;
}
<flex-container>
<flex-item><!-- also flex container -->
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</flex-item>
<flex-item></flex-item>
</flex-container>
méthode No 4: Ajouter flex: 1
aux éléments supérieurs et inférieurs
en commençant par la méthode #2 ou #3 ci-dessus, au lieu de s'inquiéter d'une hauteur égale pour les éléments supérieurs et inférieurs pour maintenir un équilibre égal, il suffit de donner à chacun flex: 1
. Cela les forcera tous les deux à consommer l'espace disponible, centrant ainsi le milieu article.
vous pouvez alors ajouter display: flex
à l'article du bas afin d'aligner le contenu.
méthode no 5: disposition de la grille CSS
C'est peut-être le plus propre et la plus efficace. Il n'y a pas besoin de positionnement absolu, de faux éléments ou d'autres hackery.
il suffit de créer une grille avec trois lignes. Le centre-aligner les éléments dans les deuxième et troisième rangées. La première ligne peut rester vide.
grid-container {
display: grid;
grid-template-rows: repeat(3, 1fr);
align-items: center;
justify-items: center;
border: 4px solid blue;
height: 300px;
width: 300px;
}
grid-item:nth-child(2) {
display: flex;
}
grid-item:nth-child(2)>flex-item {
width: 50px;
height: 50px;
margin: 0 5px;
border: 4px solid aqua;
}
grid-item:nth-child(3) {
border: 4px solid chartreuse;
height: 50px;
width: 50px;
}
<grid-container>
<grid-item></grid-item>
<grid-item><!-- also flex container -->
<flex-item></flex-item>
<flex-item></flex-item>
<flex-item></flex-item>
</grid-item>
<grid-item></grid-item>
</grid-container>
laisser le conteneur avec position: relative
et le carré vert avec position:absolute;
body {
margin: 0;
}
#container {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
width: 192px;
height: 192px;
border: 4px solid indigo;
position: relative;
background: lavender;
}
.blue {
margin: 10px;
width: 30px;
height: 30px;
outline: 4px solid skyblue;
background: honeydew;
}
#green {
position: absolute;
width: 30px;
height: 30px;
left: 0;
right: 0;
margin: auto;
bottom: 20px;
outline: 4px solid yellowgreen;
background: greenyellow;
}
<div id=container>
<div class=blue></div><div class=blue></div><div class=blue></div>
<div id=green></div>
</div>
vous pouvez utiliser un pseudo pour se déplacer vers le bas d'une rangée les trois premiers conteneurs puis appliquer un margin:auto
à la dernière
div {
display:flex;
flex-wrap:wrap;
border:#0066FD solid;;
width:200px;
height:200px;
justify-content:space-around;
/* show me box center */
background:linear-gradient(to top,rgba(0,0,0,0.2) 50%, transparent 50%),linear-gradient(to left,rgba(0,0,0,0.2) 50%, transparent 50%)
}
span, div:before {
width:50px;
height:50px;
border:solid #01CDFF;
margin:0 auto 0;
}
span:last-of-type , div:before{
margin: 12px auto;
border:solid #01FE43;
}
div:before {
content:'';
width:100%;
border:none;
}
span {
/* show me box center */
background:linear-gradient(45deg,rgba(0,0,0,0.1) 50%, transparent 50%),linear-gradient(-45deg,rgba(0,0,0,0.1) 50%, transparent 50%)
}
<div>
<span></span>
<span></span>
<span></span>
<span></span>
</div>