AI CSS Animations

Info Icon Tooltip

A small info icon beside a form label that opens a wrapping help text to its right. Only the icon triggers it: the label ignores the pointer, the icon opts back in.

Also known as: info icon hover text css, help icon tooltip, question mark tooltip css.

Monthly budget Spending pauses when you reach this limit. You can raise it at any time.

HTML

<span class="tip-info-icon">
  Monthly budget
  <button type="button" aria-label="About monthly budget" aria-describedby="tip-info-icon-tip"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="9"/><path d="M12 11v5.5M12 7.6v.1"/></svg></button>
  <span class="tip-info-icon-tip" id="tip-info-icon-tip" role="tooltip">Spending pauses when you reach this limit. You can raise it at any time.</span>
</span>

CSS

.tip-info-icon {
  --c: var(--tip-color, #3b82f6);
  font-size: var(--tip-size, 16px);
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.3em;
  margin-right: 8em; /* room for the tooltip in this preview */
  font-family: system-ui, sans-serif;
  font-weight: 600;
  pointer-events: none; /* only the icon opens the tooltip */
}
.tip-info-icon button {
  display: grid;
  place-items: center;
  width: 1.6em;
  height: 1.6em;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: color-mix(in srgb, currentColor 50%, transparent);
  cursor: help;
  pointer-events: auto;
  transition: color 0.2s ease;
}
.tip-info-icon svg {
  width: 1.2em;
  height: 1.2em;
}
.tip-info-icon:hover button { color: var(--c); }
.tip-info-icon button:focus-visible {
  outline: 2px solid var(--c);
  outline-offset: 2px;
}
.tip-info-icon-tip {
  position: absolute;
  top: 50%;
  left: calc(100% + 0.7em);
  z-index: 10;
  width: max-content;
  max-width: 13em;
  padding: 0.6em 0.8em;
  border: 1px solid rgb(15 23 42 / 0.12);
  border-radius: 0.55em;
  background: #fff;
  box-shadow: 0 0.6em 1.2em -0.5em rgb(15 23 42 / 0.35);
  color: #334155;
  font: 400 0.8em/1.45 system-ui, sans-serif;
  text-wrap: balance;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transform: translate(-0.5em, -50%);
  transition: opacity 0.18s ease, transform 0.25s cubic-bezier(0.2, 0.8, 0.2, 1), visibility 0.25s;
}
.tip-info-icon-tip::before {
  content: "";
  position: absolute;
  top: 50%;
  right: 100%;
  box-sizing: border-box;
  width: 0.75em;
  height: 0.75em;
  border: inherit;
  border-top: 0;
  border-right: 0;
  border-radius: 0 0 0 0.12em;
  background: inherit;
  transform: translate(55%, -50%) rotate(45deg);
}
.tip-info-icon:hover .tip-info-icon-tip,
.tip-info-icon:focus-within .tip-info-icon-tip {
  opacity: 1;
  visibility: visible;
  transform: translate(0, -50%);
}

@media (prefers-reduced-motion: reduce) {
  .tip-info-icon, .tip-info-icon *, .tip-info-icon::before, .tip-info-icon::after, .tip-info-icon *::before, .tip-info-icon *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

Tailwind CSS version

The same effect using Tailwind utility classes. No custom CSS or config needed.

<span class="group pointer-events-none relative mr-36 inline-flex items-center gap-1 font-semibold">
  Monthly budget
  <button type="button" aria-label="About monthly budget" aria-describedby="tooltip-budget" class="pointer-events-auto grid h-6 w-6 cursor-help place-items-center rounded-full text-slate-400 transition-colors group-hover:text-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-500">
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" class="h-5 w-5" aria-hidden="true"><circle cx="12" cy="12" r="9"/><path d="M12 11v5.5M12 7.6v.1"/></svg>
  </button>
  <span id="tooltip-budget" role="tooltip" class="invisible absolute left-[calc(100%+0.6rem)] top-1/2 z-10 w-max max-w-[12rem] -translate-x-2 -translate-y-1/2 text-balance rounded-lg border border-slate-200 bg-white px-3 py-2 text-xs font-normal leading-relaxed text-slate-600 opacity-0 shadow-lg transition-all duration-200 before:absolute before:right-full before:top-1/2 before:h-2.5 before:w-2.5 before:-translate-y-1/2 before:translate-x-1/2 before:rotate-45 before:border-b before:border-l before:border-slate-200 before:bg-white before:content-[''] group-hover:visible group-hover:translate-x-0 group-hover:opacity-100 group-focus-within:visible group-focus-within:translate-x-0 group-focus-within:opacity-100">Spending pauses when you reach this limit. You can raise it at any time.</span>
</span>

Customizing this snippet

  • Color: set --tip-color on the element or a parent. Currently previewing #3b82f6.
  • Base size: set --tip-size. Every other dimension is in em, so the whole thing scales together. Currently previewing 16px.
  • Speed: change the duration on the transition or animation shorthand. Staggered delays are relative, so they keep their rhythm.
  • Reduced motion: the rule at the end of the CSS turns the motion off for people who asked their OS for less of it. Keep it.

Similar tooltips