Comment définir la marge ou le rembourrage en pourcentage de la hauteur du conteneur parent?

j'avais creusé mon cerveau pour créer un alignement vertical dans css en utilisant le suivant

.base{
    background-color:green;
    width:200px;
    height:200px;
    overflow:auto;
    position:relative;
}

.vert-align{
    padding-top:50%;
    height:50%;
}

et utilisé la structure de div suivante.

<div class="base">
   <div class="vert-align">
       Content Here
   </div>
</div>

Alors que cela semblait fonctionner pour ce cas, j'ai été surpris quand j'ai augmenté ou diminué la largeur de mon div, l'alignement vertical allait se casser. Je m'attendais à ce que lorsque j'ai mis la propriété de rembourrage-dessus, il prendrait le rembourrage en pourcentage de la hauteur de le conteneur parent, qui est de base dans notre cas, mais la valeur ci-dessus de 50 pour cent est calculé comme un pourcentage de la largeur. : (

y a-t-il un moyen de régler le rembourrage et/ou la marge en pourcentage de la hauteur, sans recourir à JavaScript?

180
demandé sur TylerH 2011-02-13 07:49:30
la source

7 ответов

j'ai aussi eu ce problème (+1). Je suis sérieusement ennuyé par ça, c'est stupide d'avoir à faire ça.

le point fixe est que oui, le rembourrage vertical et la marge sont relatifs à la largeur, mais top et bottom ne le sont pas.

il suffit donc de placer une div à l'intérieur d'une autre, et dans la div interne, utilisez quelque chose comme top:50% (rappelez-vous position questions si elle ne fonctionne toujours pas)

186
répondu Camilo Martin 2012-04-05 00:03:31
la source

voici deux options pour émuler le comportement nécessaire. Pas une solution, mais peut aider dans certains cas. L'espacement vertical est calculée sur la base de la taille de l'élément extérieur, pas sa mère, mais cette taille peut être lui-même par rapport à la société mère et de cette façon, l'espacement sera relative.

<div id="outer">
    <div id="inner">
        content
    </div>
</div>

première option: Utiliser des pseudo-éléments, ici l'espacement vertical et horizontal est relatif à l'extérieur. Démo

#outer::before, #outer::after {
    display: block;
    content: "";
    height: 10%;
}
#inner {
    height: 80%;
    margin-left: 10%;
    margin-right: 10%;
}

le déplacement de l'espacement horizontal vers l'élément extérieur le rend relatif au parent de l'élément extérieur. Démo

#outer {
    padding-left: 10%;
    padding-right: 10%;
}

deuxième option: Utiliser le positionnement absolu. Démo

#outer {
    position: relative;
}
#inner {
    position: absolute;
    left: 10%;
    right: 10%;
    top: 10%;
    bottom: 10%;
}
28
répondu user 2016-10-02 01:29:58
la source

une réponse à une question légèrement différente: vous pouvez utiliser des unités vh pour coller des éléments au centre du viewport :

.centerme {
    margin-top: 50vh;
    background: red;
}

<div class="centerme">middle</div>
27
répondu willoller 2015-10-08 21:47:46
la source

pour rendre l'élément enfant positionné absolument à partir de son élément parent, vous devez définir la position relative sur l'élément parent et la position absolue sur l'élément enfant.

puis sur l'élément enfant "top" est relatif à la hauteur du parent. Vous devez donc également "traduire" vers le haut l'enfant 50% de sa propre taille.

.base{
    background-color: green;
    width: 200px;
    height: 200px;
    overflow: auto;
    position: relative;
}
    
.vert-align {
    position: absolute;
    top: 50%;
    transform: translate(0, -50%);
}
    <div class="base">
        <div class="vert-align">
            Content Here
        </div>
    </div>

Il ya une autre solution en utilisant flex box.

.base{
    background-color:green;
    width: 200px;
    height: 200px;
    overflow: auto;
    display: flex;
    align-items: center;
}
<div class="base">
    <div class="vert-align">
        Content Here
    </div>
</div>

vous trouverez des avantages/désavantages pour les deux.

5
répondu alain 2016-02-05 06:29:58
la source

autre façon de centrer le texte d'une ligne est:

.parent{
  position: relative;
}

.child{
   position: absolute;
   top: 50%;
   line-height: 0;
}

ou juste

.parent{
  overflow: hidden; /* if this ins't here the parent will adopt the 50% margin of the child */
}

.child{
   margin-top: 50%;
   line-height: 0;
}
3
répondu rawiro 2014-05-25 10:44:50
la source

un 50% rembourrage wont center votre enfant, il le placera en dessous du centre. Je pense que tu veux vraiment un dessus de rembourrage de 25%. Peut-être que vous êtes à court d'espace alors que votre contenu devient plus grand? Avez-vous aussi essayé de régler la marge-top au lieu de padding-top?

EDIT: Nevermind, le site w3schools dit

% indique le rembourrage en pourcentage de la largeur de l'élément contenant

So peut-être qu'il utilise toujours la largeur? Je n'avais jamais remarqué.

ce que vous faites peut être atteint en utilisant display:table Cependant (au moins pour les navigateurs modernes). la technique est expliquée ici .

1
répondu SpliFF 2011-02-13 08:23:40
la source

c'est un bug très intéressant. (À mon avis, c'est un bug de toute façon), Belle trouvaille!

concernant comment pour le régler, je recommande la réponse de Camilo Martin. Mais pour ce qui est de pourquoi , j'aimerais vous expliquer un peu si ça ne vous dérange pas.


Dans le CSS specs j'ai trouvé:

"padding"

pourcentages: se référer à la largeur du bloc contenant

... ce qui est bizarre, mais bon.

ainsi, avec un parent width: 210px et un enfant padding-top: 50% , j'obtiens une valeur calculée/calculée de padding-top: 96.5px – qui n'est pas la valeur attendue 105px .

qui est parce que dans Windows (Je ne suis pas sûr d'autres OSs), la taille des barres de défilement commune est par par défaut 17px × 100% (ou 100% × 17px pour les barres horizontales). Ces 17px sont soustraites avant calculant le 50% , donc 50% of 193px = 96.5px .

0
répondu WoodrowShigeru 2018-04-08 14:22:11
la source

Autres questions sur html css vertical-alignment