web-dev-qa-db-fra.com

Comment superposer une div sur une autre

J'ai besoin d'aide pour superposer un individu div sur un autre div.

Mon code ressemble à ceci:

<div class="navi"></div>
<div id="infoi">
    <img src="info_icon2.png" height="20" width="32"/>
</div>

Malheureusement, je ne peux pas imbriquer le div#infoi ou le img, à l'intérieur du premier div.navi.

Il doit s'agir de deux divs distincts, comme indiqué, mais j'ai besoin de savoir comment placer le div#infoi sur le div.navi et le côté le plus à droite, centré sur le div.navi.

851
tonyf
#container {
  width: 100px;
  height: 100px;
  position: relative;
}
#navi,
#infoi {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
}
#infoi {
  z-index: 10;
}
<div id="container">
  <div id="navi">a</div>
  <div id="infoi">
    <img src="https://appharbor.com/assets/images/stackoverflow-logo.png" height="20" width="32" />b
  </div>
</div>

Je suggérerais d'apprendre à propos de position: relative et d'éléments enfants avec position: absolute.

1140
alex

La solution acceptée fonctionne très bien, mais l’OMI n’explique pas pourquoi cela fonctionne. L'exemple ci-dessous se résume à l'essentiel et sépare le CSS important du CSS de style non pertinent. En prime, j'ai également inclus une explication détaillée du fonctionnement du positionnement CSS.

TLDR; si vous voulez seulement le code, faites défiler jusqu'à Le résultat.

Le problème

Il y a deux éléments frères distincts et le but est de positionner le deuxième élément (avec un id sur infoi), afin qu'il apparaisse dans l'élément précédent (celui avec un class de navi). La structure HTML ne peut pas être modifiée.

Solution proposée

Pour atteindre le résultat souhaité, nous allons déplacer ou positionner le deuxième élément, que nous appellerons #infoi, afin qu'il apparaisse dans le premier élément, que nous appellerons .navi. Plus précisément, nous voulons que #infoi soit positionné dans le coin supérieur droit de .navi.

CSS Position Requise Connaissances

CSS a plusieurs propriétés pour le positionnement des éléments. Par défaut, tous les éléments sont position: static. Cela signifie que l'élément sera positionné selon son ordre dans la structure HTML, à quelques exceptions près.

Les autres valeurs position sont relative, absolute et fixed. En définissant la variable position d'un élément sur l'une de ces trois valeurs, il est désormais possible d'utiliser une combinaison des quatre propriétés suivantes pour positionner l'élément:

  • top
  • right
  • bottom
  • left

En d'autres termes, en définissant position: absolute, nous pouvons ajouter top: 100px pour positionner l'élément à 100 pixels du haut de la page. Inversement, si nous définissons bottom: 100px, l'élément sera positionné à 100 pixels du bas de la page.

Voici où de nombreux nouveaux arrivants CSS se perdent - position: absolute a un cadre de référence. Dans l'exemple ci-dessus, le cadre de référence est l'élément body. position: absolute avec top: 100px signifie que l'élément est positionné à 100 pixels du haut de l'élément body.

Le cadre de référence de position, ou le contexte de position, peut être modifié en définissant la position d'un élément parent sur toute valeur autre que position: static. Autrement dit, nous pouvons créer un nouveau contexte de position en donnant un élément parent:

  • position: absolute;
  • position: relative;
  • position: fixed;

Par exemple, si un élément <div class="parent"> dispose de position: relative, tous les éléments enfants utilisent le <div class="parent"> comme contexte de position. Si un élément enfant recevait position: absolute et top: 100px, l'élément serait positionné à 100 pixels du haut de l'élément <div class="parent">, car <div class="parent"> est maintenant le contexte de position.

L'autre facteur à prendre en compte est ordre de pile - ou comment les éléments sont empilés dans la direction z. Ce qu'il faut savoir, c'est que l'ordre des éléments dans la pile est défini par défaut par l'inverse de leur ordre dans la structure HTML. Prenons l'exemple suivant:

<body>
  <div>Bottom</div>
  <div>Top</div>
</body>

Dans cet exemple, si les deux éléments <div> étaient placés au même endroit sur la page, l'élément <div>Top</div> recouvrirait l'élément <div>Bottom</div>. Comme <div>Top</div> vient après <div>Bottom</div> dans la structure HTML, l'ordre d'empilement est plus élevé.

div {
  position: absolute;
  width: 50%;
  height: 50%;
}

#bottom {
  top: 0;
  left: 0;
  background-color: blue;
}

