web-dev-qa-db-fra.com

Positionnement absolu en ignorant le remplissage du parent

Comment faire en sorte qu'un élément en position absolue respecte le rembourrage de son parent? Je souhaite qu'une div interne s'étende sur toute la largeur de son parent et soit placée au bas de ce dernier, essentiellement un pied de page. Mais l'enfant doit respecter le rembourrage du parent et ne le fait pas. L'enfant est pressé contre le bord du parent.

Donc je veux ceci:

enter image description here

mais j'obtiens ceci:

enter image description here

<html>
  <body>
    <div style="background-color: blue; padding: 10px; position: relative; height: 100px;">
      <div style="background-color: gray; position: absolute; left: 0px; right: 0px; bottom: 0px;">css sux</div>
    </div>
  </body>
</html>

Je peux y arriver avec une marge autour de la division intérieure, mais je préférerais ne pas avoir à ajouter cela.

138
d512

Voyons tout d'abord pourquoi cela se produit.

La raison en est que, de manière surprenante, quand une boîte a position: absolute sa boîte contenant est la boîte de remplissage du parent (c’est-à-dire la boîte autour de son remplissage). Ceci est surprenant parce que généralement (c’est-à-dire lorsqu’on utilise un positionnement statique ou relatif), la zone qui la contient est la zone content du parent.

Voici le partie pertinente de la spécification CSS :

Dans le cas où l'ancêtre est un élément en ligne, le bloc conteneur est le cadre de sélection entourant les zones de remplissage des première et dernière boîtes en ligne générées pour cet élément .... Sinon, le bloc contenant est formé par le bord de remplissage de l'ancêtre.

L'approche la plus simple - comme suggéré dans la réponse de Winter - consiste à utiliser padding: inherit sur la position absolue div. Cependant, cela ne fonctionne que si vous ne voulez pas que div, position absolue, ait un remplissage supplémentaire. Je pense que les solutions les plus générales (dans la mesure où les deux éléments peuvent avoir leur propre remplissage indépendant) sont les suivantes:

  1. Ajoutez une div relativement positionnée (sans rembourrage) autour de la div absolument positionnée. Cette nouvelle div respectera le rembourrage de son parent et la div en position absolue le remplira ensuite.

    L'inconvénient, bien sûr, est que vous manipulez le HTML simplement à des fins de présentation.

  2. Répétez le remplissage (ou ajoutez-le) sur l'élément en position absolue.

    L'inconvénient est que vous devez répéter les valeurs dans votre CSS, ce qui est fragile si vous écrivez le CSS directement. Toutefois, si vous utilisez un outil de prétraitement tel que SASS ou LESS, vous pouvez éviter ce problème en utilisant une variable. C'est la méthode que j'utilise personnellement.

147

Une chose que vous pourriez essayer utilise le css suivant:

.child-element {
    padding-left: inherit;
    padding-right: inherit;
    position: absolute;
    left: 0;
    right: 0;
}

Il laisse l’élément enfant hériter du padding du parent, puis l’enfant peut être positionné pour correspondre à la largeur et au padding des parents.

De plus, j'utilise box-sizing: border-box; pour les éléments impliqués.

Je n'ai pas testé cela dans tous les navigateurs, mais il semble fonctionner sous Chrome, Firefox et IE10. 

42
Winter

Eh bien, ce n'est peut-être pas la solution la plus élégante (sémantiquement), mais dans certains cas, cela fonctionnera sans aucun inconvénient: au lieu de remplir, utilisez une bordure transparente sur l'élément parent. Les éléments enfants à positionnement absolu respecteront la bordure et le rendu sera identique (sauf que vous utilisez la bordure de l'élément parent pour le style).

28
NewSpender

Utilisez margin au lieu de remplir dans la division parent: http://blog.vjeux.com/2012/css/css-absolute-position-taking-into-account-padding.html

6
Niloct

Voici mon meilleur coup pour ça. J'ai ajouté une autre Div, je l'ai mise en rouge et j'ai changé la taille de votre parent à 200px pour le tester. L'idée est que l'enfant devient maintenant le petit-enfant et le parent devient le grand-parent. Donc, le parent respecte son parent. J'espère que vous avez mon idée.

<html>
  <body>
    <div style="background-color: blue; padding: 10px; position: relative; height: 200px;">
     <div style="background-color: red;  position: relative; height: 100%;">    
        <div style="background-color: gray; position: absolute; left: 0px; right: 0px;bottom: 0px;">css sux</div>
     </div>
    </div>
  </body>
</html>

Modifier:

Je pense que ce que vous essayez de faire ne peut pas être fait. La position absolue signifie que vous allez lui donner des coordonnées qu’elle doit honorer. Et si le parent a un padding de 5px. Et vous placez absolument l'enfant à top: -5px; gauche: -5px . Comment est-il supposé honorer le parent et vous en même temps ??

Ma solution

Si vous voulez qu'il honore le parent, ne le placez pas absolument alors.

5
Touch

1.) vous ne pouvez pas utiliser une grande bordure sur le parent - si vous voulez avoir une bordure spécifique 

2.) Vous ne pouvez pas ajouter de marge - dans le cas où votre parent fait partie d’un autre conteneur et que vous voulez que votre parent prenne toute la largeur de ce grand parent.

La seule solution qui devrait être applicable consiste à emballer vos enfants dans un autre conteneur afin que votre parent devienne le grand-parent, puis à appliquer un rembourrage au nouveau parent/wrapper de l'enfant. Ou vous pouvez appliquer directement un rembourrage aux enfants.

Dans ton cas:

.css-sux{
  padding: 0px 10px 10px 10px;
}
2
bhavya_w

Aurait pu facilement faire en utilisant un niveau supplémentaire de Div.

<div style="background-color: blue; padding: 10px; position: relative; height: 100px;">
  <div style="position: absolute; left: 0px; right: 0px; bottom: 10px; padding:0px 10px;">
    <div style="background-color: gray;">css sux</div>
  </div>
</div>

Démo: https://jsfiddle.net/soxv3vr0/

0
asankasri