A mechanical keycap: sloped walls, a dished top with legends in the corners, and a travel of a few pixels when pressed. The walls are the button's own gradient, the top face is one inner span.
Also known as: keycap button css, css keyboard button style, keyboard key press effect.
<button class="btn-keycap" type="button"> <span class="btn-keycap-top"><span class="btn-keycap-glyph" aria-hidden="true">↵</span>Enter</span> </button>
.btn-keycap {
--c: var(--btn-color, #3b82f6);
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.5em;
padding: 0.75em 1.6em;
border: 0;
border-radius: 0.6em;
font: 600 var(--btn-size, 18px)/1.1 system-ui, sans-serif;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
--edge: color-mix(in srgb, var(--c) 55%, #000);
display: block;
width: 6.4em;
height: 3.5em;
padding: 0.16em 0.3em 0.55em;
border-radius: 0.6em;
background: linear-gradient(color-mix(in srgb, var(--c) 80%, #fff), color-mix(in srgb, var(--c) 72%, #000));
color: #fff;
box-shadow:
0 0.32em 0 var(--edge),
0 0.6em 0.8em -0.2em rgba(0, 0, 0, 0.45);
transition: transform 0.12s ease-out, box-shadow 0.12s ease-out;}
.btn-keycap-top {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: flex-start;
height: 100%;
box-sizing: border-box;
padding: 0.35em 0.55em 0.4em;
border-radius: 0.42em;
background: radial-gradient(130% 100% at 50% 15%, color-mix(in srgb, var(--c) 70%, #fff), var(--c) 75%);
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.4),
inset 0 -0.1em 0.2em color-mix(in srgb, var(--c) 70%, #000),
0 0.06em 0.12em rgba(0, 0, 0, 0.3);
font-size: 0.8em;
transition: transform 0.12s ease-out;
}
.btn-keycap-glyph {
align-self: flex-end;
font-size: 1.3em;
line-height: 1;
}
.btn-keycap:active {
transform: translateY(0.24em);
box-shadow:
0 0.08em 0 var(--edge),
0 0.2em 0.3em -0.1em rgba(0, 0, 0, 0.45);
transition-duration: 0.05s;
}
.btn-keycap:active .btn-keycap-top {
transform: scale(0.985);
transition-duration: 0.05s;
}
.btn-keycap:focus-visible {
outline: 2px solid var(--c);
outline-offset: 0.3em;
}
@media (prefers-reduced-motion: reduce) {
.btn-keycap, .btn-keycap *, .btn-keycap::before, .btn-keycap::after, .btn-keycap *::before, .btn-keycap *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}--btn-color on the element or a parent.
Currently previewing #3b82f6.--btn-size. Every other dimension is in
em, so the whole thing scales together. Currently previewing 18px.transition or animation
shorthand. Staggered delays are relative, so they keep their rhythm.