51 CSS Buttons33 / 51
CSS Masking Tape Label Button
A strip of drafting tape stuck slightly crooked: translucent so the surface shows through, fibrous weave running lengthwise, ragged torn ends cut by a repeating mask, and a hand-written label. Hover presses the tape flatter; pressing sticks it down.
Published Updated
The code
<div class="cb-33">
<div class="cb-33__stage">
<button class="cb-33__btn" type="button">
<span class="cb-33__label">pin this for later</span>
</button>
</div>
</div><div class="cb-33">
<div class="cb-33__stage">
<button class="cb-33__btn" type="button">
<span class="cb-33__label">pin this for later</span>
</button>
</div>
</div>@import url('https://fonts.googleapis.com/css2?family=Caveat:wght@500;600;700&display=swap');
.cb-33 {
--bg: #dfd8c8;
--tape: rgba(238,226,190,.9);
--tape-2: rgba(222,206,164,.92);
--ink: #3a3226;
--hand: "Caveat",ui-rounded,"Comic Sans MS",cursive;
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: repeating-linear-gradient(0deg, rgba(0,0,0,.03) 0 1px, transparent 1px 1.75rem), repeating-linear-gradient(90deg, rgba(0,0,0,.03) 0 1px, transparent 1px 1.75rem), var(--bg);
font-family: var(--hand);
}
@supports (color: oklch(50% 0 0)) {
.cb-33 {
--bg: oklch(88% .022 88);
--ink: oklch(30% .02 75);
}
}
@media (prefers-color-scheme: dark) {
.cb-33:not([data-theme="light"]) {
--bg: #26231d;
--tape: rgba(206,190,150,.86);
--tape-2: rgba(184,168,128,.9);
--ink: #2b251b;
}
}
.cb-33[data-theme="dark"] {
--bg: #26231d;
--tape: rgba(206,190,150,.86);
--tape-2: rgba(184,168,128,.9);
--ink: #2b251b;
}
.cb-33,
.cb-33 *,
.cb-33 *::before,
.cb-33 *::after {
box-sizing: border-box;
}
.cb-33__stage {
min-height: 100vh;
min-height: 100svh;
display: grid;
place-items: center;
padding: clamp(1.5rem,6vw,4rem);
}
.cb-33__btn {
cursor: pointer;
border: 0;
padding: .85rem 2.4rem;
border-radius: 0;
font: inherit;
font-size: 1.5rem;
font-weight: 600;
letter-spacing: .01em;
color: var(--ink);
background-color: var(--tape);
background-image: repeating-linear-gradient(90deg, rgba(255,255,255,.22) 0 1px, transparent 1px 2px), repeating-linear-gradient(90deg, rgba(0,0,0,.045) 0 1px, transparent 1px 5px), linear-gradient(102deg, rgba(255,255,255,.3), transparent 40%, rgba(0,0,0,.07)), linear-gradient(180deg, var(--tape), var(--tape-2));
-webkit-mask: radial-gradient(.22rem .3rem at 0 50%, transparent 96%, #000 0) 0 0/.42rem .5rem repeat-y, radial-gradient(.22rem .3rem at 100% 50%, transparent 96%, #000 0) 100% 0/.42rem .5rem repeat-y, linear-gradient(#000,#000) .4rem 0/calc(100% - .8rem) 100% no-repeat;
mask: radial-gradient(.22rem .3rem at 0 50%, transparent 96%, #000 0) 0 0/.42rem .5rem repeat-y, radial-gradient(.22rem .3rem at 100% 50%, transparent 96%, #000 0) 100% 0/.42rem .5rem repeat-y, linear-gradient(#000,#000) .4rem 0/calc(100% - .8rem) 100% no-repeat;
rotate: -1.7deg;
filter: drop-shadow(0 4px 5px rgba(60,48,30,.28));
transition: rotate .4s cubic-bezier(.16,1,.3,1), translate .4s cubic-bezier(.16,1,.3,1), filter .35s ease;
-webkit-tap-highlight-color: transparent;
}
.cb-33__label {
display: inline-block;
transition: rotate .4s cubic-bezier(.16,1,.3,1);
}
.cb-33__btn:is(:hover,:focus-visible) {
rotate: -.4deg;
translate: 0 -2px;
filter: drop-shadow(0 8px 9px rgba(60,48,30,.3));
}
.cb-33__btn:is(:hover,:focus-visible) .cb-33__label {
rotate: .6deg;
}
.cb-33__btn:active {
rotate: -1.2deg;
translate: 0 1px;
filter: drop-shadow(0 2px 2px rgba(60,48,30,.3));
}
.cb-33__btn:focus-visible {
outline: 2px dashed var(--ink);
outline-offset: 4px;
}
.cb-33__btn:disabled {
cursor: not-allowed;
opacity: .6;
filter: none;
}
@media (prefers-reduced-motion: reduce) {
.cb-33__btn,
.cb-33__label {
transition: none;
}
}
@media (forced-colors: active) {
.cb-33__btn {
background: ButtonFace;
color: ButtonText;
border: 1px solid ButtonText;
mask: none;
-webkit-mask: none;
filter: none;
rotate: 0deg;
}
}@import url('https://fonts.googleapis.com/css2?family=Caveat:wght@500;600;700&display=swap');
.cb-33 {
--bg: #dfd8c8;
--tape: rgba(238,226,190,.9);
--tape-2: rgba(222,206,164,.92);
--ink: #3a3226;
--hand: "Caveat",ui-rounded,"Comic Sans MS",cursive;
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: repeating-linear-gradient(0deg, rgba(0,0,0,.03) 0 1px, transparent 1px 1.75rem), repeating-linear-gradient(90deg, rgba(0,0,0,.03) 0 1px, transparent 1px 1.75rem), var(--bg);
font-family: var(--hand);
}
@supports (color: oklch(50% 0 0)) {
.cb-33 {
--bg: oklch(88% .022 88);
--ink: oklch(30% .02 75);
}
}
@media (prefers-color-scheme: dark) {
.cb-33:not([data-theme="light"]) {
--bg: #26231d;
--tape: rgba(206,190,150,.86);
--tape-2: rgba(184,168,128,.9);
--ink: #2b251b;
}
}
.cb-33[data-theme="dark"] {
--bg: #26231d;
--tape: rgba(206,190,150,.86);
--tape-2: rgba(184,168,128,.9);
--ink: #2b251b;
}
.cb-33,
.cb-33 *,
.cb-33 *::before,
.cb-33 *::after {
box-sizing: border-box;
}
.cb-33__stage {
min-height: 100vh;
min-height: 100svh;
display: grid;
place-items: center;
padding: clamp(1.5rem,6vw,4rem);
}
.cb-33__btn {
cursor: pointer;
border: 0;
padding: .85rem 2.4rem;
border-radius: 0;
font: inherit;
font-size: 1.5rem;
font-weight: 600;
letter-spacing: .01em;
color: var(--ink);
background-color: var(--tape);
background-image: repeating-linear-gradient(90deg, rgba(255,255,255,.22) 0 1px, transparent 1px 2px), repeating-linear-gradient(90deg, rgba(0,0,0,.045) 0 1px, transparent 1px 5px), linear-gradient(102deg, rgba(255,255,255,.3), transparent 40%, rgba(0,0,0,.07)), linear-gradient(180deg, var(--tape), var(--tape-2));
-webkit-mask: radial-gradient(.22rem .3rem at 0 50%, transparent 96%, #000 0) 0 0/.42rem .5rem repeat-y, radial-gradient(.22rem .3rem at 100% 50%, transparent 96%, #000 0) 100% 0/.42rem .5rem repeat-y, linear-gradient(#000,#000) .4rem 0/calc(100% - .8rem) 100% no-repeat;
mask: radial-gradient(.22rem .3rem at 0 50%, transparent 96%, #000 0) 0 0/.42rem .5rem repeat-y, radial-gradient(.22rem .3rem at 100% 50%, transparent 96%, #000 0) 100% 0/.42rem .5rem repeat-y, linear-gradient(#000,#000) .4rem 0/calc(100% - .8rem) 100% no-repeat;
rotate: -1.7deg;
filter: drop-shadow(0 4px 5px rgba(60,48,30,.28));
transition: rotate .4s cubic-bezier(.16,1,.3,1), translate .4s cubic-bezier(.16,1,.3,1), filter .35s ease;
-webkit-tap-highlight-color: transparent;
}
.cb-33__label {
display: inline-block;
transition: rotate .4s cubic-bezier(.16,1,.3,1);
}
.cb-33__btn:is(:hover,:focus-visible) {
rotate: -.4deg;
translate: 0 -2px;
filter: drop-shadow(0 8px 9px rgba(60,48,30,.3));
}
.cb-33__btn:is(:hover,:focus-visible) .cb-33__label {
rotate: .6deg;
}
.cb-33__btn:active {
rotate: -1.2deg;
translate: 0 1px;
filter: drop-shadow(0 2px 2px rgba(60,48,30,.3));
}
.cb-33__btn:focus-visible {
outline: 2px dashed var(--ink);
outline-offset: 4px;
}
.cb-33__btn:disabled {
cursor: not-allowed;
opacity: .6;
filter: none;
}
@media (prefers-reduced-motion: reduce) {
.cb-33__btn,
.cb-33__label {
transition: none;
}
}
@media (forced-colors: active) {
.cb-33__btn {
background: ButtonFace;
color: ButtonText;
border: 1px solid ButtonText;
mask: none;
-webkit-mask: none;
filter: none;
rotate: 0deg;
}
}Here's a working CSS Button from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: CSS Masking Tape Label Button
Source: https://codefronts.com/components/css-buttons/css-masking-tape-label-button/
A strip of drafting tape stuck slightly crooked: translucent so the surface shows through, fibrous weave running lengthwise, ragged torn ends cut by a repeating mask, and a hand-written label. Hover presses the tape flatter; pressing sticks it down.
## HTML
```html
<div class="cb-33">
<div class="cb-33__stage">
<button class="cb-33__btn" type="button">
<span class="cb-33__label">pin this for later</span>
</button>
</div>
</div>
```
## CSS
```css
@import url('https://fonts.googleapis.com/css2?family=Caveat:wght@500;600;700&display=swap');
.cb-33 {
--bg: #dfd8c8;
--tape: rgba(238,226,190,.9);
--tape-2: rgba(222,206,164,.92);
--ink: #3a3226;
--hand: "Caveat",ui-rounded,"Comic Sans MS",cursive;
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: repeating-linear-gradient(0deg, rgba(0,0,0,.03) 0 1px, transparent 1px 1.75rem), repeating-linear-gradient(90deg, rgba(0,0,0,.03) 0 1px, transparent 1px 1.75rem), var(--bg);
font-family: var(--hand);
}
@supports (color: oklch(50% 0 0)) {
.cb-33 {
--bg: oklch(88% .022 88);
--ink: oklch(30% .02 75);
}
}
@media (prefers-color-scheme: dark) {
.cb-33:not([data-theme="light"]) {
--bg: #26231d;
--tape: rgba(206,190,150,.86);
--tape-2: rgba(184,168,128,.9);
--ink: #2b251b;
}
}
.cb-33[data-theme="dark"] {
--bg: #26231d;
--tape: rgba(206,190,150,.86);
--tape-2: rgba(184,168,128,.9);
--ink: #2b251b;
}
.cb-33,
.cb-33 *,
.cb-33 *::before,
.cb-33 *::after {
box-sizing: border-box;
}
.cb-33__stage {
min-height: 100vh;
min-height: 100svh;
display: grid;
place-items: center;
padding: clamp(1.5rem,6vw,4rem);
}
.cb-33__btn {
cursor: pointer;
border: 0;
padding: .85rem 2.4rem;
border-radius: 0;
font: inherit;
font-size: 1.5rem;
font-weight: 600;
letter-spacing: .01em;
color: var(--ink);
background-color: var(--tape);
background-image: repeating-linear-gradient(90deg, rgba(255,255,255,.22) 0 1px, transparent 1px 2px), repeating-linear-gradient(90deg, rgba(0,0,0,.045) 0 1px, transparent 1px 5px), linear-gradient(102deg, rgba(255,255,255,.3), transparent 40%, rgba(0,0,0,.07)), linear-gradient(180deg, var(--tape), var(--tape-2));
-webkit-mask: radial-gradient(.22rem .3rem at 0 50%, transparent 96%, #000 0) 0 0/.42rem .5rem repeat-y, radial-gradient(.22rem .3rem at 100% 50%, transparent 96%, #000 0) 100% 0/.42rem .5rem repeat-y, linear-gradient(#000,#000) .4rem 0/calc(100% - .8rem) 100% no-repeat;
mask: radial-gradient(.22rem .3rem at 0 50%, transparent 96%, #000 0) 0 0/.42rem .5rem repeat-y, radial-gradient(.22rem .3rem at 100% 50%, transparent 96%, #000 0) 100% 0/.42rem .5rem repeat-y, linear-gradient(#000,#000) .4rem 0/calc(100% - .8rem) 100% no-repeat;
rotate: -1.7deg;
filter: drop-shadow(0 4px 5px rgba(60,48,30,.28));
transition: rotate .4s cubic-bezier(.16,1,.3,1), translate .4s cubic-bezier(.16,1,.3,1), filter .35s ease;
-webkit-tap-highlight-color: transparent;
}
.cb-33__label {
display: inline-block;
transition: rotate .4s cubic-bezier(.16,1,.3,1);
}
.cb-33__btn:is(:hover,:focus-visible) {
rotate: -.4deg;
translate: 0 -2px;
filter: drop-shadow(0 8px 9px rgba(60,48,30,.3));
}
.cb-33__btn:is(:hover,:focus-visible) .cb-33__label {
rotate: .6deg;
}
.cb-33__btn:active {
rotate: -1.2deg;
translate: 0 1px;
filter: drop-shadow(0 2px 2px rgba(60,48,30,.3));
}
.cb-33__btn:focus-visible {
outline: 2px dashed var(--ink);
outline-offset: 4px;
}
.cb-33__btn:disabled {
cursor: not-allowed;
opacity: .6;
filter: none;
}
@media (prefers-reduced-motion: reduce) {
.cb-33__btn,
.cb-33__label {
transition: none;
}
}
@media (forced-colors: active) {
.cb-33__btn {
background: ButtonFace;
color: ButtonText;
border: 1px solid ButtonText;
mask: none;
-webkit-mask: none;
filter: none;
rotate: 0deg;
}
}
```Here's a working CSS Button from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: CSS Masking Tape Label Button
Source: https://codefronts.com/components/css-buttons/css-masking-tape-label-button/
A strip of drafting tape stuck slightly crooked: translucent so the surface shows through, fibrous weave running lengthwise, ragged torn ends cut by a repeating mask, and a hand-written label. Hover presses the tape flatter; pressing sticks it down.
## HTML
```html
<div class="cb-33">
<div class="cb-33__stage">
<button class="cb-33__btn" type="button">
<span class="cb-33__label">pin this for later</span>
</button>
</div>
</div>
```
## CSS
```css
@import url('https://fonts.googleapis.com/css2?family=Caveat:wght@500;600;700&display=swap');
.cb-33 {
--bg: #dfd8c8;
--tape: rgba(238,226,190,.9);
--tape-2: rgba(222,206,164,.92);
--ink: #3a3226;
--hand: "Caveat",ui-rounded,"Comic Sans MS",cursive;
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: repeating-linear-gradient(0deg, rgba(0,0,0,.03) 0 1px, transparent 1px 1.75rem), repeating-linear-gradient(90deg, rgba(0,0,0,.03) 0 1px, transparent 1px 1.75rem), var(--bg);
font-family: var(--hand);
}
@supports (color: oklch(50% 0 0)) {
.cb-33 {
--bg: oklch(88% .022 88);
--ink: oklch(30% .02 75);
}
}
@media (prefers-color-scheme: dark) {
.cb-33:not([data-theme="light"]) {
--bg: #26231d;
--tape: rgba(206,190,150,.86);
--tape-2: rgba(184,168,128,.9);
--ink: #2b251b;
}
}
.cb-33[data-theme="dark"] {
--bg: #26231d;
--tape: rgba(206,190,150,.86);
--tape-2: rgba(184,168,128,.9);
--ink: #2b251b;
}
.cb-33,
.cb-33 *,
.cb-33 *::before,
.cb-33 *::after {
box-sizing: border-box;
}
.cb-33__stage {
min-height: 100vh;
min-height: 100svh;
display: grid;
place-items: center;
padding: clamp(1.5rem,6vw,4rem);
}
.cb-33__btn {
cursor: pointer;
border: 0;
padding: .85rem 2.4rem;
border-radius: 0;
font: inherit;
font-size: 1.5rem;
font-weight: 600;
letter-spacing: .01em;
color: var(--ink);
background-color: var(--tape);
background-image: repeating-linear-gradient(90deg, rgba(255,255,255,.22) 0 1px, transparent 1px 2px), repeating-linear-gradient(90deg, rgba(0,0,0,.045) 0 1px, transparent 1px 5px), linear-gradient(102deg, rgba(255,255,255,.3), transparent 40%, rgba(0,0,0,.07)), linear-gradient(180deg, var(--tape), var(--tape-2));
-webkit-mask: radial-gradient(.22rem .3rem at 0 50%, transparent 96%, #000 0) 0 0/.42rem .5rem repeat-y, radial-gradient(.22rem .3rem at 100% 50%, transparent 96%, #000 0) 100% 0/.42rem .5rem repeat-y, linear-gradient(#000,#000) .4rem 0/calc(100% - .8rem) 100% no-repeat;
mask: radial-gradient(.22rem .3rem at 0 50%, transparent 96%, #000 0) 0 0/.42rem .5rem repeat-y, radial-gradient(.22rem .3rem at 100% 50%, transparent 96%, #000 0) 100% 0/.42rem .5rem repeat-y, linear-gradient(#000,#000) .4rem 0/calc(100% - .8rem) 100% no-repeat;
rotate: -1.7deg;
filter: drop-shadow(0 4px 5px rgba(60,48,30,.28));
transition: rotate .4s cubic-bezier(.16,1,.3,1), translate .4s cubic-bezier(.16,1,.3,1), filter .35s ease;
-webkit-tap-highlight-color: transparent;
}
.cb-33__label {
display: inline-block;
transition: rotate .4s cubic-bezier(.16,1,.3,1);
}
.cb-33__btn:is(:hover,:focus-visible) {
rotate: -.4deg;
translate: 0 -2px;
filter: drop-shadow(0 8px 9px rgba(60,48,30,.3));
}
.cb-33__btn:is(:hover,:focus-visible) .cb-33__label {
rotate: .6deg;
}
.cb-33__btn:active {
rotate: -1.2deg;
translate: 0 1px;
filter: drop-shadow(0 2px 2px rgba(60,48,30,.3));
}
.cb-33__btn:focus-visible {
outline: 2px dashed var(--ink);
outline-offset: 4px;
}
.cb-33__btn:disabled {
cursor: not-allowed;
opacity: .6;
filter: none;
}
@media (prefers-reduced-motion: reduce) {
.cb-33__btn,
.cb-33__label {
transition: none;
}
}
@media (forced-colors: active) {
.cb-33__btn {
background: ButtonFace;
color: ButtonText;
border: 1px solid ButtonText;
mask: none;
-webkit-mask: none;
filter: none;
rotate: 0deg;
}
}
```How this works
Torn ends come from a mask made of two repeating radial notch patterns pinned to the left and right edges, so both ends are irregular while the middle stays intact:
mask:
radial-gradient(.22rem .3rem at 0 50%, transparent 96%, #000 0) 0 0/.42rem .5rem repeat-y,
radial-gradient(.22rem .3rem at 100% 50%, transparent 96%, #000 0) 100% 0/.42rem .5rem repeat-y,
linear-gradient(#000,#000) .4rem 0/calc(100% - .8rem) 100% no-repeat;Tape reads as tape because of translucency plus a directional weave: a low-alpha base, a fine repeating gradient at 1-2px, and a broad diagonal sheen. The whole label is rotated by a fraction of a degree — real tape is never square — and un-rotates toward flat on hover:
.cb-33__btn{ rotate:-1.6deg; transition:rotate .4s, translate .4s, filter .35s; }
.cb-33__btn:is(:hover,:focus-visible){ rotate:-.4deg; translate:0 -2px; }The shadow is a drop-shadow filter rather than box-shadow, so it follows the torn silhouette instead of the rectangle.
Make it yours
- Change the tape colour with
--tape; keep alpha between .82 and .92 or it stops looking translucent. - Notch size and rhythm are in the mask's
.42rem .5remtile — smaller tiles read as a cleaner tear. - Rotate more or less at rest; anything beyond 3° starts to look like a mistake rather than a hand.
- Swap the handwriting font for a marker face if the label needs more weight.
Gotchas — read before shipping
- Handwriting fonts are low-legibility at small sizes: 1.125rem minimum, and never for critical actions.
- A rotated button's hit area is rotated too — keep rotation small so pointer targets stay predictable.
drop-shadowplus a multi-layer mask is a heavy combination; use it once, not on a list.- Translucent controls inherit the background's contrast problems. Test the label against the lightest thing behind the tape.
- Multi-layer masks need explicit repeat and size per layer or the base layer tiles and eats the tape.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 120+ | 15.4+ | 53+ | 120+ |
mask shorthand with multiple layers: Chrome 120 / Safari 15.4 (prefixed earlier) / Firefox 53. Without it the ends are straight — the tape still works.