Como sobrepor uma div sobre outra div

958

Preciso de ajuda para sobrepor um indivíduo diva outro div.

Meu código fica assim:

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

Infelizmente não consigo aninhar o div#infoiou o img, dentro do primeiro div.navi.

Tem que haver dois divs separados, como mostrado, mas preciso saber como colocar o lado div#infoisuperior div.navie o direito mais central e centralizado em cima do div.navi.

tonyf
fonte
Não é o caso nesta pergunta, mas se você tiver uma div dentro de outra div, a div interna pode ser total ou parcialmente mascarada devido a overflow: hidden, use em overflow: visiblevez disso.
Christophe Roussy

Respostas:

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>

Sugiro aprender sobre position: relativee elementos filho com position: absolute.

alex
fonte
3
obrigado alex pela ajuda, mas o que estou descobrindo agora é que, quando redimensiono minha janela e a arrasto para ser menor, minha imagem info não fica com a div pai. Basicamente, queira que ele se mova com a div principal e permaneça praticamente na mesma posição, mesmo que a tela tenha sido redimensionada.
tonyf 31/05
2
@tonsils: As instruções de alex devem fornecer o resultado desejado, portanto deve haver algo mais causando o problema que você descreve. Você poderia nos fornecer uma amostra do código (HTML + CSS) para que possamos ajudá-lo?
Erik Töyrä Silfverswärd
9
absoluteos elementos posicionados são posicionados em relação ao position:absolute|relative|fixedelemento pai explicitamente posicionado ( ) mais próximo . apenas esclarecimentos adicionais ... jsfiddle.net/p5jkc8gz
xandercoded
Dependendo do caso, isso pode ser adaptado. Na minha situação, não era necessário que #navi estivesse no topo: 0 esquerda: 0 e, geralmente, se você estiver tendo código HTML, ele ficará situado enquanto a árvore HTML for analisada. Então, talvez neste caso essa definição não seja necessária.
Fabricio PH
403

A solução aceita funciona muito bem, mas a IMO não tem uma explicação sobre o motivo. O exemplo abaixo é resumido ao básico e separa o CSS importante do CSS de estilo não relevante. Como bônus, também incluí uma explicação detalhada de como o posicionamento CSS funciona.

TLDR; se você deseja apenas o código, role para baixo até O resultado .

O problema

Existem dois elementos separados, irmãos, e o objetivo é posicionar o segundo elemento (com um idde infoi), para que ele apareça no elemento anterior (aquele com um classde navi). A estrutura HTML não pode ser alterada.

Solução proposta

Para alcançar o resultado desejado, vamos mover ou posicionar o segundo elemento, que chamaremos #infoipara que apareça no primeiro elemento, que chamaremos .navi. Especificamente, queremos #infoiser posicionados no canto superior direito de .navi.

Posição CSS Conhecimento necessário

CSS possui várias propriedades para elementos de posicionamento. Por padrão, todos os elementos são position: static. Isso significa que o elemento será posicionado de acordo com sua ordem na estrutura HTML, com poucas exceções.

Os outros positionvalores são relative, absolute, sticky, e fixed. Ao definir um elemento positionpara um desses outros valores, agora é possível usar uma combinação das quatro propriedades a seguir para posicionar o elemento:

  • top
  • right
  • bottom
  • left

Em outras palavras, ao definir position: absolute, podemos adicionar top: 100pxpara posicionar o elemento 100 pixels da parte superior da página. Por outro lado, se definirmos bottom: 100pxo elemento, ele será posicionado a 100 pixels da parte inferior da página.

Aqui é onde muitos novatos em CSS se perdem -position: absolutetem um quadro de referência. No exemplo acima, o quadro de referência é obodyelemento position: absolutecomtop: 100pxsignifica que o elemento está posicionado a 100 pixels da parte superior dobodyelemento.

O quadro de referência da posição, ou o contexto da posição, pode ser alterado definindo o positionelemento pai de qualquer valor diferente deposition: static . Ou seja, podemos criar um novo contexto de posição fornecendo um elemento pai:

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

Por exemplo, se um <div class="parent">elemento é fornecido position: relative, qualquer elemento filho usa o <div class="parent">como contexto de posição. Se um elemento filho fosse fornecido position: absolutee top: 100px, o elemento seria posicionado a 100 pixels da parte superior do <div class="parent">elemento, porque <div class="parent">agora é o contexto da posição.

O outro fator a ser observado é a ordem da pilha - ou como os elementos são empilhados na direção z. O que você deve saber aqui é que a ordem dos elementos da pilha é, por padrão, definida pelo inverso de sua ordem na estrutura HTML. Considere o seguinte exemplo:

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

Neste exemplo, se os dois <div>elementos fossem posicionados no mesmo lugar na página, o <div>Top</div>elemento cobriria o <div>Bottom</div>elemento. Como <div>Top</div>vem depois <div>Bottom</div>na estrutura HTML, ele tem uma ordem de empilhamento mais alta.

A ordem de empilhamento pode ser alterada com CSS usando as propriedades z-indexou order.

