https://github.com/archisvaze/react-tilt-button
A tactile 3D button for React that tilts on hover and squishes on press. Modern and dependency-free.
https://github.com/archisvaze/react-tilt-button
button button-animation css javascript js open-source open-source-project react reactjs
Last synced: about 1 month ago
JSON representation
A tactile 3D button for React that tilts on hover and squishes on press. Modern and dependency-free.
- Host: GitHub
- URL: https://github.com/archisvaze/react-tilt-button
- Owner: archisvaze
- Created: 2026-01-22T03:28:25.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2026-04-04T20:06:22.000Z (2 months ago)
- Last Synced: 2026-04-04T22:35:46.378Z (2 months ago)
- Topics: button, button-animation, css, javascript, js, open-source, open-source-project, react, reactjs
- Language: JavaScript
- Homepage:
- Size: 217 KB
- Stars: 73
- Watchers: 0
- Forks: 4
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# React Tilt Button
> A physical, 3D tactile React button component with tilt, squish, and real depth.
π **Live Demo:** https://react-tilt-button.vercel.app/

Features:
- Tilts on hover (left / middle / right)
- Squishes on press
- Has a visible βside wallβ (depth)
- Enforces physical constraints so it never breaks
- Supports **predefined style variants**
- Is fully configurable via props
Inspired by `react-awesome-button`, but implemented as a small, dependency-free component.
---
## Installation
```bash
npm install react-tilt-button
```
```jsx
import { TiltButton } from 'react-tilt-button';
```
---
## Basic Usage
```jsx
alert('Clicked!')}>Click me
```
---
## Using Variants
Variants are **predefined visual styles** (material / theme presets).
```jsx
Solid
Outline
Arcade
Carbon
Warning
```
You can still override any value manually:
```jsx
Custom Green
```
---
## Demo
Try it live here:
π **https://react-tilt-button.vercel.app/**
The demo lets you:
- Test all variants
- Change geometry (depth, radius, tilt, etc.)
- See physical constraints in action
- Copy settings for your own usage
## Full Example
```jsx
My Button
```
---
## Physical Constraints (Important)
The component automatically clamps values:
- `elevation` β€ `height * 0.3`
- `pressInset` β€ `elevation`
- `tilt` β€ `elevation / 9`
- `radius` β€ `(height - elevation) / 4`
So the button:
- Never crashes
- Never inverts
- Never visually breaks
---
## Props
### Core
| Prop | Type | Default |
| ---------- | --------- | --------- |
| `children` | ReactNode | span |
| `onClick` | function | undefined |
| `disabled` | boolean | `false` |
---
### Variant
| Prop | Type | Default | Description |
| --------- | ------ | ------- | ------------------------------ |
| `variant` | string | `solid` | Predefined visual style preset |
---
### Geometry
| Prop | Type | Default | Notes |
| ------------ | ---------------- | ------- | ----------------------------------------------------- |
| `width` | number \| string | `260` | No max |
| `height` | number \| string | `64` | No max |
| `elevation` | number | `14` | Clamped to `height * 0.3` |
| `pressInset` | number | `5` | Clamped to `<= elevation` |
| `tilt` | number | `2` | Clamped to `<= elevation / 9` |
| `pressTilt` | boolean | `true` | When `true`, the button keeps its skew while pressing |
| `radius` | number | `14` | Clamped to `<= faceHeight / 4` |
| `motion` | number (ms) | `160` | Animation speed |
---
### Colors (Optional Overrides)
These override the selected variant.
| Prop |
| -------------- |
| `surfaceColor` |
| `sideColor` |
| `textColor` |
---
### Border (Optional Overrides)
| Prop |
| ------------- |
| `borderColor` |
| `borderWidth` |
---
## Glare / Specular Highlight (Optional)
The button supports a **dynamic specular glare highlight** that simulates light reflecting off the surface.
It automatically shifts based on hover position (left / middle / right) and fades out on press.
### Props
| Prop | Type | Default | Description |
| -------------- | ------ | --------- | ----------------------------------- |
| `glareColor` | string | `#ffffff` | Color of the glare highlight |
| `glareOpacity` | number | `0` | Intensity of the glare (0 β 1) |
| `glareWidth` | number | `0` | Width of glare band (0 β 100, in %) |
### Example
```jsx
Shiny Button
```
---
### Misc
| Prop | Description |
| ----------- | ------------------------- |
| `className` | Extra classes |
| `style` | Merged into inline styles |
| `...props` | Passed to `` |
---
## Behavior
- Action fires on **mouse release**
- Hover is split into left / middle / right zones
- This is a **physical UI primitive**, not a flat semantic button
---
## Styling
All visuals are driven by CSS variables:
- `--button-raise-level`
- `--press-inset`
- `--button-hover-pressure`
- `--radius`
- `--surface-color`
- `--side-color`
- `--text-color`
- `--border-color`
- `--border-width`
- `--glare-rgb`
- `--glare-alpha`
- `--glare-width`
So you can theme it externally if needed.
---