Punch Card
Manila IBM-style punch card with the iconic clipped top-right corner, a stamped FORTRAN-style header at the top, and a real grid of column-and-row holes punched through the body. On hover the whole card follows the cursor magnetically.
Punch Card the 42nd of 43 designs in the 43 CSS Button Designs collection. The design pairs CSS styling with a small amount of JavaScript for interactivity. Copy the HTML, CSS and JavaScript panels below into your project — the JS is self-contained, has zero dependencies, and is safe to drop into any framework (React, Vue, Svelte, plain HTML). The design honours prefers-reduced-motion and uses real semantic markup, so it ships accessibility-ready out of the box.
Live preview
The code
<button class="btn-punch"> <span class="btn-punch-header">RUN COMPILE 0030</span> <span class="btn-punch-grid" aria-hidden="true"></span> <span class="btn-punch-text">COMPILE</span> </button>
.btn-punch {
position: relative;
padding: 28px 32px 18px;
border: 1.5px solid #8a7d4a;
background: #e3d4a8;
color: #2a1d0e;
font-family: ui-monospace, monospace;
font-size: 14px; font-weight: 800;
letter-spacing: 0.28em;
cursor: pointer;
/* Iconic clipped top-right corner */
clip-path: polygon(0 0, calc(100% - 14px) 0, 100% 14px, 100% 100%, 0 100%);
box-shadow: 0 4px 12px rgba(58,36,16,0.3);
transition: transform 0.25s cubic-bezier(.3,1,.5,1);
text-align: center;
display: block;
--px: 0px; --py: 0px;
}
.btn-punch-header {
position: absolute;
top: 6px; left: 14px;
font-family: ui-monospace, monospace;
font-size: 8px; font-weight: 700;
color: #5a4520;
letter-spacing: 0.22em;
border-bottom: 1px solid #8a7d4a;
padding-bottom: 2px;
width: calc(100% - 36px);
text-align: left;
}
/* The hole grid: a single repeating background that draws columns of
1.5×4 mm rectangular holes — the visual signature of an 80-column card.
Two rows of perforations, evenly spaced, with ink-black holes. */
.btn-punch-grid {
position: absolute;
top: 22px; bottom: 4px;
left: 8px; right: 8px;
background-image:
radial-gradient(2px 4px at 50% 50%, #1a1a1a 99%, transparent 100%),
radial-gradient(2px 4px at 50% 50%, rgba(0,0,0,0.18) 99%, transparent 100%);
background-size: 14px 22px, 14px 22px;
background-position: 0 0, 0 11px;
background-repeat: repeat-x, repeat-x;
pointer-events: none;
opacity: 0.85;
-webkit-mask: linear-gradient(180deg,
#000 0 30%, transparent 30% 60%, #000 60% 100%);
mask: linear-gradient(180deg,
#000 0 30%, transparent 30% 60%, #000 60% 100%);
}
.btn-punch-text {
position: relative;
z-index: 1;
display: inline-block;
background: #e3d4a8;
padding: 2px 12px;
}
.btn-punch:hover { transform: translate(var(--px), var(--py)); } document.querySelectorAll('.btn-punch').forEach(function(btn) {
btn.addEventListener('mousemove', function(e) {
var rect = btn.getBoundingClientRect();
var x = (e.clientX - rect.left - rect.width / 2) * 0.18;
var y = (e.clientY - rect.top - rect.height / 2) * 0.18;
btn.style.setProperty('--px', x + 'px');
btn.style.setProperty('--py', y + 'px');
});
btn.addEventListener('mouseleave', function() {
btn.style.setProperty('--px', '0px');
btn.style.setProperty('--py', '0px');
});
});