Real materials
Leather, wood, paper, brushed metal and glass rendered with gradients and texture.
Interfaces that copy real objects: leather covers, stitched edges, paper notepads, metal knobs and glossy buttons.
It made early touchscreens feel familiar, until flat design swept it away in 2013.
Skeuomorphic design makes digital things look like their physical ancestors. Textures, stitching and lighting teach people how to use a screen by reminding them of objects they already know.
Leather, wood, paper, brushed metal and glass rendered with gradients and texture.
Knobs, toggle switches and dials that look like they could be turned or flipped.
A light source from above gives every button a highlight on top and shadow below.
A trash can deletes, a notepad takes notes, a bookshelf holds books.
Skeuomorphism shaped two decades of interfaces and then became the thing flat design rebelled against.
Early graphical interfaces use desktops, folders and trash cans to explain computers.
Operating systems introduce glossy, jelly-like aqua buttons and brushed metal windows.
The first iPhone uses realistic icons and textures to make touch feel natural.
Calendar and contact apps with leather and stitching spark debates among designers.
iOS 7 removes almost all textures, and skeuomorphism becomes shorthand for old-fashioned.
Skeuomorphic motion obeys physics. A needle swings and bounces, and a switch snaps from one position to the other.
These three mockups are built only from the kit on this page. Swap the tokens and they change style with it.
Synthesizers and recording apps still use knobs, meters and faders.
Card, board and puzzle games use wood, felt and paper to feel tactile.
Notes, calculators and clocks use realistic objects for charm.
The tokens every component on this page is built from. Copy them as a starting point, then adjust with intent.
Colours come from materials: leather brown, paper cream, metal grey and one glossy blue for action. Tap a swatch to copy its hex value.
:root{
--linen: #E6E0D4;
--leather: #6B3E26;
--stitch: #E8D2A6;
--aluminium: #D9DCE0;
--walnut: #A8683B;
--glossy-blue: #3B7DDD;
--ink: #2B2520;
}A slab serif for titles that recalls printed labels, and a friendly sans for interface text.
Body text carries the explanation. Keep lines under about 75 characters so the eye can find the next line.
:root{
--font-d: "Arvo",Rockwell,serif;
--font-b: "Lato",system-ui,sans-serif;
--font-m: ui-monospace,Menlo,monospace;
--fs-d: clamp(42px, 9vw, 81px);
--fs-1: 41.5px; --fs-2: 33.2px;
--fs-3: 26.6px; --fs-4: 21.2px;
--fs-body: 17px; --fs-sm: 13.6px;
}
h1,h2,h3,h4 {
font-family: var(--font-d);
font-weight: 700;
letter-spacing: 0;
text-transform: none;
line-height: 1.1;
}
/* fonts: Arvo and Lato */Layouts imitate objects: a leather header, a notepad body, a metal control panel.
Equal cards, product tiles, feature lists.
<div class="row"><div class="col-4">4</div><div class="col-4">4</div><div class="col-4">4</div></div>Articles, documentation, settings pages.
<div class="row"><div class="col-8">8</div><div class="col-4">4</div></div>Heroes and feature sections with tension.
<div class="row"><div class="col-5">5</div><div class="col-7">7</div></div>Dense galleries and logo walls.
<div class="row"><div class="col-3">3</div><div class="col-3">3</div><div class="col-3">3</div><div class="col-3">3</div></div>.row {
display: grid;
grid-template-columns: repeat(12, minmax(0, 1fr));
gap: 24px;
}
.col-3 { grid-column: span 3; } .col-4 { grid-column: span 4; }
.col-5 { grid-column: span 5; } .col-7 { grid-column: span 7; }
.col-8 { grid-column: span 8; }
@media (max-width: 760px) {
.row { grid-template-columns: 1fr; }
.row > * { grid-column: auto; }
}Soft radius, inner highlights on top and shadows below, like light falling from the ceiling.
:root {
--radius: 8px;
--radius-sm: 6px;
--bw: 1px;
--shadow: 0 1px 0 #fff inset, 0 2px 4px rgba(0,0,0,.25), 0 8px 18px rgba(0,0,0,.18);
--shadow-sm: 0 1px 0 rgba(255,255,255,.7) inset, 0 1px 3px rgba(0,0,0,.3);
--gap: 24px;
--pad: 24px;
}Change three tokens and the whole page responds, because every component reads from them. Reset brings back the style defaults.
Move a control to see the token change.Every component below is plain HTML with class names from the kit. Copy the full kit CSS once, then paste any snippet.
/* Skeuomorphism kit · Anti-Boring */
:root{
--bg:#E6E0D4;
--surface:#F7F3EA;
--surface2:#DCD4C4;
--fg:#2B2520;
--muted:#5E554A;
--accent:#3B7DDD;
--accent-fg:#FFFFFF;
--accent2:#D9DCE0;
--accent2-fg:#2B2520;
--border:#A89C88;
--bw:1px;
--radius:8px;
--radius-sm:6px;
--shadow:0 1px 0 #fff inset, 0 2px 4px rgba(0,0,0,.25), 0 8px 18px rgba(0,0,0,.18);
--shadow-sm:0 1px 0 rgba(255,255,255,.7) inset, 0 1px 3px rgba(0,0,0,.3);
--font-d:"Arvo",Rockwell,serif;
--font-b:"Lato",system-ui,sans-serif;
--font-m:ui-monospace,Menlo,monospace;
--h-weight:700;
--h-track:0;
--h-case:none;
--h-style:normal;
--h-lh:1.1;
--gap:24px;
--pad:24px;
--focus:rgba(59,125,221,.45);
--ok:#2E7D32;
--warn:#8A5A00;
--danger:#B3261E;
--info:#3B7DDD;
--field-bg:#FFFFFF;
--field-shadow:inset 0 2px 3px rgba(0,0,0,.18);
--media:repeating-linear-gradient(90deg,rgba(255,255,255,.08) 0 2px,transparent 2px 7px),repeating-linear-gradient(0deg,#A8683B 0 18px,#9A5E34 18px 22px,#B07244 22px 40px);
--code-bg:#2B2520;
--code-fg:#EDE3CF;
--btn-case:none;
--btn-track:0;
--btn-weight:700;
--badge-radius:999px;
--maxw:1160px;
--fs-sm:13.6px;
--fs-body:17px;
--fs-4:21.2px;
--fs-3:26.6px;
--fs-2:33.2px;
--fs-1:41.5px;
--fs-d:clamp(42px, 9vw, 81px);
}
*,*::before,*::after{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--fg);font:400 var(--fs-body)/1.6 var(--font-b);-webkit-font-smoothing:antialiased}
h1,h2,h3,h4{font-family:var(--font-d);font-weight:var(--h-weight);letter-spacing:var(--h-track);text-transform:var(--h-case);font-style:var(--h-style);line-height:var(--h-lh);margin:0 0 .4em}
h1{font-size:var(--fs-1)} h2{font-size:var(--fs-2)} h3{font-size:var(--fs-3)} h4{font-size:var(--fs-4)}
p{margin:0 0 1em}
a{color:inherit}
:focus-visible{outline:3px solid var(--accent);outline-offset:3px}
code,pre,kbd{font-family:var(--font-m)}
/* buttons */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:.5em;font:var(--btn-weight) 1rem/1 var(--font-b);text-transform:var(--btn-case);letter-spacing:var(--btn-track);padding:.85em 1.4em;border:var(--bw) solid var(--border);border-radius:var(--radius);background:var(--accent);color:var(--accent-fg);box-shadow:var(--shadow-sm);text-decoration:none;cursor:pointer;transition:transform .12s,box-shadow .12s,background-color .12s,color .12s}
.btn:hover{transform:translateY(-1px)}
.btn:active{transform:translateY(1px)}
.btn-2{background:var(--accent2);color:var(--accent2-fg)}
.btn-ghost{background:transparent;color:var(--fg);box-shadow:none}
.btn-sm{font-size:.85rem;padding:.6em 1em}
.btn-lg{font-size:1.15rem;padding:1em 1.7em}
.btn[disabled]{opacity:.45;cursor:not-allowed;transform:none}
/* forms */
.field{display:grid;gap:.4em;margin-bottom:1.1em}
.label{font-weight:600;font-size:.95rem}
.help{font-size:.85rem;color:var(--muted)}
.input,.select,.textarea{width:100%;font:1rem/1.4 var(--font-b);color:var(--fg);padding:.75em .9em;background:var(--field-bg);border:var(--bw) solid var(--border);border-radius:var(--radius-sm);box-shadow:var(--field-shadow);appearance:none}
.select{background-image:linear-gradient(45deg,transparent 50%,currentColor 50%),linear-gradient(135deg,currentColor 50%,transparent 50%);background-position:calc(100% - 20px) 55%,calc(100% - 14px) 55%;background-size:6px 6px;background-repeat:no-repeat;padding-right:2.4em}
.textarea{min-height:110px;resize:vertical}
.input:focus,.select:focus,.textarea:focus{outline:none;border-color:var(--accent);box-shadow:var(--field-shadow),0 0 0 3px var(--focus)}
.is-error .input{border-color:var(--danger)} .is-error .help{color:var(--danger)}
.choice{display:flex;align-items:center;gap:.6em;margin:.35em 0;cursor:pointer}
.check,.radio{appearance:none;width:1.25em;height:1.25em;margin:0;flex:none;border:var(--bw) solid var(--border);background:var(--field-bg);box-shadow:var(--field-shadow);display:grid;place-items:center;cursor:pointer}
.check{border-radius:calc(var(--radius-sm)/2)} .radio{border-radius:50%}
.check::after{content:"";width:.55em;height:.3em;border-left:2.5px solid var(--accent-fg);border-bottom:2.5px solid var(--accent-fg);transform:rotate(-45deg) translate(1px,-1px);opacity:0}
.radio::after{content:"";width:.5em;height:.5em;border-radius:50%;background:var(--accent-fg);opacity:0}
.check:checked,.radio:checked{background:var(--accent);border-color:var(--border)}
.check:checked::after,.radio:checked::after{opacity:1}
.switch{appearance:none;width:2.8em;height:1.6em;margin:0;flex:none;border-radius:999px;border:var(--bw) solid var(--border);background:var(--surface2);position:relative;cursor:pointer;transition:background .15s;box-shadow:var(--field-shadow)}
.switch::before{content:"";position:absolute;top:50%;left:.18em;width:1.1em;height:1.1em;border-radius:50%;background:var(--fg);transform:translateY(-50%);transition:left .15s}
.switch:checked{background:var(--accent)}
.switch:checked::before{left:calc(100% - 1.28em);background:var(--accent-fg)}
.range{width:100%;accent-color:var(--accent)}
/* surfaces */
.card{background:var(--surface);color:var(--fg);border:var(--bw) solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow);padding:var(--pad);position:relative}
.card-media{aspect-ratio:16/9;border-radius:var(--radius-sm);background:var(--media);margin-bottom:1em}
.badge{display:inline-block;font:600 .75rem/1 var(--font-b);padding:.45em .75em;border-radius:var(--badge-radius);background:var(--accent2);color:var(--accent2-fg);border:var(--bw) solid var(--border)}
.alert{padding:1em 1.2em;border:var(--bw) solid var(--border);border-left:6px solid var(--c,var(--info));border-radius:var(--radius-sm);background:var(--surface);margin-bottom:.8em}
.alert b{color:var(--c,var(--info))}
.alert-ok{--c:var(--ok)} .alert-warn{--c:var(--warn)} .alert-danger{--c:var(--danger)}
.progress{height:.8em;border-radius:999px;background:var(--surface2);border:var(--bw) solid var(--border);overflow:hidden}
.progress i{display:block;height:100%;background:var(--accent)}
/* navigation */
.tabs{display:flex;gap:.25em;border-bottom:var(--bw) solid var(--border);flex-wrap:wrap}
.tab{font:600 .95rem var(--font-b);padding:.7em 1em;background:none;border:0;border-bottom:3px solid transparent;color:var(--muted);cursor:pointer;margin-bottom:calc(var(--bw) * -1)}
.tab[aria-selected="true"]{color:var(--fg);border-bottom-color:var(--accent)}
.crumbs{display:flex;gap:.5em;flex-wrap:wrap;font-size:.9rem;color:var(--muted);list-style:none;padding:0;margin:0}
.crumbs li+li::before{content:"/";margin-right:.5em;opacity:.6}
.pager{display:flex;gap:.4em;list-style:none;padding:0;margin:0;flex-wrap:wrap}
.pager a{display:grid;place-items:center;min-width:2.4em;height:2.4em;border:var(--bw) solid var(--border);border-radius:var(--radius-sm);text-decoration:none;background:var(--surface)}
.pager a[aria-current]{background:var(--accent);color:var(--accent-fg)}
/* table */
.table-wrap{overflow-x:auto;border:var(--bw) solid var(--border);border-radius:var(--radius-sm);background:var(--surface)}
.table{width:100%;border-collapse:collapse;font-size:.95rem;min-width:460px}
.table th,.table td{text-align:left;padding:.75em 1em;border-bottom:1px solid color-mix(in srgb,var(--border) 30%,transparent)}
.table th{font-family:var(--font-d);font-weight:var(--h-weight)}
/* grid */
.row{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--gap)}
.col-3{grid-column:span 3}.col-4{grid-column:span 4}.col-5{grid-column:span 5}.col-6{grid-column:span 6}.col-7{grid-column:span 7}.col-8{grid-column:span 8}.col-12{grid-column:span 12}
@media (max-width:760px){.row{grid-template-columns:minmax(0,1fr);gap:min(var(--gap),16px)}.row>*{grid-column:auto!important;grid-row:auto!important}}
/* signature */
.btn{background:linear-gradient(#6FA7F2,#3B7DDD 50%,#2A67C2 51%,#4F8FE6);border-color:#1F4F96;text-shadow:0 -1px 0 rgba(0,0,0,.3);box-shadow:inset 0 1px 0 rgba(255,255,255,.5),0 1px 2px rgba(0,0,0,.35)}
.btn:active{transform:none;background:linear-gradient(#2A67C2,#3B7DDD);box-shadow:inset 0 2px 4px rgba(0,0,0,.4)}
.btn-2{background:linear-gradient(#F4F5F7,#D9DCE0 50%,#C9CDD3 51%,#E3E6EA);border-color:#8E949C;color:#2B2520;text-shadow:0 1px 0 #fff}
.btn-ghost{background:transparent;border-color:transparent;text-shadow:none;box-shadow:none;color:var(--fg);text-decoration:underline}
.card{background:linear-gradient(#FBF8F1,#F2ECDF)}
.card-media{border:4px solid #fff;box-shadow:0 2px 6px rgba(0,0,0,.35);transform:rotate(-1deg)}
.badge{background:linear-gradient(#E2463B,#B42A21);color:#fff;border:0;box-shadow:inset 0 1px 0 rgba(255,255,255,.4),0 1px 2px rgba(0,0,0,.4);text-shadow:0 -1px 0 rgba(0,0,0,.3)}
.switch{width:3.4em;background:linear-gradient(#C9CDD3,#E6E8EB);box-shadow:inset 0 2px 4px rgba(0,0,0,.3);border-color:#8E949C}
.switch::before{width:1.3em;height:1.3em;background:linear-gradient(#FFFFFF,#D9DCE0);box-shadow:0 1px 3px rgba(0,0,0,.4)}
.switch:checked{background:linear-gradient(#2A67C2,#6FA7F2)}
.switch:checked::before{left:calc(100% - 1.45em);background:linear-gradient(#FFFFFF,#D9DCE0)}
.check,.radio{background:linear-gradient(#fff,#E6E8EB);box-shadow:inset 0 1px 2px rgba(0,0,0,.2)}
.check:checked,.radio:checked{background:linear-gradient(#6FA7F2,#2A67C2)}
.progress{background:linear-gradient(#C9CDD3,#E6E8EB);box-shadow:inset 0 1px 3px rgba(0,0,0,.35)}
.progress i{background:linear-gradient(#8FC0FF,#3B7DDD 50%,#2A67C2 51%,#6FA7F2)}
.alert{background:linear-gradient(#FFFDF4,#F4EED8);box-shadow:var(--shadow-sm)}
.tabs{background:linear-gradient(#E3E6EA,#C9CDD3);border-radius:8px;padding:3px;display:inline-flex;border:1px solid #8E949C}
.tab{border:0;border-radius:6px;margin:0;color:#2B2520}
.tab[aria-selected="true"]{background:linear-gradient(#6FA7F2,#3B7DDD);color:#fff;box-shadow:inset 0 1px 3px rgba(0,0,0,.3)}
.pager a{background:linear-gradient(#F4F5F7,#D9DCE0);box-shadow:var(--shadow-sm)}
.pager a[aria-current]{background:linear-gradient(#6FA7F2,#3B7DDD)}
.table th{background:linear-gradient(#F4F5F7,#D9DCE0);text-shadow:0 1px 0 #fff}
/* dark theme: add class="alt" to <html> */
html.alt{
--bg:#1F1B17;
--surface:#2B2520;
--surface2:#25201B;
--fg:#F2EADB;
--muted:#C2B6A2;
--border:#5E554A;
--accent2:#4A4F57;
--accent2-fg:#F2EADB;
--field-bg:#1A1612;
--field-shadow:inset 0 2px 3px rgba(0,0,0,.5);
--shadow:0 1px 0 rgba(255,255,255,.06) inset, 0 2px 4px rgba(0,0,0,.5), 0 8px 18px rgba(0,0,0,.4);
--shadow-sm:0 1px 0 rgba(255,255,255,.08) inset, 0 1px 3px rgba(0,0,0,.5);
--code-bg:#120F0C;
}
html.alt .docnav{background:linear-gradient(#2B2520,#1A1612)!important}html.alt .card{background:linear-gradient(#2E2823,#26211C)}html.alt .alert{background:linear-gradient(#2E2823,#26211C)}html.alt .btn-2,html.alt .tab{text-shadow:none}html.alt .table th{background:linear-gradient(#3A342E,#2B2520);text-shadow:none}html.alt .tl li{box-shadow:none;border-color:#3A342E}Three emphasis levels, three sizes and a disabled state. Keep one primary button per view.
<div class="demo-row">
<button class="btn">Primary</button>
<button class="btn btn-2">Secondary</button>
<button class="btn btn-ghost">Ghost</button>
<button class="btn" disabled>Disabled</button>
</div>
<div class="demo-row" style="margin-top:14px">
<button class="btn btn-sm">Small</button>
<button class="btn">Default</button>
<button class="btn btn-lg">Large</button>
</div>Text fields, choices and toggles share the same border, radius and focus ring, so a form reads as one family.
<form class="formgrid" onsubmit="return false">
<div>
<div class="field">
<label class="label" for="f-name">Full name</label>
<input class="input" id="f-name" placeholder="Ada Lovelace">
<span class="help">As it appears on your ID.</span>
</div>
<div class="field is-error">
<label class="label" for="f-mail">Email</label>
<input class="input" id="f-mail" type="email" value="ada@">
<span class="help">Enter a complete email address.</span>
</div>
<div class="field">
<label class="label" for="f-plan">Plan</label>
<select class="select" id="f-plan"><option>Starter</option><option>Studio</option><option>Team</option></select>
</div>
</div>
<div>
<div class="field">
<label class="label" for="f-msg">Message</label>
<textarea class="textarea" id="f-msg" placeholder="Tell us about your project"></textarea>
</div>
<fieldset class="field" style="border:0;padding:0;margin:0 0 1.1em">
<legend class="label">Interests</legend>
<label class="choice"><input type="checkbox" class="check" checked> Typography</label>
<label class="choice"><input type="checkbox" class="check"> Motion</label>
</fieldset>
<fieldset class="field" style="border:0;padding:0;margin:0 0 1.1em">
<legend class="label">Billing</legend>
<label class="choice"><input type="radio" name="bill" class="radio" checked> Monthly</label>
<label class="choice"><input type="radio" name="bill" class="radio"> Yearly</label>
</fieldset>
<label class="choice"><input type="checkbox" class="switch" checked> Email me updates</label>
<div class="field" style="margin-top:1em">
<label class="label" for="f-range">Budget</label>
<input class="range" id="f-range" type="range" value="60">
</div>
<button class="btn">Send request</button>
</div>
</form>A container for one idea. Media sits on top, then a badge, title, short text and one action.
<div class="auto">
<article class="card">
<div class="card-media"></div>
<span class="badge">New</span>
<h4 style="margin-top:.6em">Card title</h4>
<p>Short supporting text that explains what this card is about.</p>
<a class="btn btn-sm" href="#">Read more</a>
</article>
<article class="card">
<div class="card-media" style="filter:hue-rotate(40deg)"></div>
<span class="badge">Guide</span>
<h4 style="margin-top:.6em">Second card</h4>
<p>Cards in a row share height and spacing, so the grid stays calm.</p>
<a class="btn btn-sm btn-2" href="#">Open</a>
</article>
</div>Alerts, badges and progress tell people what just happened and what to do next.
<div class="alert"><b>Info.</b> Your draft saves every 30 seconds.</div>
<div class="alert alert-ok"><b>Saved.</b> Changes are live on your site.</div>
<div class="alert alert-warn"><b>Check this.</b> Two images are missing alt text.</div>
<div class="alert alert-danger"><b>Upload failed.</b> Files must be under 10 MB. Try a smaller file.</div>
<div class="demo-row" style="margin-top:14px">
<span class="badge">Default</span>
<span class="badge" style="background:var(--accent);color:var(--accent-fg)">Accent</span>
</div>
<div style="margin-top:18px"><div class="progress" role="progressbar" aria-valuenow="64" aria-valuemin="0" aria-valuemax="100" aria-label="Upload progress"><i style="width:64%"></i></div></div>Tables scroll sideways on small screens instead of squashing columns.
| Project | Owner | Status | Due |
|---|---|---|---|
| Homepage | Rūta | Review | 12 Oct |
| Checkout | Tomas | Draft | 19 Oct |
| Onboarding | Ieva | Live | 2 Oct |
<div class="table-wrap">
<table class="table">
<thead><tr><th>Project</th><th>Owner</th><th>Status</th><th>Due</th></tr></thead>
<tbody>
<tr><td>Homepage</td><td>Rūta</td><td><span class="badge">Review</span></td><td>12 Oct</td></tr>
<tr><td>Checkout</td><td>Tomas</td><td><span class="badge">Draft</span></td><td>19 Oct</td></tr>
<tr><td>Onboarding</td><td>Ieva</td><td><span class="badge">Live</span></td><td>2 Oct</td></tr>
</tbody>
</table>
</div>A ready prompt for AI design and coding tools. It names exact tokens and bans the usual defaults, so the output keeps this style's point of view.
Design a responsive landing page for a vintage-style music recording app in an authentic Skeuomorphism style.
Palette: Linen #E6E0D4, Leather #6B3E26, Stitch #E8D2A6, Aluminium #D9DCE0, Walnut #A8683B, Glossy blue #3B7DDD, Ink #2B2520.
Typography: Arvo 700 for titles, Lato for interface text.
Layout: The hero is an app window: a stitched leather header with embossed title, a lined yellow notepad body with a red margin line holding the intro and buttons, and a brushed metal control panel with a turning knob.
Signature details: Materials drawn with CSS gradients (leather grain, brushed metal, ruled paper), a consistent light from above, inner highlights, soft drop shadows.
Components: Glossy blue gel buttons, aluminium secondary buttons, physical toggle switches, red notification badges, segmented metal tab bar.
Motion: Physical movement: a swinging VU needle with bounce, a flipping toggle, a turning knob.
Avoid: flat colours only, photographic textures, mixed light directions, knobs that do nothing.
Do not fall back on generic AI defaults: no centered hero with a gradient blob, no identical rounded cards with soft grey shadows, no purple-to-blue gradients, no emoji icons, unless this style explicitly calls for them.
Accessibility: body text contrast of at least 4.5:1, visible keyboard focus on every control, labels on all form fields, and respect prefers-reduced-motion.
Deliver one self-contained HTML file with CSS variables for every color, font, radius and shadow token.Where this style usually goes wrong, and how to keep it honest.
Leather, wood and metal on one screen look like a furniture showroom. Pick one material per area.
Real textures as photos add weight. Build them with CSS gradients where you can.
If it looks like a knob, it must turn. Controls must behave like the objects they copy.
Embossed text on textured surfaces is hard to read. Keep labels high contrast.