Come sovrapporre un div a un altro div


958

Ho bisogno di assistenza per sovrapporre un individuo diva un altro individuo div.

Il mio codice è simile al seguente:

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

Purtroppo non riesco a nidificare il div#infoio il img, all'interno del primo div.navi.

Deve essere due distinti divs come mostrato, ma ho bisogno di sapere come avrei potuto mettere il div#infoisul div.naviea destra più lato e centrato sulla parte superiore del div.navi.


Non è il caso di questa domanda, ma se hai un div dentro un altro div, il div interno può essere completamente o parzialmente mascherato a causa di overflow: hidden, usa overflow: visibleinvece.
Christophe Roussy,

Risposte:


1241

#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>

Vorrei suggerire di conoscere position: relativee gli elementi figlio con position: absolute.


3
grazie alex per il tuo aiuto, ma quello che sto trovando ora è che quando ridimensiono la mia finestra e la trascino per essere più piccola, la mia immagine informativa non rimane con il div genitore. Fondamentalmente vuole che si sposti con il div genitore e rimanga praticamente nella stessa posizione anche se lo schermo è stato leggermente ridimensionato.
tonyf,

2
@tonsils: le istruzioni di alex dovrebbero darti il ​​risultato desiderato, quindi ci deve essere qualcos'altro che causa il problema che descrivi. Potresti fornirci un campione del codice (HTML + CSS) in modo che possiamo aiutarti?
Erik Töyrä Silfverswärd,

9
absoluteGli elementi posizionati vengono posizionati rispetto al loro position:absolute|relative|fixedelemento genitore posizionato ( ) esplicitamente più vicino . solo ulteriori chiarimenti ... jsfiddle.net/p5jkc8gz
xandercoded

A seconda del caso, questo può essere adattato. Nella mia situazione non avevo bisogno di #navi per essere in alto: 0 a sinistra: 0, e come caso generale Se hai il codice HTML, sarà situato fintanto che l'albero HTML verrà analizzato. Quindi forse in questo caso quella definizione non è necessaria.
Fabricio PH

403

La soluzione accettata funziona alla grande, ma all'IMO manca una spiegazione del perché funzioni. L'esempio che segue è ridotto alle basi e separa il CSS importante dal CSS di stile non rilevante. Come bonus, ho anche incluso una spiegazione dettagliata di come funziona il posizionamento CSS.

TLDR; se desideri solo il codice, scorri verso il basso fino a Il risultato .

Il problema

Esistono due elementi separati, fratelli e sorelle, e l'obiettivo è posizionare il secondo elemento (con un iddi infoi), quindi appare all'interno dell'elemento precedente (quello con un classdi navi). La struttura HTML non può essere modificata.

La soluzione proposta

Per ottenere il risultato desiderato, sposteremo o posizioneremo il secondo elemento, che chiameremo in #infoimodo che appaia all'interno del primo elemento, che chiameremo .navi. In particolare, vogliamo #infoiessere posizionati nell'angolo in alto a destra di .navi.

Conoscenza richiesta posizione CSS

CSS ha diverse proprietà per posizionare gli elementi. Per impostazione predefinita, tutti gli elementi sono position: static. Ciò significa che l'elemento verrà posizionato in base al suo ordine nella struttura HTML, con poche eccezioni.

Gli altri positionvalori sono relative, absolute, sticky, e fixed. Impostando un elemento positionsu uno di questi altri valori è ora possibile utilizzare una combinazione delle seguenti quattro proprietà per posizionare l'elemento:

  • top
  • right
  • bottom
  • left

In altre parole, impostando position: absolute, possiamo aggiungere top: 100pxper posizionare l'elemento a 100 pixel dalla parte superiore della pagina. Al contrario, se impostiamo bottom: 100pxl'elemento verrebbe posizionato a 100 pixel dalla parte inferiore della pagina.

Ecco dove molti nuovi arrivati ​​CSS si perdono :position: absoluteha un quadro di riferimento. Nell'esempio sopra, il frame di riferimento è l'bodyelemento. position: absolutecontop: 100pxsignifica che l'elemento è posizionato a 100 pixel dalla parte superiorebodydell'elemento.

Il frame di riferimento della posizione o il contesto della posizione può essere modificato impostando l' positionelemento di un elemento padre su qualsiasi valore diverso daposition: static . Cioè, possiamo creare un nuovo contesto di posizione dando un elemento genitore:

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

Ad esempio, se <div class="parent">viene fornito un elemento position: relative, tutti gli elementi figlio utilizzano il <div class="parent">loro contesto di posizione. Se fosse dato un elemento figlio position: absolutee top: 100px, l'elemento verrebbe posizionato a 100 pixel dalla parte superiore <div class="parent">dell'elemento, poiché <div class="parent">ora è il contesto della posizione.

L'altro fattore da tenere in considerazione è l' ordine di impilamento o il modo in cui gli elementi vengono impilati nella direzione z. L'obbligo da sapere qui è che l'ordine di stack degli elementi è, per impostazione predefinita, definito dall'inverso del loro ordine nella struttura HTML. Considera il seguente esempio:

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

In questo esempio, se i due <div>elementi fossero posizionati nello stesso punto della pagina, l' <div>Top</div>elemento coprirebbe l' <div>Bottom</div>elemento. Poiché <div>Top</div>viene dopo <div>Bottom</div>nella struttura HTML ha un ordine di impilamento più elevato.

L'ordine di sovrapposizione può essere modificato con CSS utilizzando le proprietà z-indexo order.