#top {
  top: 25%;
  left: 25%;
  background-color: red;
}
<div id="bottom">Bottom</div>
<div id="top">Top</div>

L'ordre d'empilement peut être modifié avec CSS à l'aide des propriétés z-index ou order.

Nous pouvons ignorer l’ordre d’empilement dans ce numéro, car la structure HTML naturelle des éléments signifie que l’élément que nous voulons voir apparaître sur top vient après l’autre élément.

Revenons donc au problème - nous allons utiliser le contexte de position pour résoudre ce problème.

La solution

Comme indiqué ci-dessus, notre objectif est de positionner l'élément #infoi afin qu'il apparaisse dans l'élément .navi. Pour ce faire, nous allons envelopper les éléments .navi et #infoi dans un nouvel élément <div class="wrapper"> afin de créer un nouveau contexte de position.

<div class="wrapper">
  <div class="navi"></div>
  <div id="infoi"></div>
</div>

Créez ensuite un nouveau contexte de position en donnant .wrapper un position: relative.

.wrapper {
  position: relative;
}

Avec ce nouveau contexte de position, nous pouvons positionner #infoi dans .wrapper. Premièrement, donnez #infoi un position: absolute, ce qui nous permettra de positionner #infoi de manière absolue dans .wrapper.

Ajoutez ensuite top: 0 et right: 0 pour positionner l'élément #infoi dans le coin supérieur droit. Rappelez-vous, étant donné que l'élément #infoi utilise .wrapper comme contexte de position, il sera situé dans le coin supérieur droit de l'élément .wrapper.

#infoi {
  position: absolute;
  top: 0;
  right: 0;
}

Comme .wrapper est simplement un conteneur pour .navi, le positionnement de #infoi dans le coin supérieur droit de .wrapper donne l’effet de se positionner dans le coin supérieur droit de .navi.

Et voilà, #infoi apparaît maintenant dans le coin supérieur droit de .navi.

Le résultat

L'exemple ci-dessous se résume à l'essentiel et contient un style minimal.

/*
*  position: relative gives a new position context
*/
.wrapper {
  position: relative;
}

/*
*  The .navi properties are for styling only
*  These properties can be changed or removed
*/
.navi {
  background-color: #eaeaea;
  height: 40px;
}


/*
*  Position the #infoi element in the top-right
*  of the .wrapper element
*/
#infoi {
  position: absolute;
  top: 0;
  right: 0;

  /*
  *  Styling only, the below can be changed or removed
  *  depending on your use case
  */
  height: 20px;
  padding: 10px 10px;
}
<div class="wrapper">
  <div class="navi"></div>
  <div id="infoi">
    <img src="http://via.placeholder.com/32x20/000000/ffffff?text=?" height="20" width="32"/>
  </div>
</div>

La solution de rechange (sans emballage)

Dans le cas où nous ne pouvons pas éditer de code HTML, ce qui signifie que nous ne pouvons pas ajouter d'élément wrapper, nous pouvons toujours obtenir l'effet souhaité.

Au lieu d'utiliser position: absolute sur l'élément #infoi, nous allons utiliser position: relative. Cela nous permet de repositionner l'élément #infoi à partir de sa position par défaut sous l'élément .navi. Avec position: relative, nous pouvons utiliser une valeur négative top pour la déplacer de sa position par défaut et une left valeur de 100% moins quelques pixels, en utilisant left: calc(100% - 52px), pour se positionner. il près du côté droit.

/*
*  The .navi properties are for styling only
*  These properties can be changed or removed
*/
.navi {
  background-color: #eaeaea;
  height: 40px;
  width: 100%;
}


/*
*  Position the #infoi element in the top-right
*  of the .wrapper element
*/
#infoi {
  position: relative;
  display: inline-block;
  top: -40px;
  left: calc(100% - 52px);

  /*
  *  Styling only, the below can be changed or removed
  *  depending on your use case
  */
  height: 20px;
  padding: 10px 10px;
}
<div class="navi"></div>
<div id="infoi">
  <img src="http://via.placeholder.com/32x20/000000/ffffff?text=?" height="20" width="32"/>
</div>
265
Brett DeWoody

En utilisant un div avec le style z-index:1; et position: absolute;, vous pouvez superposer votre div sur un autre div.

z-index détermine l'ordre dans lequel les divs 'empilent'. Un div avec un z-index supérieur apparaîtra devant un div avec un z-index inférieur. Notez que cette propriété ne fonctionne qu'avec des éléments positionnés.

107
Hari Thakur

