Mesh Gradient Background
Three blurred radial pools over an opaque base - a mesh section that never has to fight its own text for contrast.
6 个框架初级
Solid and outline gradient buttons whose hover shift is an opacity cross-fade, not a repaint.
<!--
The hover shift is two stacked static gradients cross-faded with opacity,
not one gradient with an animated background-position. Position animation
repaints the gradient every frame; an opacity fade is compositor work. The
label sits in its own relative <span> so it stays above both layers.
The outline button is the border-card padding trick at button scale - and
its hover fill reuses the gradient the ring already paints, so the label
flips to white over stops that were chosen to clear AA under white.
-->
<div class="flex w-full flex-col items-stretch justify-center gap-3 sm:flex-row sm:items-center">
<a
href="#"
class="group relative inline-flex w-full items-center justify-center overflow-hidden rounded-lg px-5 py-2.5 text-sm font-semibold text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 focus-visible:ring-offset-2 focus-visible:ring-offset-white sm:w-auto dark:focus-visible:ring-blue-400 dark:focus-visible:ring-offset-gray-900"
>
<span class="absolute inset-0 bg-gradient-to-r from-blue-600 to-violet-600" aria-hidden="true"></span>
<span class="absolute inset-0 bg-gradient-to-r from-violet-600 to-fuchsia-600 opacity-0 transition-opacity duration-300 group-hover:opacity-100 motion-reduce:transition-none" aria-hidden="true"></span>
<span class="relative">Start free trial</span>
</a>
<a
href="#"
class="group relative inline-flex w-full items-center justify-center overflow-hidden rounded-lg bg-gradient-to-r from-blue-600 to-fuchsia-600 p-px text-sm font-semibold focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 focus-visible:ring-offset-2 focus-visible:ring-offset-white sm:w-auto dark:focus-visible:ring-blue-400 dark:focus-visible:ring-offset-gray-900"
>
<span class="inline-flex w-full items-center justify-center rounded-[calc(0.5rem_-_1px)] bg-white px-5 py-2.5 text-gray-900 transition-colors group-hover:bg-transparent group-hover:text-white motion-reduce:transition-none dark:bg-gray-950 dark:text-gray-100">
Book a demo
</span>
</a>
</div>| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
label必填 | string | - | 加载时朗读的无障碍标签。 |
href | string | '#' | 卡片链接到的目标地址。 |
variant | 'solid' | 'outline' | 'solid' | Variant |
className | string | - | 合并到根元素上的额外类名。 |
The hover shift is two stacked static gradients cross-faded with opacity - not one gradient with an animated `background-position`. Position animation repaints the gradient every frame; an opacity fade is compositor work. Recolour by editing both layers of the solid button: the base (`blue → violet`) and the hover layer (`violet → fuchsia`) should share their middle colour or the fade flickers instead of shifting. The label lives in its own `relative` span so it stays above both layers. The outline variant is the border-card padding trick at button scale, and its hover fill reuses the gradient the ring already paints - the label flips to white over stops chosen to clear AA under white in both themes, which is why the gradient has no `dark:` overrides. Buttons go full width below `sm` for tap targets; drop `w-full sm:w-auto` if they live inside a toolbar.