AI CSS Animations

Social Icons with Tooltip Hover

Each social button fills in and pops a small label above itself with a springy overshoot. The label is real text inside the link, so it doubles as the accessible name.

Also known as: tooltip on hover icons, social media icons with labels, icon label popup css.

HTML

<ul class="hfx-social-icons-tooltip">
  <li><a class="hfx-social-icons-tooltip-link" href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="5" width="18" height="14" rx="2"/><path d="m3.5 7 8.5 6 8.5-6"/></svg><span class="hfx-social-icons-tooltip-tip">Email</span></a></li>
  <li><a class="hfx-social-icons-tooltip-link" href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><path d="m8.6 13.5 6.8 4M15.4 6.5l-6.8 4"/></svg><span class="hfx-social-icons-tooltip-tip">Share</span></a></li>
  <li><a class="hfx-social-icons-tooltip-link" href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 11.5a8.4 8.4 0 0 1-12.2 7.5L3 21l2-5.3A8.5 8.5 0 1 1 21 11.5Z"/></svg><span class="hfx-social-icons-tooltip-tip">Chat</span></a></li>
  <li><a class="hfx-social-icons-tooltip-link" href="#"><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.5"/><path d="M2.5 12h19M12 2.5c2.6 2.6 3.8 5.8 3.8 9.5s-1.2 6.9-3.8 9.5c-2.6-2.6-3.8-5.8-3.8-9.5s1.2-6.9 3.8-9.5Z"/></svg><span class="hfx-social-icons-tooltip-tip">Website</span></a></li>
</ul>

CSS

.hfx-social-icons-tooltip {
  --c: var(--hfx-color, #3b82f6);
  font-size: var(--hfx-size, 16px);
  display: flex;
  align-items: center;
  gap: 0.9em;
  margin: 0;
  padding: 0;
  list-style: none;
}
.hfx-social-icons-tooltip-link {
  position: relative;
  display: grid;
  place-items: center;
  width: 3em;
  height: 3em;
  border-radius: 50%;
  background: color-mix(in srgb, var(--c) 12%, transparent);
  color: var(--c);
  transition: background-color 0.25s ease, color 0.25s ease, transform 0.25s ease;
}
.hfx-social-icons-tooltip-link svg {
  width: 1.3em;
  height: 1.3em;
}
.hfx-social-icons-tooltip-tip {
  position: absolute;
  bottom: calc(100% + 0.9em);
  left: 50%;
  padding: 0.4em 0.65em;
  border-radius: 0.45em;
  background: var(--c);
  color: #fff;
  font: 600 0.75em/1 system-ui, sans-serif;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, 0.6em) scale(0.5);
  transform-origin: 50% 100%;
  transition: opacity 0.2s ease, transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.hfx-social-icons-tooltip-tip::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  margin-left: -0.4em;
  border: 0.4em solid transparent;
  border-top-color: var(--c);
}
.hfx-social-icons-tooltip-link:is(:hover, :focus-visible) {
  background: var(--c);
  color: #fff;
  transform: translateY(-0.15em);
}
.hfx-social-icons-tooltip-link:is(:hover, :focus-visible) .hfx-social-icons-tooltip-tip {
  opacity: 1;
  transform: translate(-50%, 0) scale(1);
}

