← Back to CSS Course | Chapter 5: Layout & Display | Lesson 11 of 14

CSS Tooltips

Think of a museum placard that's normally folded flat against the wall, invisible, and only flips open when a visitor leans in close to read the plaque underneath a painting. A pure-CSS tooltip works the same way: it stays hidden until :hover 'leans in,' then a positioned pseudo-element flips into view -- no JavaScript required.

The Basic Tooltip Structure

A CSS-only tooltip typically wraps a trigger element and a hidden tooltip element in one container, using position: relative on the container so the tooltip (position: absolute) can be placed relative to it, and starting the tooltip at visibility: hidden or opacity: 0.

Example: The Basic Tooltip Structure

css
<style>
.tooltip {
  position: relative;
  display: inline-block;
}
.tip {
  position: absolute;
  opacity: 0;
  background: #333;
  color: white;
  padding: 6px 10px;
  border-radius: 4px;
}
.tooltip:hover .tip {
  opacity: 1;
}
</style>
<div class="tooltip">
  Hover me
  <span class="tip">Tooltip text</span>
</div>

Revealing on :hover

The tooltip becomes visible by targeting the tooltip element through its parent's :hover state, so no JavaScript event listener is needed -- the browser's own hover pseudo-class does the toggling.

Example: Revealing on :hover

css
<style>
.tooltip {
  position: relative;
  display: inline-block;
}
.tooltip .tip {
  background: #333;
  color: white;
  padding: 6px 10px;
  border-radius: 4px;
  opacity: 0;
}
.tooltip:hover .tip {
  opacity: 1;
}
</style>
<div class="tooltip">
  Hover me
  <span class="tip">Shown via the parent's :hover</span>
</div>

Positioning the Tooltip

The tooltip's exact placement above, below, or beside the trigger is controlled with top/bottom/left/right offsets plus a transform: translateX(-50%) trick to horizontally center it regardless of the trigger's width.

Example: Positioning the Tooltip

css
<style>
.tooltip {
  position: relative;
  display: inline-block;
}
.tip {
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  background: #333;
  color: white;
  padding: 6px 10px;
  border-radius: 4px;
  opacity: 0;
}
.tooltip:hover .tip {
  opacity: 1;
}
</style>
<div class="tooltip">
  Hover me
  <span class="tip">Centered above the trigger</span>
</div>

Adding an Arrow Pointer

A small triangular arrow pointing from the tooltip toward the trigger is commonly built with a ::after pseudo-element using zero width/height and transparent borders on three sides, a classic CSS-triangle technique.

Example: Adding an Arrow Pointer

css
<style>
.tip {
  display: inline-block;
  background: #333;
  color: white;
  padding: 6px 10px;
  border-radius: 4px;
  position: relative;
}
.tip::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 20px;
  width: 0;
  height: 0;
  border: 6px solid transparent;
  border-top-color: #333;
}
</style>
<span class="tip">Tooltip with a triangle arrow</span>

Accessibility Considerations

A purely :hover-based tooltip is invisible to keyboard-only users, so accessible implementations also trigger visibility on :focus (for keyboard tab navigation) and pair the markup with an aria-describedby attribute linking the trigger to the tooltip text.

Example: Accessibility Considerations

css
<style>
.tooltip {
  position: relative;
}
.tip {
  position: absolute;
  background: #333;
  color: white;
  padding: 6px 10px;
  border-radius: 4px;
  opacity: 0;
}
.tooltip:hover .tip,
.tooltip:focus .tip {
  opacity: 1;
}
</style>
<button class="tooltip" aria-describedby="tip1">
  Hover or Tab
  <span class="tip" id="tip1">Also visible on keyboard focus</span>
</button>

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.