How to create an animated tooltip in ReactJS with styled-components

Eduardo Quintino
4 min readMay 12, 2020

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.

(Leia em Português)

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>
);
}
Customized items

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.
Box visible when hovered

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;
`;
Box with transitions

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;
...
`;
Box with position absolute

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);
}
}
`;
Final tooltip

And here is the final result!

Complete code

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>

--

--