Skip to content

Thumbs React

A copy-paste micro-interactions component in pure HTML, CSS & vanilla JS. Zero dependencies, framework-agnostic, MIT-licensed.

Micro-interactionsHTMLCSSJavaScriptany framework

Copy into your project

HTML
<button class="nuda-thumbs-react" aria-label="Thumbs up" aria-pressed="false">
  <svg viewBox="0 0 24 24" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
    <path d="M7 10v12"/>
    <path d="M15 5.88L14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88z"/>
  </svg>
  <span class="nuda-thumbs-react__burst" aria-hidden="true"></span>
</button>
CSS
/* Thumbs React — thumbs-up pops and a ring bursts outward on click. */
.nuda-thumbs-react {
  position: relative;
  background: none;
  border: none;
  cursor: pointer;
  padding: 8px;
  outline: none;
}

.nuda-thumbs-react svg {
  width: 26px;
  height: 26px;
  fill: none;
  stroke: #777;
  transition: fill 0.25s, stroke 0.25s,
    transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.nuda-thumbs-react[aria-pressed="true"] svg {
  fill: #e4ff54;
  stroke: #e4ff54;
}

.nuda-thumbs-react.is-up svg {
  animation: nuda-thumbs-pop 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.nuda-thumbs-react__burst {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 2px solid #e4ff54;
  opacity: 0;
  transform: scale(0.4);
  pointer-events: none;
}

.nuda-thumbs-react.is-up .nuda-thumbs-react__burst {
  animation: nuda-thumbs-burst 0.6s ease-out;
}

@keyframes nuda-thumbs-pop {
  0%   { transform: scale(1) rotate(0); }
  40%  { transform: scale(1.3) rotate(-12deg); }
  100% { transform: scale(1) rotate(0); }
}

@keyframes nuda-thumbs-burst {
  0%   { opacity: 0.8; transform: scale(0.4); }
  100% { opacity: 0; transform: scale(1.6); }
}

.nuda-thumbs-react:focus-visible {
  outline: 2px solid #e4ff54;
  outline-offset: 3px;
  border-radius: 8px;
}

@media (prefers-reduced-motion: reduce) {
  .nuda-thumbs-react svg { transition: none; }
  .nuda-thumbs-react.is-up svg,
  .nuda-thumbs-react.is-up .nuda-thumbs-react__burst { animation: none; }
}
JavaScript
/* Thumbs React — vanilla JS
   Toggles liked state and fires the pop + burst. */
(function () {
  document.querySelectorAll(".nuda-thumbs-react").forEach(function (btn) {
    btn.addEventListener("click", function () {
      var pressed = btn.getAttribute("aria-pressed") === "true";
      btn.setAttribute("aria-pressed", String(!pressed));
      if (!pressed) {
        btn.classList.add("is-up");
        setTimeout(function () { btn.classList.remove("is-up"); }, 600);
      }
    });
  });
})();

How to use Thumbs React

Paste the HTML where you need it and the CSS into a global stylesheet (or a <style> tag). Every class is prefixed nuda- so it never collides with Tailwind or your own styles. Tweak the CSS custom properties to match your design system.

Works in React, Vue, Svelte, Astro, Next.js, Nuxt, Laravel Blade, Django, Rails — or a single .html file. No npm install, no build step.

More micro-interactions components

← Browse all NudaUI components