In questo numero possiamo ignorare l'ordine di sovrapposizione poiché la struttura HTML naturale degli elementi indica che l'elemento su cui vogliamo apparire topviene dopo l'altro elemento.

Quindi, tornando al problema a portata di mano - useremo il contesto di posizione per risolvere questo problema.

La soluzione

Come detto sopra, il nostro obiettivo è posizionare l' #infoielemento in modo che appaia all'interno .navidell'elemento. Per fare ciò, avvolgiamo gli elementi .navie #infoiin un nuovo elemento in <div class="wrapper">modo da poter creare un nuovo contesto di posizione.

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

Quindi creare un nuovo contesto di posizione dando .wrappera position: relative.

.wrapper {
  position: relative;
}

Con questo nuovo contesto di posizione, possiamo posizionarci #infoiall'interno .wrapper. Innanzitutto, dai #infoia position: absolute, permettendoci di posizionarci #infoiassolutamente .wrapper.

Quindi aggiungere top: 0e right: 0per posizionare l' #infoielemento nell'angolo in alto a destra. Ricorda, poiché l' #infoielemento sta usando .wrappercome contesto di posizione, sarà in alto a destra .wrapperdell'elemento.

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

Poiché .wrapperè semplicemente un contenitore per .navi, il posizionamento #infoinell'angolo in alto a destra di .wrapperdà l'effetto di essere posizionato nell'angolo in alto a destra di .navi.

E lì ce l'abbiamo, #infoiora sembra essere nell'angolo in alto a destra di .navi.

Il risultato

L'esempio che segue è ridotto ai concetti di base e contiene uno stile minimo.

Una soluzione alternativa (griglia)

Ecco una soluzione alternativa che utilizza CSS Grid per posizionare l' .navielemento con l' #infoielemento all'estrema destra. Ho usato le gridproprietà verbose per renderlo il più chiaro possibile.

Una soluzione alternativa (senza involucro)

Nel caso in cui non possiamo modificare alcun HTML, nel senso che non possiamo aggiungere un elemento wrapper, possiamo comunque ottenere l'effetto desiderato.

Invece di utilizzare position: absolutesul #infoielemento, useremo position: relative. Questo ci consente di riposizionare l' #infoielemento dalla sua posizione predefinita sotto l' .navielemento. Con position: relativepossiamo usare un topvalore negativo per spostarlo verso l'alto dalla sua posizione predefinita, e un leftvalore 100%meno un paio di pixel, usando left: calc(100% - 52px), per posizionarlo vicino al lato destro.


29
questa è la voce IMO più utile perché spiega perché funziona!
Bret Weinraub,

20
Questa è probabilmente la migliore spiegazione di come funziona il posizionamento che ho visto finora. Conciso, ma abbastanza profondo per farlo bene.
Marcel,

2
Idem sulla qualità della risposta. La spiegazione più chiara che abbia mai visto.
Wade Hatler,

2
Questa è un'ottima risposta soprattutto per i nuovi arrivati ​​in CSS
Ali Ezzat Odeh

2
Complimenti per la spiegazione
Joey587,

111

Usando una divcon stile z-index:1;ed position: absolute;è possibile sovrapporre la tua divsu qualsiasi altro div.

z-indexdetermina l'ordine in cui i "stack" dei div. Un div con un valore più alto z-indexapparirà davanti a un div con un valore più basso z-index. Si noti che questa proprietà funziona solo con elementi posizionati .


5
puoi fornire un esempio?
Fabricio PH

3
La nota sugli elementi posizionati è fondamentale.
Lawrence Dol,

Questa risposta è così incompleta che ha bisogno di un intero post per spiegare il perché. Cerca i contesti di sovrapposizione.
Bojidar Stanchev,

39

La nuova specifica Grid CSS offre una soluzione molto più elegante. L'uso position: absolutepuò portare a sovrapposizioni o problemi di ridimensionamento mentre Grid ti salverà da hack CSS sporchi.

Esempio di overlay griglia minimo:

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;
}

Questo è tutto. Se non costruisci per Internet Explorer, molto probabilmente il tuo codice funzionerà.


4
Questa dovrebbe essere la risposta migliore.
Inline il

1
Risposta superiore. La risposta selezionata dovrebbe essere rivalutata.
AbdulG

Soluzione perfetta
Deniz da King

24

Ecco una semplice soluzione al 100% basata su CSS. Il "segreto" è usare l' display: inline-blockelemento nell'involucro. L' vertical-align: bottomimmagine nell'immagine è un trucco per superare il padding 4px che alcuni browser aggiungono dopo l'elemento.

Consiglio : se l'elemento prima dell'involucro è in linea possono finire nidificati. In questo caso puoi "avvolgere la confezione" all'interno di un contenitore con display: block- di solito un buono e vecchio 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

Questo è quello di cui hai bisogno:

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>


9

Non sono un programmatore né un esperto di CSS, ma sto ancora usando la tua idea nei miei progetti web. Ho provato anche diverse risoluzioni:

#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>

Ovviamente ci sarà un involucro attorno a entrambi. È possibile controllare la posizione del div del menu che verrà visualizzato all'interno del div dell'intestazione con i margini a sinistra e le prime posizioni. Se lo desideri, puoi anche impostare il menu div in virgola mobile.


0

Ecco un semplice esempio per portare un effetto di sovrapposizione con un'icona di caricamento su un altro 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>

Provalo qui: http://jsbin.com/fotozolucu/edit?html,css,output

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.