Jak nakładać jeden div na inny div

958

Potrzebuję pomocy w nałożeniu jednej osoby divna drugą div.

Mój kod wygląda następująco:

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

Niestety nie mogę zagnieździć div#infoiani pierwszego img, ani pierwszego div.navi.

divMuszą to być dwa oddzielne s, jak pokazano, ale muszę wiedzieć, w jaki sposób mogę umieścić div#infoinad div.navii po prawej stronie i wyśrodkować na górze div.navi.

tonyf
źródło
Nie ma to miejsca w tym pytaniu, ale jeśli masz jeden div wewnątrz innego div, wewnętrzny div może być całkowicie lub częściowo zamaskowany z powodu overflow: hidden, użyj overflow: visiblezamiast niego.
Christophe Roussy

Odpowiedzi:

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>

Sugerowałbym poznanie position: relativeelementów dziecięcych position: absolute.

alex
źródło
3
dziękuję alex za twoją pomoc, ale to, co teraz znajduję, to to, że kiedy zmieniam rozmiar okna i przeciągam go, aby był mniejszy, mój obraz informacji nie pozostaje z jego rodzica div. Zasadniczo chcę, aby poruszał się z rodzicielskim div i pozostawał prawie w tej samej pozycji, nawet jeśli ekran został nieco przeskalowany.
tonyf
2
@tonsils: Instrukcje autorstwa alex powinno dać pożądanego rezultatu, więc to musi być coś innego powodując opisać problem. Czy możesz nam podać próbkę kodu (HTML + CSS), abyśmy mogli Ci pomóc?
Erik Töyrä Silfverswärd
9
absolutely pozycjonowane elementy są pozycjonowane względem ich najbliższego jawnie pozycjonowanego ( position:absolute|relative|fixed) elementu nadrzędnego. tylko dalsze wyjaśnienia ... jsfiddle.net/p5jkc8gz
xandercoded
W zależności od przypadku można to dostosować. W mojej sytuacji nie musiałem #navi być na górze: 0 pozostało: 0, i jako ogólny przypadek Jeśli masz kod HTML, będzie on umieszczony tak długo, jak długo drzewo HTML zostanie sparsowane. Może więc w tym przypadku ta definicja nie jest konieczna.
Fabricio PH,
402

Przyjęte rozwiązanie działa świetnie, ale IMO nie wyjaśnia, dlaczego działa. Poniższy przykład jest sprowadzony do podstaw i oddziela ważny CSS od nieistotnego CSS w stylu. Jako bonus zamieściłem również szczegółowe wyjaśnienie, jak działa pozycjonowanie CSS.

TLDR; jeśli chcesz tylko kod, przewiń w dół do wyniku .

Problem

Istnieją dwa oddzielne elementy, rodzeństwem, a celem jest, aby umieścić drugi element (o ido infoi) tak, że jest widoczny w poprzednim elementem (jednego z classz navi). Struktury HTML nie można zmienić.

Proponowane rozwiązanie

Aby osiągnąć pożądany rezultat, będziemy przesuwać lub ustawiać drugi element, który nazwiemy, #infoiaby pojawił się w pierwszym elemencie, który nazwiemy .navi. W szczególności chcemy #infoiznaleźć się w prawym górnym rogu .navi.

Wymagana wiedza na temat pozycji CSS

CSS ma kilka właściwości dla elementów pozycjonujących. Domyślnie wszystkie elementy są position: static. Oznacza to, że element zostanie umieszczony zgodnie ze swoją kolejnością w strukturze HTML, z kilkoma wyjątkami.

Pozostałe positionwartości są relative, absolute, sticky, i fixed. Ustawiając element na positionjedną z tych innych wartości, można teraz zastosować kombinację następujących czterech właściwości do pozycjonowania elementu:

  • top
  • right
  • bottom
  • left

