← Back toHTML DOM

Position an element absolutely to another element

Written byPhuoc Nguyen
Category
Level 2 — Intermediate
Created
02 May, 2020
Last updated
07 May, 2021
It's a common requirement that asks for an element to be shown absolutely to a particular element. We can list some cases, such as
  • Show a popover when clicking an element
  • Show a tooltip when moving the mouse over an element
  • Or show a context menu when right-clicking an element
In this post, you'll see three ways to archive that requirement. They are implemented to demonstrate the first use case where we display a popover under a given target.
First of all, assume that the target and popover elements are two simple `div` elements as below:
<div id="target">...</div>
<div id="popover">...</div>
Resource
The implementations don't tell you how to add an arrow to the popover. You can take a look at this page to see how it can be done with CSS

1. Use absolute CSS

This is the easiest way. To position the popover absolutely to the target, we can place the popover in the target
<div id="target" class="target">
...
<div id="popover" class="popover">...</div>
</div>
and apply the simple CSS styles as below:
.target {
position: relative;
}
.popover {
left: 50%;
position: absolute;
top: 100%;
transform: translate(-50%, 0.75rem);
}
This way uses CSS only and doesn't require any position calculation. Anyway, it doesn't work if the target has the `overflow: hidden` style.
In the demo below, clicking the Toggle overflow:hidden button will make the popover hidden as well.

2. Append the popover to `body`

This approach comes from the idea of putting the popover to `body`:
<body>
<div id="target">...</div>

<div id="popover">...</div>
</body>
We still use the absolute style for the popover, but this time we need to calculate the `top` and `left` properties.
It's easy to determine them based on the bounding rectangles of the target and popover:
const target = document.getElementById('target');
const popover = document.getElementById('popover');

const targetRect = target.getBoundingClientRect();
const popoverRect = popover.getBoundingClientRect();

const top = targetRect.top + targetRect.height;
const left = targetRect.left + targetRect.width / 2 - popoverRect.width / 2;
We also need space for the arrow at the top, so let's add some offset:
popover.style.top = `${top + 8}px`;
popover.style.left = `${left}px`;

3. Use an anchor element

This approach is similar to the previous one. The difference is that instead of appending the popover to `body`, we add an anchor between the target and popover.
<div id="target">...</div>
<div id="anchor" class="anchor"></div>
<div id="popover">...</div>
The anchor is positioned absolutely as following:
.anchor {
left: 0;
position: absolute;
top: 0;
}
The popover's top and left properties have to subtract the top and left values of the anchor from the one we calculate in the previous section:
const target = document.getElementById('target');
const anchor = document.getElementById('anchor');
const popover = document.getElementById('popover');

const targetRect = target.getBoundingClientRect();
const anchorRect = anchor.getBoundingClientRect();
const popoverRect = popover.getBoundingClientRect();

const top = targetRect.top + targetRect.height;
const left = targetRect.left + targetRect.width / 2 - popoverRect.width / 2;

popover.style.top = `${top - anchorRect.top + 8}px`;
popover.style.left = `${left - anchorRect.left}px`;

Use cases

See also

Questions? 🙋

Do you have any questions? Not just about this specific post, but about any topic in front-end development that you'd like to learn more about? If so, feel free to send me a message on Twitter or send me an email. You can find them at the bottom of this page.
I have a long list of upcoming posts, but your questions or ideas for the next one will be my top priority. Let's learn together! Sharing knowledge is the best way to grow 🥷.

Recent posts ⚡

Newsletter 🔔

If you're into front-end technologies and you want to see more of the content I'm creating, then you might want to consider subscribing to my newsletter.
By subscribing, you'll be the first to know about new articles, products, and exclusive promotions.
Don't worry, I won't spam you. And if you ever change your mind, you can unsubscribe at any time.
Phước Nguyễn