@media (prefers-reduced-motion: reduce) {
  .hfx-social-icons-tooltip, .hfx-social-icons-tooltip *, .hfx-social-icons-tooltip::before, .hfx-social-icons-tooltip::after, .hfx-social-icons-tooltip *::before, .hfx-social-icons-tooltip *::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.

<ul class="flex gap-3">
  <li>
    <a href="#" class="group relative grid h-11 w-11 place-items-center rounded-full bg-blue-500/10 text-blue-500 transition duration-200 hover:-translate-y-0.5 hover:bg-blue-500 hover:text-white">
      <svg class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="5" width="18" height="14" rx="2"/><path d="m3.5 7 8.5 6 8.5-6"/></svg>
      <span class="pointer-events-none absolute bottom-full left-1/2 mb-3 origin-bottom -translate-x-1/2 translate-y-2 scale-50 whitespace-nowrap rounded-md bg-blue-500 px-2 py-1 text-xs font-semibold text-white opacity-0 transition duration-300 ease-[cubic-bezier(0.34,1.56,0.64,1)] after:absolute after:left-1/2 after:top-full after:-ml-1 after:border-4 after:border-transparent after:border-t-blue-500 after:content-[''] group-hover:translate-y-0 group-hover:scale-100 group-hover:opacity-100">Email</span>
    </a>
  </li>
  <li>
    <a href="#" class="group relative grid h-11 w-11 place-items-center rounded-full bg-blue-500/10 text-blue-500 transition duration-200 hover:-translate-y-0.5 hover:bg-blue-500 hover:text-white">
      <svg class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><path d="m8.6 13.5 6.8 4M15.4 6.5l-6.8 4"/></svg>
      <span class="pointer-events-none absolute bottom-full left-1/2 mb-3 origin-bottom -translate-x-1/2 translate-y-2 scale-50 whitespace-nowrap rounded-md bg-blue-500 px-2 py-1 text-xs font-semibold text-white opacity-0 transition duration-300 ease-[cubic-bezier(0.34,1.56,0.64,1)] after:absolute after:left-1/2 after:top-full after:-ml-1 after:border-4 after:border-transparent after:border-t-blue-500 after:content-[''] group-hover:translate-y-0 group-hover:scale-100 group-hover:opacity-100">Share</span>
    </a>
  </li>
  <li>
    <a href="#" class="group relative grid h-11 w-11 place-items-center rounded-full bg-blue-500/10 text-blue-500 transition duration-200 hover:-translate-y-0.5 hover:bg-blue-500 hover:text-white">
      <svg class="h-5 w-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 11.5a8.4 8.4 0 0 1-12.2 7.5L3 21l2-5.3A8.5 8.5 0 1 1 21 11.5Z"/></svg>
      <span class="pointer-events-none absolute bottom-full left-1/2 mb-3 origin-bottom -translate-x-1/2 translate-y-2 scale-50 whitespace-nowrap rounded-md bg-blue-500 px-2 py-1 text-xs font-semibold text-white opacity-0 transition duration-300 ease-[cubic-bezier(0.34,1.56,0.64,1)] after:absolute after:left-1/2 after:top-full after:-ml-1 after:border-4 after:border-transparent after:border-t-blue-500 after:content-[''] group-hover:translate-y-0 group-hover:scale-100 group-hover:opacity-100">Chat</span>
    </a>
  </li>
  <li>
    <a href="#" class="group relative grid h-11 w-11 place-items-center rounded-full bg-blue-500/10 text-blue-500 transition duration-200 hover:-translate-y-0.5 hover:bg-blue-500 hover:text-white">
      <svg class="h-5 w-5" 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.5"/><path d="M2.5 12h19M12 2.5c2.6 2.6 3.8 5.8 3.8 9.5s-1.2 6.9-3.8 9.5c-2.6-2.6-3.8-5.8-3.8-9.5s1.2-6.9 3.8-9.5Z"/></svg>
      <span class="pointer-events-none absolute bottom-full left-1/2 mb-3 origin-bottom -translate-x-1/2 translate-y-2 scale-50 whitespace-nowrap rounded-md bg-blue-500 px-2 py-1 text-xs font-semibold text-white opacity-0 transition duration-300 ease-[cubic-bezier(0.34,1.56,0.64,1)] after:absolute after:left-1/2 after:top-full after:-ml-1 after:border-4 after:border-transparent after:border-t-blue-500 after:content-[''] group-hover:translate-y-0 group-hover:scale-100 group-hover:opacity-100">Website</span>
    </a>
  </li>
</ul>

Customizing this snippet

  • Color: set --hfx-color on the element or a parent. Currently previewing #3b82f6.
  • Base size: set --hfx-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 hover effects

Profile Card Social Icons Hover
Social Icons Fill Up Hover
Social Icons Flip Hover
Bouncing Social Icons Hover