Comment superposer un div sur un autre div

958

J'ai besoin d'aide pour superposer un individu divsur 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#infoiou 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#infoidessus div.naviet le côté le plus à droite et centré sur le dessus du div.navi.

tonyf
la source
Ce n'est pas le cas dans cette question, mais si vous avez un div à l'intérieur d'un autre div, le div intérieur peut être entièrement ou partiellement masqué en raison de overflow: hidden, utilisez overflow: visibleplutôt.
Christophe Roussy

Réponses:

1242

#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ère au sujet de l' apprentissage position: relativeet des éléments enfants avec position: absolute.

alex
la source
3
merci alex pour votre aide mais ce que je trouve maintenant, c'est que lorsque je redimensionne ma fenêtre et la fais glisser pour qu'elle soit plus petite, mon image info ne reste pas avec sa div parent. Vous voulez essentiellement qu'il se déplace avec le div parent et reste à peu près à la même position, même si l'écran a été quelque peu redimensionné.
tonyf
2
@tonsils: Les instructions de alex devraient vous donner le résultat souhaité, donc il doit y avoir autre chose à l'origine du problème que vous décrivez. Pourriez-vous nous fournir un échantillon du code (HTML + CSS) afin que nous puissions vous aider?
Erik Töyrä Silfverswärd
9
absoluteLes éléments positionnés sont positionnés par rapport à leur position:absolute|relative|fixedélément parent explicitement positionné ( ) le plus proche . juste une clarification supplémentaire ... jsfiddle.net/p5jkc8gz
xandercoded
Selon les cas, cela peut être adapté. Dans ma situation, je n'avais pas besoin que #navi soit en haut: 0 à gauche: 0, et comme cas général Si vous avez du code HTML, il sera situé tant que l'arborescence HTML sera analysée. Alors peut-être que dans ce cas, cette définition n'est pas nécessaire.
Fabricio PH
403

La solution acceptée fonctionne très bien, mais l'OMI n'a pas d'explication sur la raison pour laquelle elle fonctionne. L'exemple ci-dessous se résume aux principes de base et sépare le CSS important du CSS de style non pertinent. En bonus, j'ai également inclus une explication détaillée du fonctionnement du positionnement CSS.

TLDR; si vous ne voulez que le code, faites défiler vers le bas jusqu'au résultat .

Le problème

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

Solution proposée

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

Position CSS Connaissances requises

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

Les autres positionvaleurs sont relative, absolute, stickyet fixed. En définissant un élément positionsur l'une de ces autres 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: 100pxpour positionner l'élément à 100 pixels du haut de la page. Inversement, si nous définissons bottom: 100pxl'élément, il serait positionné à 100 pixels du bas de la page.

C'est là que de nombreux nouveaux arrivants CSS se perdent -position: absolutea un cadre de référence. Dans l'exemple ci-dessus, le cadre de référence est l'bodyélément. position: absoluteavectop: 100pxsignifie que l'élément est positionné à 100 pixels du haut de l'bodyélément.

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

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

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

L'autre facteur à prendre en compte est l' ordre d'empilement - ou la façon dont les éléments sont empilés dans la direction z. Il faut savoir ici que l'ordre des éléments de la pile est, par défaut, défini 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 <div>éléments étaient positionnés au même endroit sur la page, l' <div>Top</div>élément couvrirait l' <div>Bottom</div>élément. Comme <div>Top</div>vient après <div>Bottom</div>dans la structure HTML, il a un ordre d'empilement plus élevé.

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

Nous pouvons ignorer l'ordre d'empilement dans ce problème car la structure HTML naturelle des éléments signifie que l'élément sur lequel nous voulons apparaître topvient après l'autre élément.

Donc, revenons au problème en cours - nous utiliserons le contexte de position pour résoudre ce problème.

La solution

Comme indiqué ci-dessus, notre objectif est de positionner l' #infoiélément de sorte qu'il apparaisse à l'intérieur de l' .naviélément. Pour ce faire, nous encapsulerons les éléments .naviet #infoidans un nouvel élément <div class="wrapper">afin de pouvoir 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 .wrapperun position: relative.

.wrapper {
  position: relative;
}

Avec ce nouveau contexte de position, nous pouvons nous positionner à l' #infoiintérieur .wrapper. Tout d'abord, donnez #infoiun position: absolute, nous permettant de nous positionner #infoiabsolument .wrapper.

Ajoutez ensuite top: 0et right: 0pour positionner l' #infoiélément dans le coin supérieur droit. N'oubliez pas que l' #infoiélément étant utilisé .wrappercomme contexte de position, il se trouvera en haut à droite de l' .wrapperélément.

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

