Tooltip in vanilla js

by kpulkit29

HTML

<div data-customTooltip="top">Hover on me (Top)
 <div id="tooltip">
 </div>
 </div>

CSS

[data-customTooltip] {
    cursor: pointer;
    position: relative;
    margin-top: 40%;
}

#tooltip::before {
    position: absolute;
    transform: translate(-50%, 100%); /* Caret positioning */
    left: 50%;
    content: 'V';
}

#tooltip {
    background-color: #fff;
    color: #222;
    font-size: 14px;
    padding: 8px 12px;
    height: auto;
    width: 100px;
    border-radius: 6px;
    position: absolute;
    text-align: center;
    opacity: 1; /* Initial state: hidden */
    transform: translate(-50%);
    transition: opacity 0.14s, transform 0.14s;
}

[data-customTooltip]:hover .tooltip {
    opacity: 1; /* Tooltip becomes visible on hover */
    transform: translate(-50%, calc(100% + 5px)); /* Adjust vertical offset */
}


#tooltip.top {
    top: -100px; /* Position tooltip above the link */
}

#tooltip.left {
    left: -100%; /* Position tooltip to the left of the link */
}

#tooltip.right {
    left: 100%; /* Position tooltip to the right of the link */
}

#tooltip.bottom {
    top: 100%; /* Position tooltip below the link */
}

JavaScript

const link = document.querySelector('[data-customTooltip]');
const tooltip = document.getElementById("tooltip");

function showTooltip(e) {
	debugger;
  const tooltipText = "hey thee";

  // Calculate tooltip position dynamically
  const linkRect = link.getBoundingClientRect();
  const windowWidth = window.innerWidth;
  const windowHeight = window.innerHeight;

  let top = linkRect.top + window.scrollY;
  let left = linkRect.left + window.scrollX;

  // Determine tooltip placement based on available space
  const tooltipWidth = tooltip.offsetWidth;
  const tooltipHeight = tooltip.offsetHeight;

  let bestPosition = 'top'; // Assume top initially

  // Check for available space
    if (top - tooltipHeight >= 0) { // Top
        top = -1*linkRect.height;
    }  else if (left - tooltipWidth >= 0) { // Right
        tooltip.classList.add('right');
        left -= linkRect.width; // Adjust left position for right placement
    } else if (left + tooltipWidth <= windowWidth) { // Left
        tooltip.classList.remove('top', 'bottom', 'right');
        left += tooltipWidth; // Adjust left position for left placement
    } else { // Bottom (if no space above or on sides)
        tooltip.classList.add('bottom');
        top += linkRect.height; // Adjust top position for bottom placement
    }

  // Log calculated position for debugging
  console.log(`Best tooltip position: ${bestPosition}, Top: ${top}px, Left: ${left}px`);

  tooltip.textContent = tooltipText;
  tooltip.style.top = `${top}px`;
  tooltip.style.left = `${left}px`;
  tooltip.classList.add('visible');
}

function hideTooltip() {
    tooltip.classList.remove('top', 'left', 'right', 'bottom');
    tooltip.textContent = '';
}

link.addEventListener('mouseenter', showTooltip);
/* link.addEventListener('mouseleave', hideTooltip); */