Innymi słowy, ustawiając position: absolute, możemy dodać, top: 100pxaby ustawić element w odległości 100 pikseli od góry strony. I odwrotnie, jeśli ustawimy, bottom: 100pxelement zostanie umieszczony 100 pikseli od dołu strony.

Tutaj gubi się wielu początkujących CSS -position: absolutema punkt odniesienia. W powyższym przykładzie ramką odniesienia jestbodyelement. position: absoluteotop: 100pxoznacza, że element jest umieszczony 100 pikseli z górybodyelementu.

Ramkę odniesienia lub kontekst pozycji można zmienić, ustawiając positionelement nadrzędny na dowolną wartość inną niżposition: static . Oznacza to, że możemy utworzyć nowy kontekst pozycji, podając element nadrzędny:

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

Na przykład, jeśli <div class="parent">podano element position: relative, wszystkie elementy potomne używają <div class="parent">jako kontekstu pozycji. Gdyby podano element potomny position: absolutei top: 100px, element zostałby umieszczony 100 pikseli od góry <div class="parent">elementu, ponieważ <div class="parent">jest to teraz kontekst pozycji.

Innym czynnikiem, o którym należy pamiętać, jest kolejność stosów - lub sposób układania elementów w kierunku Z. Trzeba tutaj wiedzieć, że kolejność elementów jest domyślnie definiowana przez odwrotność ich kolejności w strukturze HTML. Rozważ następujący przykład:

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

W tym przykładzie, jeśli dwa <div>elementy zostałyby umieszczone w tym samym miejscu na stronie, <div>Top</div>element obejmowałby ten <div>Bottom</div>element. Ponieważ <div>Top</div>pojawia się <div>Bottom</div>w strukturze HTML, ma wyższą kolejność układania.

Kolejność układania można zmienić za pomocą CSS przy użyciu właściwości z-indexlub order.

W tym wydaniu możemy zignorować kolejność układania, ponieważ naturalna struktura HTML elementów oznacza, że ​​element, na którym chcemy się pojawić, toppojawia się po drugim elemencie.

Wróćmy więc do problemu - użyjemy kontekstu pozycji, aby rozwiązać ten problem.

Rozwiązanie

Jak wspomniano powyżej, naszym celem jest takie umieszczenie #infoielementu, aby pojawił się w .navielemencie. W tym celu zawiniemy elementy .navii #infoiw nowy element <div class="wrapper">, abyśmy mogli utworzyć nowy kontekst pozycji.

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

Następnie należy utworzyć nowy kontekst pozycji dając ..wrapperposition: relative

.wrapper {
  position: relative;
}

Dzięki temu nowemu kontekstowi pozycji możemy pozycjonować #infoiwewnątrz .wrapper. Po pierwsze, daje , co pozwala nam na pozycji absolutnie .#infoiposition: absolute#infoi.wrapper

Następnie dodaj top: 0i, right: 0aby ustawić #infoielement w prawym górnym rogu. Pamiętaj, ponieważ ponieważ #infoielement używa .wrapperjako kontekstu pozycji, znajdzie się w prawym górnym rogu .wrapperelementu.

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

Ponieważ .wrapperjest to tylko pojemnik na .navi, pozycjonowanie #infoiw prawym górnym rogu .wrapperdaje efekt pozycjonowania w prawym górnym rogu .navi.

I mamy to, #infoiteraz wydaje się być w prawym górnym rogu .navi.

Wynik

Poniższy przykład sprowadza się do podstaw i zawiera minimalną stylizację.

Alternatywne rozwiązanie (siatka)

Oto alternatywne rozwiązanie z wykorzystaniem CSS Grid do pozycjonowania .navielementu z #infoielementem po prawej stronie. Użyłem pełnych gridwłaściwości, aby było to jak najbardziej jasne.

Alternatywne rozwiązanie (bez opakowania)

W przypadku, gdy nie możemy edytować żadnego HTML, co oznacza, że ​​nie możemy dodać elementu opakowania, nadal możemy osiągnąć pożądany efekt.

