Stackbits
Buttons > Cloth Button

🔍 Cloth Button

Elevate your interface with the Cloth Button, a texture-inspired React component designed for a tactile user experience. Ideal for primary actions, form submissions, or interactive elements, this button enhances visual appeal with its fabric-like appearance—whether it's used for navigation, confirmations, or key user interactions. The subtle textile styling adds dimension and uniqueness to your application.

Meet the Designer

All the design credits goes to

Preview

Follow below steps 👇🏻

Install dependencies

1
npm i clsx tailwind-merge

Utils

Create a lib/utils.ts file and paste this code

1
import { ClassValue, clsx } from 'clsx';
2
import { twMerge } from 'tailwind-merge';
3
4
export function cn(...inputs: ClassValue[]) {
5
return twMerge(clsx(inputs));
6
}

Component

Create a file cloth-button.tsx in your components folder and paste this code

1
import React from 'react';
2
import { ClassValue } from 'clsx';
3
import { cn } from '@/lib/utils';
4
5
type ClothButtonProps = {
6
children: React.ReactNode;
7
className?: ClassValue;
8
} & React.ButtonHTMLAttributes<HTMLButtonElement>;
9
10
const ClothButton = ({ children, className, ...props }: ClothButtonProps) => {
11
return (
12
<button
13
{...props}
14
className={cn('bg-slate-100/95 rounded-full overflow-hidden relative', className)}
15
>
16
<div
17
className={cn(
18
'absolute inset-0',
19
'[background-size:3px_3px]',
20
'[background-image:linear-gradient(45deg,rgba(255,255,255,0.4)_1px,transparent_1px),linear-gradient(135deg,rgba(255,255,255,0.4)_1px,transparent_1px)]'
21
)}
22
style={{
23
transformOrigin: 'center center'
24
}}
25
/>
26
27
<div
28
className={cn(
29
'absolute inset-0',
30
'[background-size:3px_3px]',
31
'[background-image:linear-gradient(45deg,transparent_45%,rgba(0,0,0,0.1)_45%,rgba(0,0,0,0.1)_55%,transparent_55%),linear-gradient(135deg,transparent_45%,rgba(0,0,0,0.1)_45%,rgba(0,0,0,0.1)_55%,transparent_55%)]'
32
)}
33
style={{
34
transformOrigin: 'center center'
35
}}
36
/>
37
38
<div
39
className={cn(
40
'absolute inset-0',
41
'[background-size:6px_6px]',
42
'[background-image:radial-gradient(circle,rgba(255,255,255,1)_0.3px,transparent_0.2px)]'
43
)}
44
/>
45
46
<div
47
className={cn(
48
'absolute inset-0',
49
'[background-size:3px_3px]',
50
'[background-image:radial-gradient(circle,rgba(0,0,0,0.3)_0.3px,transparent_0.2px)]'
51
)}
52
/>
53
54
<div
55
style={{
56
boxShadow: 'inset 0px 0px 4px 1px rgba(0, 0, 0, 1)'
57
}}
58
className="absolute inset-0 rounded-full"
59
/>
60
61
<div
62
className={cn(
63
'm-0.5 px-6 py-3 rounded-full relative overflow-hidden',
64
'group hover:shadow-black/50 hover:shadow-md transition-all duration-200'
65
)}
66
>
67
<div
68
className={cn(
69
'absolute inset-0',
70
'[background-size:3px_3px]',
71
'[background-image:linear-gradient(45deg,rgba(255,255,255,0.4)_1px,transparent_1px),linear-gradient(135deg,rgba(255,255,255,0.4)_1px,transparent_1px)]'
72
)}
73
style={{
74
transformOrigin: 'center center'
75
}}
76
/>
77
78
<div
79
className={cn(
80
'absolute inset-0',
81
'[background-size:3px_3px]',
82
'[background-image:linear-gradient(45deg,transparent_45%,rgba(0,0,0,0.1)_45%,rgba(0,0,0,0.1)_55%,transparent_55%),linear-gradient(135deg,transparent_45%,rgba(0,0,0,0.1)_45%,rgba(0,0,0,0.1)_55%,transparent_55%)]'
83
)}
84
style={{
85
transformOrigin: 'center center'
86
}}
87
/>
88
89
<div
90
className={cn(
91
'absolute inset-0',
92
'[background-size:6px_6px]',
93
'[background-image:radial-gradient(circle,rgba(255,255,255,1)_0.3px,transparent_0.2px)]'
94
)}
95
/>
96
97
<div
98
className={cn(
99
'absolute inset-0',
100
'[background-size:3px_3px]',
101
'[background-image:radial-gradient(circle,rgba(0,0,0,0.3)_0.3px,transparent_0.2px)]'
102
)}
103
/>
104
105
<div className="absolute inset-0 rounded-full shadow-inner shadow-black/30 border-[1px] border-transparent border-dashed group-hover:border-white/10 group-hover:shadow-white/40 group-active:shadow-black transition-all duration-200 bg-gradient-to-r from-[#111e29]/60 to-[#041624]/60" />
106
107
<div className="absolute inset-0 rounded-full border-[1px] border-dashed border-white/10" />
108
109
<div className="relative inline-block ">
110
<div
111
style={{
112
textShadow: '0px 0.5px 1px rgba(0, 0, 0, 1)',
113
color: 'rgba(50, 50, 50, 0.9)',
114
position: 'absolute',
115
filter: 'blur(0.5px)',
116
top: '1px',
117
left: '0px',
118
zIndex: 1
119
}}
120
className="font-semibold"
121
>
122
{children}
123
</div>
124
125
<div
126
style={{
127
position: 'absolute',
128
top: '-0.5px',
129
left: '0.1px',
130
zIndex: 2
131
}}
132
className="text-white/50 font-semibold whitespace-nowrap"
133
>
134
{children}
135
</div>
136
137
<div
138
style={{
139
position: 'relative',
140
zIndex: 3
141
}}
142
className="bg-clip-text text-transparent bg-gradient-to-r from-[#d7e3ef] via-[#6E818F] to-[#4e606e] font-semibold"
143
>
144
{children}
145
</div>
146
</div>
147
</div>
148
</button>
149
);
150
};
151
152
export default ClothButton;

Usage

1
<ClothButton>
2
<p>Cloth Button</p>
3
</ClothButton>

⭐️ Got a question or feedback?
Feel free to reach out!