AI CSS Animations

Tooltip for Truncated Text

A file chip cut off with an ellipsis that reveals the full name on hover, wiping out from the left edge. Align it to the start and move the arrow with the --arrow property.

Also known as: ellipsis tooltip css, show full text on hover, text overflow tooltip.

board-review-final-v7-approved.pdf

HTML

<span class="tip-truncated-text" tabindex="0">
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z"/><path d="M14 3v5h5"/></svg>
  <span class="tip-truncated-text-name">board-review-final-v7-approved.pdf</span>
  <span class="tip-truncated-text-tip" role="tooltip" aria-hidden="true">board-review-final-v7-approved.pdf</span>
</span>

CSS

.tip-truncated-text {
  --c: var(--tip-color, #3b82f6);
  font-size: var(--tip-size, 16px);
  position: relative;
  display: inline-flex;
  --arrow: 1.5em;
  box-sizing: border-box;
  align-items: center;
  gap: 0.5em;
  width: 12em;
  padding: 0.55em 0.8em;
  border: 1px solid color-mix(in srgb, var(--c) 30%, transparent);
  border-radius: 0.6em;
  background: color-mix(in srgb, var(--c) 7%, transparent);
  cursor: default;
}
.tip-truncated-text:focus-visible {
  outline: 2px solid var(--c);
  outline-offset: 2px;
}
.tip-truncated-text svg {
  flex: none;
  width: 1.2em;
  height: 1.2em;
  color: var(--c);
}
.tip-truncated-text-name {
  min-width: 0;
  overflow: hidden;
  font: 500 0.9em/1.3 system-ui, sans-serif;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* the screen reader already reads the full name, so the bubble is aria-hidden */
.tip-truncated-text-tip {
  position: absolute;
  bottom: calc(100% + 0.6em);
  left: 0;
  z-index: 10;
  padding: 0.45em 0.75em;
  border-radius: 0.45em;
  background: color-mix(in srgb, var(--c) 14%, #0f172a);
  color: #fff;
  font: 500 0.85em/1.3 system-ui, sans-serif;
  white-space: nowrap;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  clip-path: inset(-0.5em 100% -0.8em -0.5em);
  transition: opacity 0.15s ease, clip-path 0.2s ease, visibility 0.2s;
}
.tip-truncated-text-tip::before {
  content: "";
  position: absolute;
  top: 100%;
  left: var(--arrow);
  width: 0.6em;
  height: 0.6em;
  background: inherit;
  transform: translate(-50%, -50%) rotate(45deg);
}
.tip-truncated-text:hover .tip-truncated-text-tip,
.tip-truncated-text:focus-within .tip-truncated-text-tip {
  opacity: 1;
  visibility: visible;
  clip-path: inset(-0.5em -0.5em -0.8em -0.5em);
  transition: opacity 0.15s ease, clip-path 0.45s cubic-bezier(0.65, 0, 0.35, 1), visibility 0s;
}

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

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