Voici une solution simple à 100% basée sur CSS. Le "secret" consiste à utiliser le display: inline-block dans l'élément wrapper. Le vertical-align: bottom dans l'image est un hack permettant de surmonter le remplissage 4px ajouté par certains navigateurs après l'élément.

Conseil: si l'élément avant l'encapsuleur est en ligne, il peut être imbriqué. Dans ce cas, vous pouvez "envelopper l'emballage" dans un conteneur avec display: block - généralement un bon et ancien div.

.wrapper {
    display: inline-block;
    position: relative;
}

.hover {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0, 188, 212, 0);
    transition: background-color 0.5s;
}

.hover:hover {
    background-color: rgba(0, 188, 212, 0.8);
    // You can Tweak with other background properties too (ie: background-image)...
}

img {
    vertical-align: bottom;
}
<div class="wrapper">
    <div class="hover"></div>
    <img src="http://placehold.it/450x250" />
</div>
20
Tuco

Voici ce dont vous avez besoin:

function showFrontLayer() {
  document.getElementById('bg_mask').style.visibility='visible';
  document.getElementById('frontlayer').style.visibility='visible';
}
function hideFrontLayer() {
  document.getElementById('bg_mask').style.visibility='hidden';
  document.getElementById('frontlayer').style.visibility='hidden';
}
#bg_mask {
  position: absolute;
  top: 0;
  right: 0;  bottom: 0;
  left: 0;
  margin: auto;
  margin-top: 0px;
  width: 981px;
  height: 610px;
  background : url("img_dot_white.jpg") center;
  z-index: 0;
  visibility: hidden;
} 

#frontlayer {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  margin: 70px 140px 175px 140px;
  padding : 30px;
  width: 700px;
  height: 400px;
  background-color: orange;
  visibility: hidden;
  border: 1px solid black;
  z-index: 1;
} 


</style>
<html>
  <head>
    <META HTTP-EQUIV="EXPIRES" CONTENT="-1" />

  </head>
  <body>
    <form action="test.html">
      <div id="baselayer">

        <input type="text" value="testing text"/>
        <input type="button" value="Show front layer" onclick="showFrontLayer();"/> Click 'Show front layer' button<br/><br/><br/>

        Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text
        Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text
        Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing textsting text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text Testing text
        <div id="bg_mask">
          <div id="frontlayer"><br/><br/>
            Now try to click on "Show front layer" button or the text box. It is not active.<br/><br/><br/>
            Use position: absolute to get the one div on top of another div.<br/><br/><br/>
            The bg_mask div is between baselayer and front layer.<br/><br/><br/>
            In bg_mask, img_dot_white.jpg(1 pixel in width and height) is used as background image to avoid IE browser transparency issue;<br/><br/><br/>
            <input type="button" value="Hide front layer" onclick="hideFrontLayer();"/>
          </div>
        </div>
      </div>
    </form>
  </body>
</html>
19
DhavalThakor

Je ne suis pas vraiment un codeur ni un expert en CSS, mais j'utilise toujours votre idée dans mes conceptions Web. J'ai aussi essayé différentes résolutions:

#wrapper {
  margin: 0 auto;
  width: 901px;
  height: 100%;
  background-color: #f7f7f7;
  background-image: url(images/wrapperback.gif);
  color: #000;
}
#header {
  float: left;
  width: 100.00%;
  height: 122px;
  background-color: #00314e;
  background-image: url(images/header.jpg);
  color: #fff;
}
#menu {
  float: left;
  padding-top: 20px;
  margin-left: 495px;
  width: 390px;
  color: #f1f1f1;
}
<div id="wrapper">
  <div id="header">
    <div id="menu">
      menu will go here
    </div>
  </div>
</div>

Bien sûr, il y aura une enveloppe autour d'eux. Vous pouvez contrôler l'emplacement du menu div qui sera affiché dans l'en-tête div avec les marges gauche et les positions supérieures. Vous pouvez également régler le menu div pour qu'il flotte correctement si vous le souhaitez.

9
Muhammad Ahsan

La nouvelle spécification (Grid CSS) offre une solution beaucoup plus élégante. L'utilisation de position: absolute peut entraîner des chevauchements ou des problèmes de mise à l'échelle alors que Grid vous épargnera des hacks CSS sales.

Exemple minimal de superposition de grille:

HTML

<div class="container">
  <div class="content">This is the content</div>
  <div class="overlay">Overlay - must be placed under content in the HTML</div>
</div>

CSS

.container {
  display: grid;
}

.content, .overlay {
  grid-area: 1 / 1;
}

C'est ça. Si vous ne construisez pas pour Internet Explorer, votre code fonctionnera probablement.

6
ja0nz