I am currently developing a customized Tooltip
component using React that can be rendered to the right or below the target element. In my approach, the Tooltip
component takes children as input and displays them. When these children are hovered over, the tooltip appears through CSS classes with absolute positioning. Everything works perfectly when the elements are arranged in a column and the tooltip is set to appear on the right. However, a misalignment issue arises when the elements are arranged in a row with the tooltip rendering below the child, seemingly due to the length of the tooltip text pushing it off-center.
To see this issue in action, you can visit this codesandbox link. Click the button to switch the layout from column to row and hover over the elements to observe the misalignment:
https://codesandbox.io/s/busted-tooltip-obf0h1?file=/src/Tooltip.scss
I need help aligning the tooltips centrally with their respective child elements when they render below them. How can I achieve this?
// CustomTooltip.jsx
import React, { useState } from 'react';
import './Tooltip.scss';
const Tooltip = ({ children, label, orientation = 'right' }) => {
const [isHovered, setIsHovered] = useState(false);
return (
<div className={`Tooltip__Container ${orientation}`}>
<div
onMouseOver={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
>
{children}
</div>
<div className={`Tooltip__Inner ${orientation} ${isHovered ? 'Visible' : ''}`}>
{orientation === 'right' && <div className={`Tooltip__PointLeft ${isHovered ? 'Visible' : ''}`} />}
{orientation === 'bottom' && <div className={`Tooltip__PointUp ${isHovered ? 'Visible' : ''}`} />}
<div className={`Tooltip ${orientation} ${isHovered ? 'Visible' : ''}`}>
{label}
</div>
</div>
</div>
);
};
export default Tooltip;
/* Tooltip.scss */
@import 'src/styles/colors.scss', 'src/styles/typography.scss', 'src/styles/breakpoints.scss';
.Tooltip__Container {
display: flex;
position: relative;
&.right {
flex-direction: row;
}
&.bottom {
flex-direction: column;
}
}
.Tooltip__Inner {
display: flex;
z-index: -1;
position: absolute;
transition: all .25s ease;
opacity: 0;
left: 0;
top: 0;
&.right {
flex-direction: row;
}
&.bottom {
flex-direction: column;
}
}
.Tooltip__Inner.right.Visible {
opacity: 1;
left: 3.5rem;
}
.Tooltip__Inner.bottom.Visible {
opacity: 1;
top: 3.5rem;
}
.Tooltip__PointLeft.Visible {
opacity: 1;
width: 0;
height: 0;
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
border-right: 10px solid $white-transparent;
align-self: center;
justify-self: center;
}
.Tooltip__PointUp.Visible {
opacity: 1;
width: 0;
height: 0;
width: 0;
height: 0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-bottom: 10px solid $white-transparent;
align-self: center;
justify-self: center;
}
.Tooltip {
background-color: $white-transparent;
padding: .75rem;
border-radius: 3px;
@include MainFont;
color: white;
}