Je centre un DIV à l'intérieur d'un autre DIV à l'aide d'un flexbox. Pensez à une fenêtre de dialogue qui apparaît au centre de l'écran en cas de besoin.
Cela fonctionne bien, mais il serait beaucoup mieux si l'espace au-dessus et en dessous de la boîte de dialogue n'était pas exactement égal, avec 40% de l'espace restant au-dessus et 60% en dessous de la boîte de dialogue. Cela devient délicat car la hauteur de la boîte de dialogue varie avec la quantité de texte à l'intérieur.
Ainsi, par exemple, si la hauteur du navigateur est de 1000 px et la hauteur de la fenêtre de dialogue est de 400 px, je veux que l'espace vertical restant (600 px) soit 240 px au-dessus et 360 px en dessous de la boîte de dialogue. Je pourrais le faire avec Javascript, mais je suis curieux de savoir s'il existe un moyen intelligent avec CSS. J'ai essayé d'ajouter une marge inférieure à la DIV #dialogBox, mais cela ne fonctionne pas lorsque la hauteur de la boîte de dialogue approche de la hauteur du navigateur.
#dialogBoxPanel
{
position:absolute;
display:flex;
align-items:center;
justify-content:center;
left:0px;
top:0px;
width:100%;
height:100%;
}
#dialogBox
{
width:350px;
}
<div id="dialogBoxPanel">
<div id="dialogBox">Text</div>
</div>
Utilisez le pseudo-élément et la direction de la colonne pour simuler l'espace blanc. Ajustez simplement le flex-grow
du pseudo-élément pour contrôler la quantité d'espace libre que chacun devrait prendre. Une flex-grow égale donnera un espace égal:
#dialogBoxPanel {
position: absolute;
display: flex;
flex-direction: column;
align-items: center;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
/* the center */
background:linear-gradient(red,red) center/100% 1px no-repeat;
}
#dialogBox {
width: 350px;
border:1px solid;
}
#dialogBoxPanel:before {
content:"";
flex-grow:4;
}
#dialogBoxPanel:after {
content:"";
flex-grow:6;
}
<div id="dialogBoxPanel">
<div id="dialogBox">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc hendrerit diam eu nisl fringilla ornare. Pellentesque aliquam quam et tellus egestas sodales. Interdum et malesuada fames ac ante ipsum primis in faucibus. Proin bibendum,</div>
</div>
Vous pouvez aussi utiliser 2
et 3
. Nous devons simplement garder le même ratio:
#dialogBoxPanel {
position: absolute;
display: flex;
flex-direction: column;
align-items: center;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
/* the center */
background:linear-gradient(red,red) center/100% 1px no-repeat;
}
#dialogBox {
width: 350px;
border:1px solid;
}
#dialogBoxPanel:before {
content:"";
flex-grow:2;
}
#dialogBoxPanel:after {
content:"";
flex-grow:3;
}
<div id="dialogBoxPanel">
<div id="dialogBox">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc hendrerit diam eu nisl fringilla ornare. Pellentesque aliquam quam et tellus egestas sodales. Interdum et malesuada fames ac ante ipsum primis in faucibus. Proin bibendum,</div>
</div>
Une autre idée consiste à utiliser une valeur supérieure égale à 40%
et rectifier la position avec translate (même logique avec le 50%
lors du centrage)
#dialogBoxPanel {
position: absolute;;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
/* the center */
background:linear-gradient(red,red) center/100% 1px no-repeat;
}
#dialogBox {
position:relative;
top:40%;
width: 350px;
transform:translateY(-40%);
margin:auto;
border:1px solid;
}
<div id="dialogBoxPanel">
<div id="dialogBox">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc hendrerit diam eu nisl fringilla ornare. Pellentesque aliquam quam et tellus egestas sodales. Interdum et malesuada fames ac ante ipsum primis in faucibus. Proin bibendum,</div>
</div>
Cette solution utilise display: grid
, c'est une nouvelle fonctionnalité alors assurez-vous de vérifier les support du navigateur et cliquez ici pour en savoir plus.
C'est la ligne qui contrôle les espaces supérieurs et inférieurs:
grid-template-rows: 40fr [content-start] auto [content-end] 60fr;
Le contenu du texte d'extrait peut être modifié pour que vous puissiez vérifier que la case reste centrée même si la hauteur change.
#dialogBoxPanel {
display: grid;
place-content: center;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
grid-template-rows: 40fr [content-start] auto [content-end] 60fr;
}
#dialogBox {
border: 1px solid;
width: 350px;
grid-area: content;
}
<div id="dialogBoxPanel">
<div id="dialogBox" contenteditable>Text</div>
</div>
Vous pouvez ajouter des diviseurs d'espacement et définir la flex-croissance avec un rapport 4: 6.
#dialogBoxPanel {
position: absolute;
display: flex;
flex-direction: column;
align-items: center;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
}
#dialogBox {
width: 350px;
border: 1px solid black;
}
.spacer-top{
flex-grow: 4;
}
.spacer-bottom{
flex-grow: 6;
<div id="dialogBoxPanel">
<div class="spacer-top"></div>
<div id="dialogBox">Text</div>
<div class="spacer-bottom"></div>
</div>
De manière simple en utilisant la position et la marge, j'ai supposé que la hauteur de votre dialogue était toujours de 40% de la hauteur du navigateur.
.modal{
max-height:50%;
width:400px;
margin: 10% auto 5% auto;
position:absolute;
top:0;
bottom:0;
right:0;
left:0;
overflow-y: auto
}
.modal-body{
background-color: beige;
padding: 20px;
line-height: 21px
}
HTML
<div class="modal">
<div class="modal-body">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea </div>
</div>