Creating a customized popover similar to Bootstrap's popover, I have successfully implemented popovers in all directions except for the top direction. My challenge lies in fixing the popover at the bottom just above the button that triggers it, and ensuring that as the content inside the popover grows in height, it expands towards the top while keeping the bottom portion fixed.
let popoverBtn = document.querySelectorAll("[data-toggle='popover']");
let popover = document.querySelector(".popover-overlay");
let popoverHeading = document.querySelector(".popover-overlay-heading h4");
let popoverContent = document.querySelector(".popover-overlay-content p");
for (let i = 0; i < popoverBtn.length; i++) {
if (popoverBtn[i]) {
popoverBtn[i].addEventListener("click", function(e) {
let top = e.target.offsetTop;
let left = e.target.offsetLeft;
let width = e.target.offsetWidth;
let height = e.target.offsetHeight;
let heading = e.target.getAttribute("title");
let description = e.target.getAttribute("data-content");
let popoverHeight = parseFloat(getComputedStyle(popover).height);
let popoverWidth = parseFloat(getComputedStyle(popover).width);
let dir = e.target.getAttribute("data-placement");
popoverHeading.textContent = heading;
popoverContent.textContent = description;
popover.classList.add("active");
popover.style.top = '0px';
popover.style.left = '0px'
switch (dir) {
case "top":
popover.style.top = top - popoverHeight - 20 + "px";
popover.style.left = left + "px";
popover.style.bottom = top;
break;
case "bottom":
popover.style.top = top + height + 5 + "px";
popover.style.left = left + "px";
break;
case "left":
popover.style.top = top + "px";
popover.style.left = left - popoverWidth - 20 + "px";
break;
case "right":
popover.style.top = top + "px";
popover.style.left = left + width + 30 + "px";
break;
default:
popover.style.top = top + "px";
popover.style.left = left + width + 30 + "px";
break;
}
})
}
}
body {
margin: 0px;
padding: 0px;
font-family: sans-serif;
}
h3,
h4,
p {
margin: 0px;
}
.container {
width: 100%;
}
.bg-gray {
background-color: rgba(0, 0, 0, 0.3);
}
.bg-light-gray {
background-color: rgba(0, 0, 0, 0.1);
}
section {
min-height: 400px;
display: flex;
align-items: center;
justify-content: center;
gap: 20px;
}
section button {
display: inline-block;
border: none;
background-color: #dc3545;
color: #fff;
padding: 0.5rem 1rem;
font-size: 1.25rem;
line-height: 1.5;
border-radius: 0.3rem;
}
.popover-overlay {
position: fixed;
z-index: 100;
border-radius: 5px;
border: 1px solid rgba(0, 0, 0, 0.1);
box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.1);
display: none;
width: 280px;
height: 121px;
}
.popover-overlay.active {
display: block;
}
.popover-overlay-heading {
background-color: #f7f7f7;
border-bottom: 1px solid #d3d3d3;
padding: 1rem;
}
.popover-overlay-content {
background-color: #fff;
padding: 1rem;
}
<div class="popover-overlay">
<div class="popover-overlay-heading">
<h4></h4>
</div>
<div class="popover-overlay-content">
<p></p>
</div>
</div>
<div class="container">
<section class="bg-gray">
<button data-placement="top" type="button" class="btn btn-lg btn-danger" data-toggle="popover" title="Popover title" data-content="It's very engaging. Right? And here's some amazing content. It's very engaging. It's very engaging. Right? And here's some amazing content. It's very engaging.">Popover Top</button>
<button data-placement="left" type="button" class="btn btn-lg btn-danger" data-toggle="popover" title="Popover title" data-content="And here's some amazing content. It's very engaging. Right?">Popover Left</button>
<button data-placement="right" type="button" class="btn btn-lg btn-danger" data-toggle="popover" title="Popover title" data-content="And here's some amazing content. It's very engaging. Right?">Popover Right</button>
<button data-placement="bottom" type="button" class="btn btn-lg btn-danger" data-toggle="popover" title="Popover title" data-content="And here's some amazing content. It's very engaging. Right?">Popover Bottom</button>
</section>
</div>