Как наложить один div на другой div

958

Мне нужна помощь с наложением одного человека divна другого div.

Мой код выглядит так:

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

К сожалению, я не могу гнездиться внутри div#infoiили imgвнутри div.navi.

Это должно быть два отдельных divs, как показано, но мне нужно знать, как я мог бы разместить div#infoiнад div.naviи справа крайнюю сторону и по центру сверху div.navi.

tonyf
источник
Не в этом вопросе, но если у вас есть один div внутри другого div, то внутренний div может быть полностью или частично замаскирован из-за overflow: hiddenиспользования overflow: visibleвместо этого.
Кристоф Русси

Ответы:

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>

Я бы предложил изучить position: relativeи дочерние элементы с position: absolute.

Алекс
источник
3
спасибо alex за вашу помощь, но сейчас я обнаружил, что когда я изменяю размер окна и перетаскиваю его, чтобы уменьшить, мое информационное изображение не остается с родительским div. По сути, нужно, чтобы он двигался вместе с родительским div и оставался практически на том же месте, даже если размер экрана несколько изменился.
Тониф
2
@tonsils: инструкции alex должны дать желаемый результат, поэтому должно быть что-то еще, что вызывает проблему, которую вы описываете. Не могли бы вы предоставить нам образец кода (HTML + CSS), чтобы мы могли вам помочь?
Эрик Тойра Сильфверсвард
9
absoluteпозиционируемые элементы расположены относительно их ближайшего явно позиционированного ( position:absolute|relative|fixed) родительского элемента. просто дальнейшие разъяснения ... jsfiddle.net/p5jkc8gz
xandercoded
В зависимости от случая это можно адаптировать. В моей ситуации мне не нужно, чтобы #navi был top: 0 left: 0, и в общем случае, если у вас есть HTML-код, он будет находиться до тех пор, пока HTML-дерево анализируется. Так что, возможно, в этом случае это определение не является необходимым.
Fabricio PH
403

Принятое решение прекрасно работает, но IMO не хватает объяснения, почему оно работает. Пример ниже сводится к основам и отделяет важный CSS от несоответствующего CSS стиля. В качестве бонуса я также включил подробное объяснение того, как работает позиционирование CSS.

TLDR; если вам нужен только код, прокрутите вниз до «Результат» .

Проблема

Есть два отдельных элемента, родственных элемента, и цель состоит в том, чтобы расположить второй элемент (со знаком idof infoi), чтобы он появился в предыдущем элементе (тот, у которого есть classof navi). Структура HTML не может быть изменена.

Предложенное решение

Чтобы достичь желаемого результата, мы собираемся переместить или расположить второй элемент, который мы назовем #infoiтак, чтобы он появился внутри первого элемента, который мы назовем .navi. В частности, мы хотим #infoiбыть расположены в верхнем правом углу .navi.

CSS Позиция Требуется Знание

У CSS есть несколько свойств для позиционирования элементов. По умолчанию все элементы есть position: static. Это означает, что элемент будет располагаться в соответствии с его порядком в структуре HTML, за некоторыми исключениями.

Остальные positionзначения relative, absolute, stickyи fixed. Установив элемент positionк одному из этих других значений, теперь можно использовать комбинацию следующих четырех свойств для позиционирования элемента:

  • top
  • right
  • bottom
  • left

Другими словами, установив position: absolute, мы можем добавить top: 100pxдля позиционирования элемента 100 пикселей сверху страницы. И наоборот, если мы установим bottom: 100pxэлемент будет расположен на 100 пикселей от нижней части страницы.

Вот где теряются многие новички CSS -position: absoluteимеет систему координат. В приведенном выше примере системой отсчета являетсяbodyэлемент. position: absoluteсtop: 100pxозначает, что элемент расположен в 100 пикселях от верхней частиbodyэлемента.

Положение системы координат или контекст позиции можно изменить, установив positionдля родительского элемента любое значение, кромеposition: static . То есть мы можем создать новый контекст позиции, задав родительский элемент:

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

Например, если <div class="parent">задан элемент position: relative, любые дочерние элементы используют в <div class="parent">качестве контекста позиции. Если бы был задан дочерний элемент position: absoluteи top: 100px, элемент был бы расположен в 100 пикселях от вершины <div class="parent">элемента, потому что <div class="parent">теперь это контекст позиции.

Другой фактор, о котором нужно знать, это порядок стека или то, как элементы располагаются в направлении z. Здесь необходимо знать, что порядок стеков элементов по умолчанию определяется в порядке, обратном их порядку в структуре HTML. Рассмотрим следующий пример:

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

В этом примере, если два <div>элемента были расположены в одном и том же месте на странице, <div>Top</div>элемент будет покрывать <div>Bottom</div>элемент. Так <div>Top</div>как <div>Bottom</div>в структуре HTML идет после, он имеет более высокий порядок наложения.

Порядок размещения можно изменить с помощью CSS с помощью свойств z-indexили order.

Мы можем игнорировать порядок размещения в этом выпуске, поскольку естественная HTML-структура элементов означает, что элемент, на котором мы хотим отображаться, topидет после другого элемента.