Zamiast używać position: absolutena #infoielemencie użyjemy position: relative. To pozwala nam zmienić położenie #infoielementu z jego domyślnej pozycji poniżej .navielementu. Za pomocą position: relativemożemy użyć topwartości ujemnej, aby przesunąć ją w górę z jej domyślnej pozycji, a leftwartości 100%minus kilka pikseli, używając left: calc(100% - 52px), aby ustawić ją w pobliżu prawej strony.

Brett DeWoody
źródło
29
jest to najbardziej przydatny wpis IMO, ponieważ wyjaśnia, dlaczego to działa!
Bret Weinraub,
20
Jest to prawdopodobnie najlepsze wytłumaczenie dotychczasowego działania pozycjonowania. Zwięzłe, ale wystarczająco głębokie, aby zrobić to dobrze.
Marcel
2
To samo dotyczy jakości odpowiedzi. Najczystsze wyjaśnienie, jakie widziałem.
Wade Hatler,
2
To świetna odpowiedź, szczególnie dla nowicjuszy w css
Ali Ezzat Odeh,
2
Wyrazy uznania
111

Za pomocą divstylu z-index:1;i position: absolute;można nakładać swojej divna dowolny inny div.

z-indexokreśla kolejność, w jakiej div tworzy „stos”. Div z wyższym z-indexpojawi się przed div z niższym z-index. Uwaga: ta właściwość działa tylko z elementami pozycjonowanymi .

Hari Thakur
źródło
5
czy możesz podać przykład?
Fabricio PH,
3
Uwaga na temat elementów pozycjonowanych jest krytyczna.
Lawrence Dol
Ta odpowiedź jest tak niekompletna, że ​​potrzebuje całego posta, aby wyjaśnić, dlaczego. Wyszukaj konteksty stosu.
Bojidar Stanchev
39

Nowa specyfikacja Grid CSS zapewnia znacznie bardziej eleganckie rozwiązanie. Używanie position: absolutemoże prowadzić do nakładania się lub problemów ze skalowaniem, podczas gdy Siatka uratuje cię przed brudnymi włamaniami CSS.

Przykład minimalnej nakładki siatki:

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

Otóż ​​to. Jeśli nie budujesz dla Internet Explorera, najprawdopodobniej twój kod będzie działał.

ja0nz
źródło
4
To powinna być najlepsza odpowiedź.
Inline
1
Najlepsza odpowiedź. Wybrana odpowiedź powinna zostać ponownie oceniona.
AbdulG
Idealne rozwiązanie
Deniz da King
24

Oto proste rozwiązanie w 100% oparte na CSS. „Sekretem” jest użycie display: inline-blockelementu otoki. vertical-align: bottomNa obrazie jest hack do pokonania padding 4PX że niektóre przeglądarki dodać po elemencie.

Rada : jeśli element przed opakowaniem jest w linii, mogą zostać zagnieżdżone. W takim przypadku możesz „owinąć opakowanie” wewnątrz pojemnika display: block- zwykle dobrym i starym 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
źródło
20

Oto, czego potrzebujesz:

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
źródło
9

Nie jestem zbytnim programistą ani ekspertem w dziedzinie CSS, ale nadal używam twojego pomysłu w moich projektach internetowych. Próbowałem też różnych rozdzielczości:

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

Oczywiście wokół nich będzie owijka. Możesz kontrolować lokalizację menu div, które będzie wyświetlane w div div nagłówka z lewym marginesem i górnymi pozycjami. Możesz także ustawić menu div tak, aby unosiło się w prawo, jeśli chcesz.

Muhammad Ahsan
źródło
0

Oto prosty przykład na dodanie efektu nakładki z ikoną ładowania nad innym divem.

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

Wypróbuj tutaj: http://jsbin.com/fotozolucu/edit?html,css,output

Nishad Up
źródło