[html] How to overlay one div over another div

The accepted solution works great, but IMO lacks an explanation as to why it works. The example below is boiled down to the basics and separates the important CSS from the non-relevant styling CSS. As a bonus, I've also included a detailed explanation of how CSS positioning works.

TLDR; if you only want the code, scroll down to The Result.

The Problem

There are two separate, sibling, elements and the goal is to position the second element (with an id of infoi), so it appears within the previous element (the one with a class of navi). The HTML structure cannot be changed.

Proposed Solution

To achieve the desired result we're going to move, or position, the second element, which we'll call #infoi so it appears within the first element, which we'll call .navi. Specifically, we want #infoi to be positioned in the top-right corner of .navi.

CSS Position Required Knowledge

CSS has several properties for positioning elements. By default, all elements are position: static. This means the element will be positioned according to its order in the HTML structure, with few exceptions.

The other position values are relative, absolute, sticky, and fixed. By setting an element's position to one of these other values it's now possible to use a combination of the following four properties to position the element:

  • top
  • right
  • bottom
  • left

In other words, by setting position: absolute, we can add top: 100px to position the element 100 pixels from the top of the page. Conversely, if we set bottom: 100px the element would be positioned 100 pixels from the bottom of the page.

Here's where many CSS newcomers get lost - position: absolute has a frame of reference. In the example above, the frame of reference is the body element. position: absolute with top: 100px means the element is positioned 100 pixels from the top of the body element.

The position frame of reference, or position context, can be altered by setting the position of a parent element to any value other than position: static. That is, we can create a new position context by giving a parent element:

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

For example, if a <div class="parent"> element is given position: relative, any child elements use the <div class="parent"> as their position context. If a child element were given position: absolute and top: 100px, the element would be positioned 100 pixels from the top of the <div class="parent"> element, because the <div class="parent"> is now the position context.

The other factor to be aware of is stack order - or how elements are stacked in the z-direction. The must-know here is the stack order of elements are, by default, defined by the reverse of their order in the HTML structure. Consider the following example:

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

In this example, if the two <div> elements were positioned in the same place on the page, the <div>Top</div> element would cover the <div>Bottom</div> element. Since <div>Top</div> comes after <div>Bottom</div> in the HTML structure it has a higher stacking order.

_x000D_
_x000D_
div {_x000D_
  position: absolute;_x000D_
  width: 50%;_x000D_
  height: 50%;_x000D_
}_x000D_
_x000D_
#bottom {_x000D_
  top: 0;_x000D_
  left: 0;_x000D_
  background-color: blue;_x000D_
}_x000D_
_x000D_
#top {_x000D_
  top: 25%;_x000D_
  left: 25%;_x000D_
  background-color: red;_x000D_
}
_x000D_
<div id="bottom">Bottom</div>_x000D_
<div id="top">Top</div>
_x000D_
_x000D_
_x000D_

The stacking order can be changed with CSS using the z-index or order properties.

We can ignore the stacking order in this issue as the natural HTML structure of the elements means the element we want to appear on top comes after the other element.

So, back to the problem at hand - we'll use position context to solve this issue.

The Solution

As stated above, our goal is to position the #infoi element so it appears within the .navi element. To do this, we'll wrap the .navi and #infoi elements in a new element <div class="wrapper"> so we can create a new position context.

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

Then create a new position context by giving .wrapper a position: relative.

.wrapper {
  position: relative;
}

With this new position context, we can position #infoi within .wrapper. First, give #infoi a position: absolute, allowing us to position #infoi absolutely in .wrapper.

Then add top: 0 and right: 0 to position the #infoi element in the top-right corner. Remember, because the #infoi element is using .wrapper as its position context, it will be in the top-right of the .wrapper element.

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

Because .wrapper is merely a container for .navi, positioning #infoi in the top-right corner of .wrapper gives the effect of being positioned in the top-right corner of .navi.

And there we have it, #infoi now appears to be in the top-right corner of .navi.

The Result

The example below is boiled down to the basics, and contains some minimal styling.

_x000D_
_x000D_
/*_x000D_
*  position: relative gives a new position context_x000D_
*/_x000D_
.wrapper {_x000D_
  position: relative;_x000D_
}_x000D_
_x000D_
/*_x000D_
*  The .navi properties are for styling only_x000D_
*  These properties can be changed or removed_x000D_
*/_x000D_
.navi {_x000D_
  background-color: #eaeaea;_x000D_
  height: 40px;_x000D_
}_x000D_
_x000D_
_x000D_
/*_x000D_
*  Position the #infoi element in the top-right_x000D_
*  of the .wrapper element_x000D_
*/_x000D_
#infoi {_x000D_
  position: absolute;_x000D_
  top: 0;_x000D_
  right: 0;_x000D_