Итак, вернемся к проблеме - мы будем использовать контекст позиции для решения этой проблемы.

Решение

Как указано выше, наша цель - расположить #infoiэлемент так, чтобы он отображался внутри .naviэлемента. Чтобы сделать это, мы будем обернуть .naviи #infoiэлементы в новом элементе <div class="wrapper">таким образом , мы можем создать новый контекст позиции.

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

Затем создайте новый контекст позиции, давая ..wrapperposition: relative

.wrapper {
  position: relative;
}

С этим новым контекстом позиции мы можем позиционировать #infoiвнутри .wrapper. Во- первых, дать , что позволяет нам позиционировать абсолютно .#infoiposition: absolute#infoi.wrapper

Затем добавьте top: 0и right: 0расположите #infoiэлемент в правом верхнем углу. Помните, потому что #infoiэлемент использует в .wrapperкачестве контекста позиции, он будет в правом верхнем углу .wrapperэлемента.

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

Поскольку .wrapperэто просто контейнер для .navi, позиционирование #infoiв верхнем правом углу .wrapperдает эффект позиционирования в верхнем правом углу .navi.

И там у нас это есть, #infoiтеперь, кажется, в правом верхнем углу .navi.

Результат

Пример ниже сводится к основам и содержит некоторые минимальные стили.

Альтернативное (сеточное) решение

Вот альтернативное решение с использованием CSS Grid для позиционирования .naviэлемента с #infoiэлементом справа. Я использовал подробные gridсвойства, чтобы сделать его максимально понятным.

Альтернативное (без обертки) решение

В случае, если мы не можем редактировать HTML, то есть мы не можем добавить элемент-обертку, мы все равно можем добиться желаемого эффекта.

Вместо того , чтобы использовать position: absoluteна #infoiэлементе, мы будем использовать position: relative. Это позволяет нам переместить #infoiэлемент из его позиции по умолчанию под .naviэлементом. С помощью position: relativeмы можем использовать отрицательное topзначение, чтобы переместить его из положения по умолчанию, и leftзначение 100%минус несколько пикселей, используя left: calc(100% - 52px), чтобы расположить его рядом с правой стороной.

Бретт ДеВуди
источник
29
это самая полезная запись IMO, потому что она объясняет, почему она работает!
Брет Вайнрауб
20
Это, вероятно, лучшее объяснение того, как работает позиционирование, которое я видел до сих пор. Краткий, но достаточно глубокий, чтобы понять это правильно.
Марсель
2
Так же по качеству ответа. Ясное объяснение, которое я видел.
Уэйд Хэтлер
2
Это отличный ответ, особенно для новичков в css
Али
2
Престижность для объяснения
Joey587
111

Используя divстиль z-index:1;и position: absolute;вы можете наложить divна любой другой div.

z-indexопределяет порядок, в котором div'ы укладываются. Div с более высоким z-indexпоявится перед div с более низким z-index. Обратите внимание, что это свойство работает только с позиционированными элементами .

Хари Тхакур
источник
5
Можете ли вы привести пример?
Fabricio PH
3
Примечание о позиционировании элементов имеет решающее значение.
Лоуренс Дол
Этот ответ настолько неполный, что ему нужен целый пост, чтобы объяснить, почему. Посмотрите контексты укладки.
Божидар Станчев
39

Новая спецификация Grid CSS обеспечивает гораздо более элегантное решение. Использование position: absoluteможет привести к перекрытию или масштабированию, в то время как Grid избавит вас от грязных хаков CSS.

Самый минимальный пример Grid Overlay:

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

Вот и все. Если вы не строите для Internet Explorer, ваш код, скорее всего, будет работать.

ja0nz
источник
4
Это должно быть лучшим ответом.
Встроенный
1
Превосходный ответ. Выбранный ответ должен быть переоценен.
АбдулГ
Идеальное решение
Дениз да Кинг
24

Здесь следует простое решение на 100% на основе CSS. «Секрет» заключается в использовании display: inline-blockэлемента в оболочке. Изображение vertical-align: bottomна картинке - это хак для преодоления отступов в 4 пикселя, которые некоторые браузеры добавляют после элемента.

Совет : если элемент перед упаковщиком встроен, он может оказаться вложенным. В этом случае вы можете «обернуть обертку» внутри контейнера, display: blockобычно старого и доброго 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
источник
20

Это то, что вам нужно:

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
источник
9

Я не большой программист и не эксперт в CSS, но я все еще использую вашу идею в своих веб-проектах. Я пробовал разные разрешения тоже:

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

Конечно, вокруг них будет обертка. Вы можете управлять расположением меню div, которое будет отображаться внутри заголовка div с левыми полями и верхними позициями. Вы также можете настроить меню div, если хотите.

Мухаммед Ахсан
источник
0

Вот простой пример добавления эффекта наложения со значком загрузки поверх другого элемента 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>

Попробуйте это здесь: http://jsbin.com/fotozolucu/edit?html,css,output

Нишад Ап
источник