Have you seen those boxes with extra descriptions when you hover on a text?
Those are tooltips! Even thought it can seem intimidating to start creating your first tooltip, you actually only need to know basic CSS.
This article will show you how to create beautiful tooltips with only CSS.
First, let’s start with a <span>
element with tooltip
class and add an anchor text.
<span class="tooltip">Hover over me!</span>
I promised only to use CSS — no additional HTML elements.
How can we create the tooltip in that way? If your guess was :before
or :after
pseudo elements, you are correct.
Where do you define the tooltip text? One might say to define directly in the content
property of the pseudo elements.
However, it will make things more difficult to handle.
For example, if you need to add several tooltips, you’ll always need to add more CSS rules and define content. So, here we are going to use HTML custom data attributes to define the text.
Let’s add tooltip text as the data-text
attribute to our tooltip span. (You can use whatever name prefixed by data-
. Moreover, you can even drop the prefix in some cases.)
<span data-text="Thanks for hovering! I'm a tooltip" class="tooltip" >Hover over me!</span>
Now, we can add CSS rules to style the container:
.tooltip { position:relative; /* making the .tooltip span a container for the tooltip text */ border-bottom:1px dashed #000; /* little indicater to indicate it's hoverable */ }
Finally, we are going to create the tooltip text, which is positioned on the right side:
.tooltip:before { content: attr(data-text); /* here's the magic */ position:absolute; /* vertically center */ top:50%; transform:translateY(-50%); /* move to right */ left:100%; margin-left:15px; /* and add a small left margin */ /* basic styles */ width:200px; padding:10px; border-radius:10px; background:#000; color: #fff; text-align:center; display:none; /* hide by default */ }
content: attr(data-text)
is the magic here. This takes the data-text
attribute of the parent element and uses it as the content.
Tooltip text is positioned absolute
, and it is relative to the .tooltip
element.
Final rule: showing the tooltip text when hovering:
.tooltip:hover:before { display:block; }
You just created your first tooltip! Next, let’s see how we can improve on this.
In the above example, we positioned the tooltip on the right. But what if we want to put the tooltip in a different place? We can use additional classes to define other positions.
<span data-text="Thanks for hovering! I'm a tooltip" class="tooltip left" >Hover over me!</span>
CSS for the new class:
.tooltip.left:before { /* reset defaults */ left:initial; margin:initial; /* set new values */ right:100%; margin-right:15px; }
You can use the same method to create classes for bottom and top positions. Additionally, you’ll need to reset the top
value and override the transform
value accordingly.
Usually, CSS tooltips has arrows pointing towards the anchor text.
Thankfully, we have another pseudo element that can be used to make arrows.
Here’s the code for an arrow on a right-aligned tooltip:
.tooltip:after { content: ""; position:absolute; /* position tooltip correctly */ left:100%; margin-left:-5px; /* vertically center */ top:50%; transform:translateY(-50%); /* the arrow */ border:10px solid #000; border-color: transparent black transparent transparent; display:none; } .tooltip:hover:before, .tooltip:hover:after { display:block; }
The trick here is to set a border. border: 10px solid #000;
creates a border with 10px width.
Since we haven’t defined the width and height for .tooltip:after
, width and height is equal to two times the border width:
What if we set the border color of each side to different colors?
border-color: blue black red green;
Guess what? Setting all colors to transparent except one side makes the arrow we need.
border-color: transparent black transparent transparent;
Why do we use margin-left:-5px
?
When we set a border width to 10px
, the total width become 20px
. We use margin-left
to position the arrow correctly (note that we used margin-left:15px
in the tooltip).
How do we get rid of this annoying margin? Easy!
Set the border width to half of the tooltip’s left margin (7.5px
in our case). I intentionally made it 10px
to show you how to deal with the above situation. Now you’re familiar with both.
Creating arrows for other positions (left, top, and bottom) is done in the same way. Positioning them requires the same approach we used in .tooltip.left:before
.
A common animation to use for tooltips is the fade-in.
You can also use other animations like zoom-in or bounce, but I personally think they are too much for a tooltip.
Let’s see how to add fade-in animation to our CSS tooltip.
The best method would be to use opacity
and transition
. There are several advantages of using these instead of CSS animations.
First off, they’re easy to implement. Secondly, you won’t have to worry about fade-out animation — opacity
and transition
does that for us.
Instead of setting display:none
on the tooltip by default, we are going to use opacity:0
. We’re going to set the transition time we need:
.tooltip:before { /* other styles */ /* display:none; */ opacity:0; transition:.3s opacity; }
opacity:0
makes the tooltip transparent. Additionally, transition: .3s opacity
tells the CSS engine to make a transition effect for 0.3 seconds when the opacity changes.
.tooltip:hover:before { opacity:1; }
When you hover over the tooltip, opacity is set to 1 (fully visible). The browser will automatically create both fade-in and fade-out animations for you because we have already set an opacity transition.
You can add the same animation to the tooltip arrow:
.tooltip:after { opacity:0; transition:.3s; } .tooltip:hover:after { opacity:1; }
In this article, we created a tooltip with only CSS (without extra HTML elements).
We used :before
as the tooltip text and :after
as the arrow. Now you understand that writing nested HTML elements below for simple tooltips isn’t necessary.
<span class="tooltip"> Hover over me <span class="tooltip-text"> Some tooltip text </span> </span>
However, our approach has one downside: what if we need to add a link to the tooltip text?
<a>
tags in the data-text
attribute won’t be shown as a link, but as text. Therefore, if you need to include HTML in the tooltip you’ll need to have HTML tags like the above code.
Positioning, adding arrows, and animating those HTML tags is similar to what we did in this article. The only changes are:
.tooltip:before
becomes .tooltip-text
tooltip:after
becomes .tooltip-text:before
or .tooltip-text:after
.In conclusion, we mainly used pseudo elements and content:attr()
to create CSS tooltips. To add arrows, we used a trick with border
. To animate it, we used opacity
and transition
.
The final result was a CSS-only tooltip.
As web frontends get increasingly complex, resource-greedy features demand more and more from the browser. If you’re interested in monitoring and tracking client-side CPU usage, memory usage, and more for all of your users in production, try LogRocket.
LogRocket is like a DVR for web and mobile apps, recording everything that happens in your web app, mobile app, or website. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.
Modernize how you debug web and mobile apps — start monitoring for free.
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowBuild scalable admin dashboards with Filament and Laravel using Form Builder, Notifications, and Actions for clean, interactive panels.
Break down the parts of a URL and explore APIs for working with them in JavaScript, parsing them, building query strings, checking their validity, etc.
In this guide, explore lazy loading and error loading as two techniques for fetching data in React apps.
Deno is a popular JavaScript runtime, and it recently launched version 2.0 with several new features, bug fixes, and improvements […]
16 Replies to "Creating beautiful tooltips with only CSS"
There is a big issue with this tooltip.
Actually, setting its opacity to 0 makes it disappear to the users eyes only, to to their mouse pointer.
So, the tooltip actually shows up even though we don’t hover the triggering element, but also where the tooltip is supposed to be…
Sorry for the delay. Have you tried adding `pointer-events: none` to the tooltip?
I noticed this too, but I found an easy fix! Just add “visibility: hidden;” wherever it says “opacity:0;”, and add “visibility: visible;” wherever it says “opacity:1;”. Should work like a charm.
This does work, but I found that it undoes the transition when you hover off the tooltip (in the case that it contains a link). So, the opacity changes over the specified time when you hover the triggering element, but “snaps” off when you unhover over it or the tooltip itself.
Is there a way to do this with a list of generated items in the tooltip? I tried doing this, but the list has a bunch of text in it instead of actual line breaks. In other words, can it only be text when you use this method to make the tooltip?
For reasons I haven’t figured out, if there are two items with tooltips, one immediately below the other, you can “see through” the upper one to the content of the one below it. With white text, this shows up as imperfections in the letters. The effect is much more apparent with black text on a buff yellow background. The fix is to give the tooltip class a z-index larger than anything else in the area right after “position: absolute;”
I’ve also added “transition-delay: 100ms;” right after transition. I have three tooltips one below the other, and this keeps them from popping in and out if the skims over that area. An intentional hover is needed to make the tooltip disappear.
With the small changes mentioned in the comments, I now have beautiful tooltips. Thank you,
Supun Kavinda!
This is terrific! I saw you wrote that “You can use the same method to create classes for bottom and top positions. Additionally, you’ll need to reset the top value and override the transform value accordingly,” though, and I’ve been playing with the CSS for quite awhile, but can’t fully figure out how to reset and override the CSS correctly to get top and bottom tooltips working–could you (or anyone else seeing this) let me know how I can do this? Any help would be greatly appreciated!
I’m currently having the same issue. Have you been able to find any solutions?
Clearly explained and easy to use. Thanks for this helpful contribution!
Very helpful article, thank you very much!
Great tutorial, helped me very much! Thanx
Is there a workaround for the tooltips being “hidden” by surrounding DIV?
Try using `overflow: visible` on the surrounding div.
Hi All,
I have managed to get the box to appear at the top, however when I apply this effect to the next word in my paragraph which I also want the hover to appear, the second tooltip starts out hovering where the first tooltip was and then when it fades out, it jumps to the second word.
How would I position the second tooltip to appear above the second word initially instead of inheriting the first tooltip position?
Would really appreciate some feedback here.
Thanks,
Simon Carter
Looks and works great, and appreciate the breakdown! Would love to see position top and bottom in these examples. Cheers!