_x000D_
  /*_x000D_
  *  Styling only, the below can be changed or removed_x000D_
  *  depending on your use case_x000D_
  */_x000D_
  height: 20px;_x000D_
  padding: 10px 10px;_x000D_
}
_x000D_
<div class="wrapper">_x000D_
  <div class="navi"></div>_x000D_
  <div id="infoi">_x000D_
    <img src="http://via.placeholder.com/32x20/000000/ffffff?text=?" height="20" width="32"/>_x000D_
  </div>_x000D_
</div>
_x000D_
_x000D_
_x000D_

An Alternate (Grid) Solution

Here's an alternate solution using CSS Grid to position the .navi element with the #infoi element in the far right. I've used the verbose grid properties to make it as clear as possible.

_x000D_
_x000D_
:root {_x000D_
  --columns: 12;_x000D_
}_x000D_
_x000D_
/*_x000D_
*  Setup the wrapper as a Grid element, with 12 columns, 1 row_x000D_
*/_x000D_
.wrapper {_x000D_
  display: grid;_x000D_
  grid-template-columns: repeat(var(--columns), 1fr);_x000D_
  grid-template-rows: 40px;_x000D_
}_x000D_
_x000D_
/*_x000D_
*  Position the .navi element to span all columns_x000D_
*/_x000D_
.navi {_x000D_
  grid-column-start: 1;_x000D_
  grid-column-end: span var(--columns);_x000D_
  grid-row-start: 1;_x000D_
  grid-row-end: 2;_x000D_
  _x000D_
  /*_x000D_
  *  Styling only, the below can be changed or removed_x000D_
  *  depending on your use case_x000D_
  */_x000D_
  background-color: #eaeaea;_x000D_
}_x000D_
_x000D_
_x000D_
/*_x000D_
*  Position the #infoi element in the last column, and center it_x000D_
*/_x000D_
#infoi {_x000D_
  grid-column-start: var(--columns);_x000D_
  grid-column-end: span 1;_x000D_
  grid-row-start: 1;_x000D_
  place-self: center;_x000D_
}
_x000D_
<div class="wrapper">_x000D_
  <div class="navi"></div>_x000D_
  <div id="infoi">_x000D_
    <img src="http://via.placeholder.com/32x20/000000/ffffff?text=?" height="20" width="32"/>_x000D_
  </div>_x000D_
</div>
_x000D_
_x000D_
_x000D_

An Alternate (No Wrapper) Solution

In the case we can't edit any HTML, meaning we can't add a wrapper element, we can still achieve the desired effect.

Instead of using position: absolute on the #infoi element, we'll use position: relative. This allows us to reposition the #infoi element from its default position below the .navi element. With position: relative we can use a negative top value to move it up from its default position, and a left value of 100% minus a few pixels, using left: calc(100% - 52px), to position it near the right-side.

_x000D_
_x000D_
/*_x000D_
*  The .navi properties are for styling only_x000D_
*  These properties can be changed or removed_x000D_
*/_x000D_
.navi {_x000D_
  background-color: #eaeaea;_x000D_
  height: 40px;_x000D_
  width: 100%;_x000D_
}_x000D_
_x000D_
_x000D_
/*_x000D_
*  Position the #infoi element in the top-right_x000D_
*  of the .wrapper element_x000D_
*/_x000D_
#infoi {_x000D_
  position: relative;_x000D_
  display: inline-block;_x000D_
  top: -40px;_x000D_
  left: calc(100% - 52px);_x000D_
_x000D_
  /*_x000D_
  *  Styling only, the below can be changed or removed_x000D_
  *  depending on your use case_x000D_
  */_x000D_
  height: 20px;_x000D_
  padding: 10px 10px;_x000D_
}
_x000D_
<div class="navi"></div>_x000D_
<div id="infoi">_x000D_
  <img src="http://via.placeholder.com/32x20/000000/ffffff?text=?" height="20" width="32"/>_x000D_
</div>
_x000D_
_x000D_
_x000D_

Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width

Examples related to position

How does the "position: sticky;" property work? React Native absolute positioning horizontal centre RecyclerView - Get view at particular position RecyclerView - How to smooth scroll to top of item on a certain position? How to find index of STRING array in Java from a given value? Insert node at a certain position in a linked list C++ How to position the Button exactly in CSS Float a DIV on top of another DIV Iframe positioning css - position div to bottom of containing div

Examples related to overlay

How to overlay image with color in CSS? Youtube autoplay not working on mobile devices with embedded HTML5 player Pure css close button Prevent body scrolling but allow overlay scrolling Change color of PNG image via CSS? How to make overlay control above all other controls? Creating a system overlay window (always on top) Merging two images with PHP overlay opaque div over youtube iframe How to overlay one div over another div