shadcn.io is not affiliated with official shadcn/ui
Shadcn Hitbox for React and Tailwind
Expand hit areas of interactive elements without affecting layout.
Installation
bunx --bun shadcn@latest add https://kit.dev/r/hitbox.jsonpnpm dlx shadcn@latest add https://kit.dev/r/hitbox.jsonnpx shadcn@latest add https://kit.dev/r/hitbox.jsonyarn shadcn@latest add https://kit.dev/r/hitbox.jsonAdd the following to your globals.css.
:root {
--destructive-foreground: var(--color-red-700);
--info: var(--color-blue-500);
--info-foreground: var(--color-blue-700);
--success: var(--color-emerald-500);
--success-foreground: var(--color-emerald-700);
--warning: var(--color-amber-500);
--warning-foreground: var(--color-amber-700);
}
.dark {
--destructive-foreground: var(--color-red-400);
--info: var(--color-blue-500);
--info-foreground: var(--color-blue-400);
--success: var(--color-emerald-500);
--success-foreground: var(--color-emerald-400);
--warning: var(--color-amber-500);
--warning-foreground: var(--color-amber-400);
}
@utility hitbox-debug {
position: relative;
&::before {
position: absolute;
top: var(--hitbox-t, 0px);
right: var(--hitbox-r, 0px);
bottom: var(--hitbox-b, 0px);
left: var(--hitbox-l, 0px);
pointer-events: inherit;
content: "";
@apply border border-dashed border-info bg-info/10 {
}
}
&:hover::before {
@apply border border-dashed border-success bg-success/10 {
}
}
}
@utility hitbox {
position: relative;
&::before {
position: absolute;
top: var(--hitbox-t, 0px);
right: var(--hitbox-r, 0px);
bottom: var(--hitbox-b, 0px);
left: var(--hitbox-l, 0px);
pointer-events: inherit;
content: "";
}
}
@utility hitbox-* {
--hitbox-t: calc(--value([*]) * -1);
--hitbox-b: calc(--value([*]) * -1);
--hitbox-l: calc(--value([*]) * -1);
--hitbox-r: calc(--value([*]) * -1);
position: relative;
&::before {
position: absolute;
top: var(--hitbox-t, 0px);
right: var(--hitbox-r, 0px);
bottom: var(--hitbox-b, 0px);
left: var(--hitbox-l, 0px);
pointer-events: inherit;
content: "";
}
}
@utility hitbox-l-* {
--hitbox-l: calc(--value([*]) * -1);
position: relative;
&::before {
position: absolute;
top: var(--hitbox-t, 0px);
right: var(--hitbox-r, 0px);
bottom: var(--hitbox-b, 0px);
left: var(--hitbox-l, 0px);
pointer-events: inherit;
content: "";
}
}
@utility hitbox-r-* {
--hitbox-r: calc(--value([*]) * -1);
position: relative;
&::before {
position: absolute;
top: var(--hitbox-t, 0px);
right: var(--hitbox-r, 0px);
bottom: var(--hitbox-b, 0px);
left: var(--hitbox-l, 0px);
pointer-events: inherit;
content: "";
}
}
@utility hitbox-t-* {
--hitbox-t: calc(--value([*]) * -1);
position: relative;
&::before {
position: absolute;
top: var(--hitbox-t, 0px);
right: var(--hitbox-r, 0px);
bottom: var(--hitbox-b, 0px);
left: var(--hitbox-l, 0px);
pointer-events: inherit;
content: "";
}
}
@utility hitbox-b-* {
--hitbox-b: calc(--value([*]) * -1);
position: relative;
&::before {
position: absolute;
top: var(--hitbox-t, 0px);
right: var(--hitbox-r, 0px);
bottom: var(--hitbox-b, 0px);
left: var(--hitbox-l, 0px);
pointer-events: inherit;
content: "";
}
}
@utility hitbox-x-* {
--hitbox-l: calc(--value([*]) * -1);
--hitbox-r: calc(--value([*]) * -1);
position: relative;
&::before {
position: absolute;
top: var(--hitbox-t, 0px);
right: var(--hitbox-r, 0px);
bottom: var(--hitbox-b, 0px);
left: var(--hitbox-l, 0px);
pointer-events: inherit;
content: "";
}
}
@utility hitbox-y-* {
--hitbox-t: calc(--value([*]) * -1);
--hitbox-b: calc(--value([*]) * -1);
position: relative;
&::before {
position: absolute;
top: var(--hitbox-t, 0px);
right: var(--hitbox-r, 0px);
bottom: var(--hitbox-b, 0px);
left: var(--hitbox-l, 0px);
pointer-events: inherit;
content: "";
}
}Update the import paths to match your project setup.
Usage
import React from "react";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { Field, FieldLabel } from "@/components/ui/field";
import { Switch } from "@/components/ui/switch";const Example = () => {
const [show, setShow] = React.useState(true);
return (
<div className="relative flex size-full items-center justify-center">
<div className="absolute top-2 right-2">
<Field orientation="horizontal">
<Switch
checked={show}
onCheckedChange={({ checked }) => setShow(checked)}
/>
<FieldLabel>Show hitbox</FieldLabel>
</Field>
</div>
<Button
className={cn("group/hitbox hitbox-6 w-28", { "hitbox-debug": show })}
clickEffect={false}
size="lg"
>
<span className="font-mono group-hover/hitbox:hidden">hit-area-6</span>
<span className="not-group-hover/hitbox:hidden group-active:hidden">
Hovered
</span>
<span className="not-group-active/hitbox:hidden">Pressed</span>
</Button>
</div>
);
};Demos
Axes
Basic
Custom
Debug
Sidebar
Sides
API Reference
Hitbox
ClassType