tailwind1-9 Exercise 3: An Animation, a Breakpoint and a Variable JavaScript Can Read ===================================================================================== input.css: @import "tailwindcss"; @theme { --animate-wiggle: wiggle 1s ease-in-out infinite; @keyframes wiggle { 0%, 100% { transform: rotate(-3deg); } 50% { transform: rotate(3deg); } } --breakpoint-xs: 30rem; } @theme static { --color-primary: var(--color-red-500); } page.html:
(1) The animation. In the console: const el = document.getElementById('w'); console.log(getComputedStyle(el).animationName, el.getAnimations().length); const a = getComputedStyle(el).transform; setTimeout(() => console.log(a !== getComputedStyle(el).transform), 350); Measured: animation-name: wiggle, getAnimations().length: 1 transform at one moment: matrix(0.998817, 0.0486202, -0.0486202, 0.998817, 0, 0) (about +2.8 degrees) 350ms later: matrix(0.99892, -0.046464, 0.046464, 0.99892, 0, 0) (about -2.7 degrees) so the transform changed: true (2) The breakpoint. Resize the viewport (DevTools device toolbar) to 479px and to 480px: 479px gray (base) 480px red (xs: applies from 30rem = 480px) (3) static versus plain. A page where NO class mentions "primary", reading the variable from JavaScript: getComputedStyle(document.documentElement).getPropertyValue('--color-primary') with @theme static { --color-primary: var(--color-red-500); } "oklch(63.7% 0.237 25.331)" with a plain @theme { --color-primary: var(--color-red-500); } "" (empty: the variable was not written) WHY THIS WORKS AS AN ANSWER --------------------------- (1) Putting @keyframes inside @theme next to the --animate-* variable means Tailwind writes the animation class and its keyframes together. The proof that it really runs is the pair of facts: the browser lists one running animation on the element, and the element's transform differs between two samples taken apart in time, swinging between roughly +3 and -3 degrees as the keyframes say. (Add motion-safe: in front of animate-wiggle so people who ask for reduced motion do not get it.) (2) --breakpoint-xs adds a new screen variant: the compiled media query is (width >= 30rem), inclusive, so 479px misses it and 480px has it, just like the built-in sm, md and the rest. (3) Tailwind only writes the theme variables that a class uses, so a plain @theme variable that nothing mentions never reaches the page and JavaScript reads an empty string. @theme static says "write it anyway", and as the value shows, the variable it points at (red-500) is written too, so the reference resolves.