How to create an animated tooltip in ReactJS with styled-components
One day I was trying to discover a way to create a simple tooltip. I ended up discovering many ways to do it with npm packages. But the simplest way was, instead of using a new library, using the one I already have installed: styled-components.
In this post, I will show a way to create a tooltip that when hovered it shows an animated box with informations.
First, create a react-app project.
yarn create react-app tooltipornpx create-react-app tooltip
Enter in the folder created and install styled-components.
yarn add styled-componentsornpm install styled-components
Then start your project.
yarn startornpm start
Create two divs, one that will be the area to hover and the other will be the tooltip.
App.js
import React from "react";export default function App() {
return (
<div>
<div>
<h3>Hover :D</h3>
</div>
<div>
<p>First item</p>
<p>Second item</p>
</div>
</div>
);
}
Replace the divs for elements of styled-components with the style you want.
import React from "react";
import styled from "styled-components";const TooltipText = styled.div`
background: rgba(28, 56, 151, 0.9);
color: #fff;
width: 200px;
text-align: center;
line-height: 44px;
border-radius: 3px;
cursor: pointer;
`;
const TooltipBox = styled.div`
color: #fff;
background-color: rgba(0, 0, 0, 0.8);
width: 230px;
padding: 8px 8px;
border-radius: 4px;
`;
const TooltipCard = styled.div`
margin: 16px;
`;export default function App() {
return (
<TooltipCard>
<TooltipText>
<h3>Hover :D</h3>
</TooltipText>
<TooltipBox>
<p>First item</p>
<p>Second item</p>
</TooltipBox>
</TooltipCard>
);
}
To be able to hover and show the box below, set the visibility of the box to hidden and move the properties to be shown when the text is hovered. The order of elements matters.
const TooltipBox = styled.div`
visibility: hidden;
`;const TooltipCard = styled.div`
margin: 16px;
& ${TooltipText}:hover + ${TooltipBox} {
visibility: visible;
color: #fff;
background-color: rgba(0, 0, 0, 0.8);
width: 230px;
padding: 8px 8px;
border-radius: 4px;
}
`;
- & Is used to refer back to the main component.
- ${TooltipText}: hover Refers to when the blue box is hovered.
- + ${TooltipBox} Is the target component that will be visible.
Now, let’s add transitions to CSS to show the box. With transitions is possible to choose which properties we want to change, the time and the timing function to be used.
const TooltipBox = styled.div`
visibility: hidden;
color: transparent;
background-color: transparent;
width: 150px;
padding: 5px 5px;
border-radius: 4px;
transition: visibility 0.5s, color 0.5s, background-color 0.5s, width 0.5s, padding 0.5s ease-in-out;
`;
At this point, it is possible to see the animation, but the box is still occupying space below. To solve this, we will use positions absolute and relative to the divs.
const TooltipBox = styled.div`
position: absolute;
top: calc(100% + 10px);
left: 30px;
...
`;const TooltipCard = styled.div`
position: relative;
...
`;
Finally, it is possible to insert an arrow to reference the text hovered. We will use the before pseudo-element.
const TooltipBox = styled.div`
...
&:before {
content: "";
width: 0;
height: 0;
left: 40px;
top: -10px;
position: absolute;
border: 10px solid transparent;
transform: rotate(135deg);
transition: border 0.4s ease-in-out;
}
`;const TooltipCard = styled.div`
position: relative;
margin: 16px;
& ${TooltipText}:hover + ${TooltipBox} {
...
&:before {
border-color: transparent transparent rgba(0, 0, 0, 0.8) rgba(0, 0, 0, 0.8);
}
}
`;
And here is the final result!
Example in CodeSandbox.
Ps: if the content of the box overflows the width, you can insert a hidden property (to prevent the triangle disappear):
const TooltipBox = styled.div`
...
> div {
overflow: hidden;
}
`;...<TooltipBox>
<div>
<p>First item with too much information</p>
<p>Secondalsowithtoomuchinformationtobehidden</p>
</div>
</TooltipBox>