Parce qu'il .wrappers'agit simplement d'un conteneur pour .navi, le positionnement #infoidans le coin supérieur droit de .wrapperdonne l'effet d'être positionné dans le coin supérieur droit de .navi.

Et #infoivoilà , il semble maintenant être dans le coin supérieur droit de .navi.

Le résultat

L'exemple ci-dessous se résume aux bases et contient un style minimal.

Une solution alternative (grille)

Voici une solution alternative utilisant CSS Grid pour positionner l' .naviélément avec l' #infoiélément à l'extrême droite. J'ai utilisé les gridpropriétés verbeuses pour le rendre aussi clair que possible.

Une solution alternative (sans emballage)

Dans le cas où nous ne pouvons pas modifier 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: absolutel' #infoiélément, nous utiliserons position: relative. Cela nous permet de repositionner l' #infoiélément à partir de sa position par défaut sous l' .naviélément. Avec position: relativenous pouvons utiliser une topvaleur négative pour la déplacer vers le haut par rapport à sa position par défaut, et une leftvaleur de 100%moins quelques pixels, en utilisant left: calc(100% - 52px), pour la positionner près du côté droit.

Brett DeWoody
la source
29
c'est l'entrée IMO la plus utile car elle explique pourquoi ça marche!
Bret Weinraub
20
C'est probablement la meilleure explication du fonctionnement du positionnement que j'ai vue jusqu'à présent. Concis, mais suffisamment profond pour bien faire les choses.
Marcel
2
Idem sur la qualité de la réponse. Explication la plus claire que j'ai vue.
Wade Hatler
2
Ceci est une excellente réponse en particulier pour les nouveaux arrivants en CSS
Ali Ezzat Odeh
2
Bravo pour l'explication
Joey587
111

En utilisant un divstyle avec z-index:1;et position: absolute;vous pouvez superposer votre divsur n'importe quel autre div.

z-indexdétermine l'ordre dans lequel les divs «empilent». Un div avec un plus haut z-indexapparaîtra devant un div avec un plus bas z-index. Notez que cette propriété ne fonctionne qu'avec des éléments positionnés .

Hari Thakur
la source
5
Pouvez vous donner un exemple?
Fabricio PH
3
La note sur les éléments positionnés est critique.
Lawrence Dol
Cette réponse est si incomplète qu'elle a besoin d'un article entier pour expliquer pourquoi. Recherchez les contextes d'empilement.
Bojidar Stanchev
39

La nouvelle spécification CSS Grid fournit une solution beaucoup plus élégante. L'utilisation position: absolutepeut entraîner des chevauchements ou des problèmes de mise à l'échelle tandis que Grid vous évitera des hacks CSS sales.

Exemple de superposition de grille la plus minimale:

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 très probablement.

ja0nz
la source
4
Cela devrait être la meilleure réponse.
Inline
1
Réponse supérieure. La réponse sélectionnée doit être réévaluée.
AbdulG
Solution parfaite
Deniz da King
24

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

Conseil : si l'élément avant le wrapper est en ligne, il peut se retrouver imbriqué. Dans ce cas, vous pouvez "envelopper l'emballage" à l'intérieur d'un récipient avec display: block- généralement un bon et vieux 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>

Tuco
la source
20

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>

DhavalThakor
la source
9

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 un emballage autour d'eux deux. Vous pouvez contrôler l'emplacement du div de menu qui sera affiché dans le div d'en-tête avec les marges gauche et les positions supérieures. Vous pouvez également définir le menu div pour qu'il flotte à droite si vous le souhaitez.

Muhammad Ahsan
la source
0

Voici un exemple simple pour apporter un effet de superposition avec une icône de chargement sur une autre div.

<style>
    #overlay {
        position: absolute;
        width: 100%;
        height: 100%;
        background: black url('icons/loading.gif') center center no-repeat; /* Make sure the path and a fine named 'loading.gif' is there */
        background-size: 50px;
        z-index: 1;
        opacity: .6;
    }
    .wraper{
        position: relative;
        width:400px;  /* Just for testing, remove width and height if you have content inside this div */
        height:500px; /* Remove this if you have content inside */
    }
</style>

<h2>The overlay tester</h2>
<div class="wraper">
    <div id="overlay"></div>
    <h3>Apply the overlay over this div</h3>
</div>

Essayez-le ici: http://jsbin.com/fotozolucu/edit?html,css,output

Nishad Up
la source