Podemos ignorar a ordem de empilhamento nesta edição, pois a estrutura HTML natural dos elementos significa que o elemento em que queremos que apareça topvem após o outro elemento.

Então, voltando ao problema em questão - usaremos o contexto da posição para resolver esse problema.

A solução

Como mencionado acima, nosso objetivo é posicionar o #infoielemento para que ele apareça dentro do .navielemento. Para fazer isso, agruparemos os elementos .navie #infoiem um novo elemento <div class="wrapper">para que possamos criar um novo contexto de posição.

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

Em seguida, crie um novo contexto de posição dando .wrappera position: relative.

.wrapper {
  position: relative;
}

Com este novo contexto de posição, podemos posicionar #infoidentro .wrapper. Primeiro, dê #infoia position: absolute, permitindo-nos posicionar #infoiabsolutamente .wrapper.

Em seguida, adicione top: 0e right: 0para posicionar o #infoielemento no canto superior direito. Lembre-se, como o #infoielemento está usando .wrappercomo contexto de posição, ele estará no canto superior direito do .wrapperelemento.

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

Como .wrapperé apenas um contêiner para .navi, o posicionamento #infoino canto superior direito da .wrapperdá o efeito de ser posicionado no canto superior direito da .navi.

E aí está, #infoiagora parece estar no canto superior direito de .navi.

O resultado

O exemplo abaixo é resumido ao básico e contém alguns estilos mínimos.

Uma solução alternativa (grade)

Aqui está uma solução alternativa usando CSS Grid para posicionar o .navielemento com o #infoielemento na extrema direita. Eu usei as gridpropriedades detalhadas para deixar o mais claro possível.

Uma solução alternativa (sem invólucro)

Caso não possamos editar nenhum HTML, o que significa que não podemos adicionar um elemento wrapper, ainda podemos obter o efeito desejado.

Em vez de usar position: absoluteo #infoielemento, usaremos position: relative. Isso nos permite reposicionar o #infoielemento de sua posição padrão abaixo do .navielemento. Com position: relativepodemos usar um topvalor negativo para movê-lo para cima de sua posição padrão, e um leftvalor de 100%menos alguns pixels, usando left: calc(100% - 52px), para posicioná-lo próximo ao lado direito.

Brett DeWoody
fonte
29
esta é a entrada mais útil na IMO porque explica por que funciona!
Bret Weinraub 10/10
20
Essa é provavelmente a melhor explicação de como o posicionamento funciona até agora. Conciso, mas profundo o suficiente para acertar.
Marcel
2
O mesmo vale para a qualidade da resposta. A explicação mais clara que eu já vi.
Wade Hatler,
2
Esta é uma grande resposta, especialmente para os recém-chegados em css
Ali Ezzat Odeh
2
Kudos para a explicação
Joey587
111

Usando um divcom estilo z-index:1;e position: absolute;você pode sobrepor seu divem qualquer outro div.

z-indexdetermina a ordem em que as divs 'empilham'. Um div com um valor mais alto z-indexaparecerá na frente de um div com um valor mais baixo z-index. Observe que essa propriedade funciona apenas com elementos posicionados .

Hari Thakur
fonte
5
você pode dar um exemplo?
21417 Fabricio PH
3
A observação sobre os elementos posicionados é crítica.
21818 Lawrence Dol
Essa resposta é tão incompleta que é necessário um post inteiro para explicar o porquê. Procure contextos de empilhamento.
Bojidar Stanchev 01/08/19
39

A nova especificação Grid CSS fornece uma solução muito mais elegante. O uso position: absolutepode levar a sobreposições ou problemas de dimensionamento, enquanto o Grid o salvará de hacks CSS sujos.

Exemplo mínimo de sobreposição de grade:

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

É isso aí. Se você não criar para o Internet Explorer, seu código provavelmente funcionará.

ja0nz
fonte
4
Esta deve ser a melhor resposta.
Inline
1
Resposta superior. A resposta selecionada deve ser reavaliada.
AbdulG
Solução perfeita
Deniz da King
24

A seguir, uma solução simples 100% baseada em CSS. O "segredo" é usar o display: inline-blockelemento no invólucro. A vertical-align: bottomimagem é um truque para superar o preenchimento de 4px que alguns navegadores adicionam após o elemento.

Conselho : se o elemento antes do wrapper estiver embutido, eles poderão acabar aninhados. Nesse caso, você pode "embrulhar o invólucro" dentro de um recipiente com display: block- geralmente um bom e velho 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
fonte
20

Isto é o que você precisa:

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
fonte
9

Não sou muito codificador nem especialista em CSS, mas ainda estou usando a sua ideia nos meus designs da web. Também tentei resoluções diferentes:

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

Claro que haverá um invólucro em torno de ambos. Você pode controlar a localização do menu div que será exibido dentro do cabeçalho div com margens esquerdas e posições superiores. Você também pode definir o menu div para flutuar corretamente, se quiser.

Muhammad Ahsan
fonte
0

Aqui está um exemplo simples para trazer um efeito de sobreposição com um ícone de carregamento sobre outra 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>

Experimente aqui: http://jsbin.com/fotozolucu/edit?html,css,output

Nishad Up
fonte