Botón neobrutalista
Borde grueso, color plano y sombra dura que se aplasta al presionar.
Código completo
Es exactamente el archivo que se descarga. Cópialo a tu proyecto y úsalo.
/**
* Botón neobrutalista: borde grueso, color plano y sombra dura que se aplasta al presionar.
*
* <BrutalistButton>Empezar gratis</BrutalistButton>
* <BrutalistButton tone="pink">Ver precios</BrutalistButton>
*/
import type { ButtonHTMLAttributes, CSSProperties } from "react";
const TONES = {
sun: "#ffd23f",
pink: "#ff7ab8",
mint: "#5eead4",
sky: "#7cc4ff",
white: "#ffffff",
} as const;
export type BrutalistButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
tone?: keyof typeof TONES;
};
const CSS = `
.gcb-btn { --gcb-ink: #111111; display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-height: 54px; padding: 0 26px;
border: 3px solid var(--gcb-ink); border-radius: 10px; background: var(--gcb-bg); color: var(--gcb-ink);
font-family: inherit; font-size: 16px; font-weight: 900; line-height: 1; letter-spacing: .02em; text-transform: uppercase; cursor: pointer;
box-shadow: 6px 6px 0 var(--gcb-ink); transition: transform .12s ease-out, box-shadow .12s ease-out; }
.gcb-btn:hover { transform: translate(-2px, -2px); box-shadow: 8px 8px 0 var(--gcb-ink); }
.gcb-btn:active { transform: translate(6px, 6px); box-shadow: 0 0 0 var(--gcb-ink); }
.gcb-btn:focus-visible { outline: 3px solid var(--gcb-ink); outline-offset: 5px; }
.gcb-btn:disabled { opacity: .55; cursor: not-allowed; transform: none; box-shadow: 3px 3px 0 var(--gcb-ink); }
.gcb-btn svg { width: 20px; height: 20px; stroke-width: 3; }
@media (prefers-reduced-motion: reduce) { .gcb-btn { transition: none; } }
`;
export function BrutalistButton({ tone = "sun", className, style, children, ...props }: BrutalistButtonProps) {
return (
<>
<style>{CSS}</style>
<button type="button" {...props} className={["gcb-btn", className].filter(Boolean).join(" ")} style={{ ["--gcb-bg" as string]: TONES[tone], ...style } as CSSProperties}>
{children}
</button>
</>
);
}
Úsalo en tu proyecto
Instálalo con la CLI de shadcn.
npx shadcn@latest add https://www.gassierconsulting.com/r/boton-brutalistaEjemplo de uso de Botón neobrutalista
Después de copiar brutalist-button.tsx a tu proyecto, impórtalo y colócalo donde lo necesites.
import { BrutalistButton } from "./brutalist-button";
export default function Ejemplo() {
return <BrutalistButton />;
}Accesibilidad y rendimiento
El archivo tiene 45 líneas (2 KB) y no necesita @keyframes. Esto es lo que hace Botón neobrutalista por quien lo usa:
- Detecta prefers-reduced-motion y baja o quita el movimiento cuando la persona lo pide.
- Muestra un anillo de foco visible al navegar con teclado (:focus-visible).
Acerca del producto
Un botón neobrutalista: borde negro de 3 px, color plano y sombra sólida sin desenfoque que se aplasta al presionar. Cinco colores listos.
Incluye
Un solo archivo React + TypeScript, con los estilos dentro. No usa Tailwind ni bibliotecas externas.
- Cinco tonos: sol, rosa, menta, cielo y blanco
- Sin estado ni JavaScript: es solo CSS
- Texto en mayúsculas de peso 900
- Respeta prefers-reduced-motion
Cómo usarlo
Funciona sobre fondos claros y lisos. Cambia el tono con la propiedad tone.