J'ai une div avec deux images et un h1
. Tous doivent être alignés verticalement dans la div, les uns à côté des autres.
Une des images doit être absolute
positionnée dans la div.
Quel est le CSS nécessaire pour que cela fonctionne sur tous les navigateurs courants?
<div id="header">
<img src=".." ></img>
<h1>testing...</h1>
<img src="..."></img>
</div>
Wow, ce problème est populaire. Ceci est basé sur un malentendu dans la propriété vertical-align
. Cet excellent article l'explique:
Comprendre vertical-align
, ou "Comment (pas) centrer verticalement le contenu" par Gavin Kistner.
“Comment centrer en CSS” est un excellent outil web qui permet de trouver les attributs de centrage CSS nécessaires dans différentes situations.
En un mot (et pour empêcher la pourriture du lien):
vertical-align: middle
. Cependant, le "contexte" n’est pas la hauteur totale du conteneur parent, c’est la hauteur de la ligne de texte dans laquelle ils se trouvent. exemple jsfiddleabsolute
et spécifier sa valeur height
, margin-top
et top
position. exemple jsfiddleline-height
du conteneur pour remplir sa hauteur. Cette méthode est assez polyvalente dans mon expérience. exemple jsfiddleMaintenant que le support de flexbox augmente, ce CSS appliqué à l'élément conteneur centrerait verticalement l'élément contenu:
.container {
display: flex;
align-items: center;
}
Utilisez la version préfixée si vous devez également cibler Explorer 10 et les anciens navigateurs (<4.4) Android:
.container {
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-ms-flex-align: center;
-webkit-align-items: center;
-webkit-box-align: center;
align-items: center;
}
J'ai utilisé ce code très simple:
HTML:
<div class="ext-box">
<div class="int-box">
<h2>Some txt</h2>
<p>bla bla bla</p>
</div>
</div>
CSS:
div.ext-box { display: table; width:100%;}
div.int-box { display: table-cell; vertical-align: middle; }
Évidemment, que vous utilisiez un .class
ou un #id
, le résultat ne changera pas.
Cela a fonctionné pour moi:
.vcontainer {
min-height: 10em;
display: table-cell;
vertical-align: middle;
}
.outer {
display: flex;
align-items: center;
justify-content: center;
}
Une technique d'un de mes amis:
HTML:
<div style="height:100px; border:1px solid;">
<p style="border:1px dotted;">I'm vertically centered.</p>
</div>
CSS:
div:before {content:" "; display:inline-block; height:100%; vertical-align:middle;}
div p {display:inline-block;}
DÉMO ici
Pour positionner les éléments de bloc au centre (fonctionne à partir de IE9 et supérieur), il faut un wrapper div
:
.vcontainer {
position: relative;
top: 50%;
transform: translateY(-50%);
-webkit-transform: translateY(-50%);
}
Tous doivent être alignés verticalement dans la div
Aligné comment ? Le dessus des images est-il aligné sur le haut du texte?
Une des images doit être positionnée de manière absolue dans la div.
Absolument positionné par rapport à la DIV? Peut-être pourriez-vous esquisser ce que vous cherchez ...?
fd a décrit les étapes pour le positionnement absolu, ainsi que pour ajuster l’affichage de l’élément H1
de manière à ce que les images apparaissent en même temps que lui. A cela, j'ajouterai que vous pouvez aligner les images en utilisant le style vertical-align
:
#header h1 { display: inline; }
#header img { vertical-align: middle; }
... cela mettrait l'en-tête et les images ensemble, avec les bords supérieurs alignés. D'autres options d'alignement existent. voir la documentation . Vous pouvez également trouver avantageux de supprimer la DIV et de déplacer les images à l'intérieur de l'élément H1
- cela donne une valeur sémantique au conteneur et vous évite d'avoir à ajuster l'affichage du H1
:
<h1 id=header">
<img src=".." ></img>
testing...
<img src="..."></img>
</h1>
Utilisez cette formule, et cela fonctionnera toujours sans fissures:
#outer {height: 400px; overflow: hidden; position: relative;}
#outer[id] {display: table; position: static;}
#middle {position: absolute; top: 50%;} /* For Explorer only*/
#middle[id] {display: table-cell; vertical-align: middle; width: 100%;}
#inner {position: relative; top: -50%} /* For Explorer only */
/* Optional: #inner[id] {position: static;} */
<div id="outer">
<div id="middle">
<div id="inner">
any text
any height
any content, for example generated from DB
everything is vertically centered
</div>
</div>
</div>
Presque toutes les méthodes doivent spécifier la hauteur, mais souvent nous n’avons aucune hauteur.
Voici donc une astuce CSS3 en 3 lignes qui ne nécessite pas de connaître la hauteur.
.element {
position: relative;
top: 50%;
transform: translateY(-50%);
}
Il est pris en charge même dans IE9.
avec ses préfixes de vendeurs:
.element {
position: relative;
top: 50%;
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
}
Source: http://zerosixthree.se/vertical-align-anything-with-just-3-lines-of-css/
Mon astuce consiste à insérer dans la div une table avec 1 ligne et 1 colonne, de définir 100% de la largeur et de la hauteur, ainsi que la propriété vertical-align: middle.
<div>
<table style="width:100%; height:100%;">
<tr>
<td style="vertical-align:middle;">
BUTTON TEXT
</td>
</tr>
</table>
</div>
pour alignement vertical: d-flex align-items-center
pour alignement horizontal: d-flex justify-content-center
.container {
height: 180px;
width:100%;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
rel="stylesheet"/>
<div class="d-flex align-items-center justify-content-center bg-info container">
<div class="bg-light p-2">I am in Center</div>
</div>
.container {
display: flex;
align-items: center;
justify-content: center;
background-color: #17a2b8;
height: 180px;
width:100%;
}
.child {
background-color: #f8f9fa;
padding: 0.5rem;
}
<div class="container">
<div class="child">I am in Center</div>
</div>
Aujourd'hui, j'ai trouvé une nouvelle solution permettant d'aligner verticalement plusieurs lignes de texte dans une div à l'aide de CSS3 (et j'utilise également le système de grille bootstrap v3 pour embellir l'interface utilisateur), comme suit:
.immediate-parent-of-text-containing-div{
height: 50px; /* or any fixed height that suits you.*/
}
.text-containing-div {
display: inline-grid;
align-items: center;
text-align: center;
height: 100%;
}
Selon ma compréhension, le parent immédiat d'un élément contenant du texte doit avoir une certaine hauteur. J'espère que cela vous aidera aussi. Merci!
Nous pouvons utiliser un calcul de fonction CSS pour calculer la taille de l'élément, puis positionner l'élément enfant en conséquence.
Exemple HTML:
<div class="box">
<span><a href="#">Some Text</a></span>
</div>
Et CSS:
.box {
display: block;
background: #60D3E8;
position: relative;
width: 300px;
height: 200px;
text-align: center;
}
.box span {
font: bold 20px/20px 'source code pro', sans-serif;
position: absolute;
left: 0;
right: 0;
top: calc(50% - 10px);
}
a {
color: white;
text-decoration: none;
}
Démo créée ici: https://jsfiddle.net/xnjq1t22/
Cette solution fonctionne bien avec div
height
et width
sensibles également.
Remarque: La compatibilité de la fonction de calcul avec les anciens navigateurs n’est pas testée.
Par défaut, h1 est un élément de bloc et restituera la ligne après la première img et fera en sorte que la seconde img apparaisse sur la ligne suivant le bloc.
Pour que cela ne se produise plus, vous pouvez paramétrer le comportement h1 du flux h1:
#header > h1 { display: inline; }
En ce qui concerne le positionnement absolu de l'img à l'intérieur du div , vous devez définir le div qui le contient pour qu'il ait une "taille connue" avant que cela fonctionne correctement. D'après mon expérience, vous devez également modifier l'attribut position de la position par défaut - position: le relatif fonctionne pour moi:
#header { position: relative; width: 20em; height: 20em; }
#img-for-abs-positioning { position: absolute; top: 0; left: 0; }
Si vous voulez que cela fonctionne, essayez d’enlever progressivement les attributs height, width, position de div.header pour obtenir les attributs minimaux requis pour obtenir l’effet souhaité.
PDATE:
Voici un exemple complet qui fonctionne sur Firefox 3:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Example of vertical positioning inside a div</title>
<style type="text/css">
#header > h1 { display: inline; }
#header { border: solid 1px red;
position: relative; }
#img-for-abs-positioning { position: absolute;
bottom: -1em; right: 2em; }
</style>
</head>
<body>
<div id="header">
<img src="#" alt="Image 1" width="40" height="40" />
<h1>Header</h1>
<img src="#" alt="Image 2" width="40" height="40"
id="img-for-abs-positioning" />
</div>
</body>
</html>
En utilisant CSS pour centrer verticalement, vous pouvez laisser les conteneurs extérieurs agir comme un tableau et le contenu comme une cellule de tableau. Dans ce format, vos objets resteront centrés. :)
J'ai imbriqué plusieurs objets dans JSFiddle pour un exemple, mais l'idée principale est la suivante:
HTML
<div class="circle">
<div class="content">
Some text
</div>
</div>
CSS
.circle {
/* act as a table so we can center vertically its child */
display: table;
/* set dimensions */
height: 200px;
width: 200px;
/* horizontal center text */
text-align: center;
/* create a red circle */
border-radius: 100%;
background: red;
}
.content {
/* act as a table cell */
display: table-cell;
/* and now we can vertically center! */
vertical-align: middle;
/* some basic markup */
font-size: 30px;
font-weight: bold;
color: white;
}
L'exemple des objets multiples:
HTML
<div class="container">
<div class="content">
<div class="centerhoriz">
<div class="circle">
<div class="content">
Some text
</div><!-- content -->
</div><!-- circle -->
<div class="square">
<div class="content">
<div id="smallcircle"></div>
</div><!-- content -->
</div><!-- square -->
</div><!-- center-horiz -->
</div><!-- content -->
</div><!-- container -->
CSS
.container {
display: table;
height: 500px;
width: 300px;
text-align: center;
background: lightblue;
}
.centerhoriz {
display: inline-block;
}
.circle {
display: table;
height: 200px;
width: 200px;
text-align: center;
background: red;
border-radius: 100%;
margin: 10px;
}
.square {
display: table;
height: 200px;
width: 200px;
text-align: center;
background: blue;
margin: 10px;
}
.content {
display: table-cell;
vertical-align: middle;
font-size: 30px;
font-weight: bold;
color: white;
}
#smallcircle {
display: inline-block;
height: 50px;
width: 50px;
background: green;
border-radius: 100%;
}
Résultat
Ma nouvelle façon préférée de le faire est avec une grille CSS:
/* technique */
.wrapper {
display: inline-grid;
grid-auto-flow: column;
align-items: center;
justify-content: center;
}
/* visual emphasis */
.wrapper {
border: 1px solid red;
height: 180px;
width: 400px;
}
img {
width: 100px;
height: 80px;
background: #fafafa;
}
img:nth-child(2) {
height: 120px;
}
<div class="wrapper">
<img src="https://source.unsplash.com/random/100x80/?bear">
<img src="https://source.unsplash.com/random/100x120/?lion">
<img src="https://source.unsplash.com/random/100x80/?tiger">
</div>
Utilisez simplement une table à une cellule à l’intérieur du div! Il suffit de définir la hauteur de la cellule et de la table ainsi que 100% et vous pouvez utiliser l'alignement vertical.
Un tableau à une cellule à l'intérieur de la div gère l'alignement vertical et est rétrocompatible avec l'âge de pierre!
Pour moi, ça a fonctionné comme ça:
<div style="width:70px; height:68px; float:right; display: table-cell; line-height: 68px">
<a href="javascript:void(0)" style="margin-left: 4px; line-height: 2" class="btn btn-primary">Login</a>
</div>
L'élément "a" converti en bouton, à l'aide de Bootstrap classes, est désormais centré verticalement à l'intérieur d'un "div" extérieur.
C’est ma solution personnelle pour un élément i dans un div
<div class="circle">
<i class="fa fa-plus icon">
</i></div>
.circle {
border-radius: 50%;
color: blue;
background-color: red;
height:100px;
width:100px;
text-align: center;
line-height: 100px;
}
.icon {
font-size: 50px;
vertical-align: middle;
}
# 3 façons de rendre le centre enfant div en parent div
Méthode de transformation/traduction
/* 1st way */
.parent1 {
background: darkcyan;
width: 200px;
height: 200px;
position: relative;
}
.child1 {
background: white;
height: 30px;
width: 30px;
position: absolute;
top: 50%;
left: 50%;
margin: -15px;
}
/* 2nd way */
.parent2 {
display: flex;
justify-content: center;
align-items: center;
background: darkcyan;
height: 200px;
width: 200px;
}
.child2 {
background: white;
height: 30px;
width: 30px;
}
/* 3rd way */
.parent3 {
position: relative;
height: 200px;
width: 200px;
background: darkcyan;
}
.child3 {
background: white;
height: 30px;
width: 30px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
<div class="parent1">
<div class="child1"></div>
</div>
<hr />
<div class="parent2">
<div class="child2"></div>
</div>
<hr />
<div class="parent3">
<div class="child3"></div>
</div>
J'utilise la solution suivante (sans positionnement ni hauteur de ligne) depuis plus d'un an, elle fonctionne également avec IE 7 et 8.
<style>
.outer {
font-size: 0;
width: 400px;
height: 400px;
background: orange;
text-align: center;
display: inline-block;
}
.outer .emptyDiv {
height: 100%;
background: orange;
visibility: collapse;
}
.outer .inner {
padding: 10px;
background: red;
font: bold 12px Arial;
}
.verticalCenter {
display: inline-block;
*display: inline;
zoom: 1;
vertical-align: middle;
}
</style>
<div class="outer">
<div class="emptyDiv verticalCenter"></div>
<div class="inner verticalCenter">
<p>Line 1</p>
<p>Line 2</p>
</div>
</div>