Vibe coding made design faster, and made it easier to skip why interfaces work the way they do. From punch cards to glass buttons, every pattern solved a real problem. These guides trace where each began and how it changed, so new designers still learn the subtleties. Every pattern is a live demo to try, inspect and copy.
Ten changes in how buttons look and respond, from where each one started to how it has changed since. Each first is the earliest documented case, with sources; disputed ones are marked.
Changes
10, oldest first
Span
2007 origins to 2026
Demos
Live, with Design and Dev views
Sources
Company docs first, then press
Timeline
Oldest first. Hollow dot: where a pattern started. Solid dot: its latest big change. Point at a name to preview it; select it to jump there.
hey team, meeting moved to thurs, sorry for late notice, bring the numbers
<button class="ai" aria-busy="false">
<svg class="sparkle" aria-hidden="true">…</svg> Rewrite with AI
</button>
/* Working state: the sparkle turns, the edge shimmers */
.ai[aria-busy="true"] .sparkle { animation: spin 1.2s linear infinite; }
.ai[aria-busy="true"] {
background: linear-gradient(90deg, var(--a), var(--b), var(--a)) 0 0 / 200% 100%;
animation: shimmer 1.4s linear infinite;
}
2019 → 2021
Soft, "physical" buttons
Neumorphism made buttons look pressed out of the surface. It went viral, then faded because its low contrast fails accessibility. It is the bridge to today's tactile buttons.
Earliest documented
Alexander Plyuto's banking concept on Dribbble, late 2019. Who named it is disputed (Michal Malewicz's article popularised "neumorphism"; others credit Jason Kelley).
Since then
Peaked as a 2020–21 trend, then faded over contrast failures.
Soft buttons use the surface colour for the button and a pale label, so many people cannot read them or tell where the button is. Press both: the shape works; the label is the problem.
2020 → 2022
Focus rings only for the keyboard
For years teams removed focus outlines because they flashed on every mouse click, which left keyboard users lost. :focus-visible lets the browser decide: a ring for the keyboard, none for a click.
Earliest documented
The CSS :focus-visible pseudo-class: Chrome and Edge 86, Firefox 85, then Safari 15.4 on 14 March 2022.
Since then
Supported everywhere from 2022, and marked "widely available" in September 2024. Safari still handles buttons differently from other browsers.
<button class="save">Save draft</button>
/* A ring for the keyboard, none for a mouse click */
.save:focus { outline: none; }
.save:focus-visible {
outline: 2px solid var(--focus);
outline-offset: 3px;
}
Press Play to watch a click, then a Tab key press.
2021
Tinted and tonal buttons
A middle level of emphasis between a solid button and a text link, so a screen can have one loud action and several quiet ones.
Earliest documented
Apple's iOS 15 button system (WWDC21, June 2021) added gray, tinted and filled styles. Google's Material 3 filled tonal button arrived the same year. Which came first is unconfirmed: a parallel arrival.
Since then
The default secondary action across iOS and Material products.
Plain: the quietest. Use it for actions people rarely need.
2022
Send ↔ Stop
In AI chat composers, the send button becomes a stop button while an answer streams, then turns back.
Earliest documented
Unconfirmed. ChatGPT (November 2022) popularised it, but the only sources found, in two searches, are user forums. OpenAI's release notes do not mention it.
/* The pointer stands in for your eyes; the glow is clipped to each shape */
.gaze button { position: relative; overflow: hidden; }
.gaze button::after {
content: ""; position: absolute; inset: 0; opacity: 0;
background: radial-gradient(100px circle at var(--x) var(--y),
rgb(255 255 255 / .3), transparent 70%);
}
.gaze button.look::after { opacity: 1; }
.gaze button:disabled::after { display: none; } /* no highlight */
Move over the buttons: the glow follows, trimmed to each shape. The disabled one stays dark.
2025
Buttons that change shape when pressed
Instead of only changing colour, buttons now squish, round and make room. A connected group of buttons replaces the older segmented control.
Earliest documented
Google's Material 3 Expressive update (May 2025): more shapes and sizes, toggle behaviour, and shape changes on press and selection. Segmented buttons are deprecated in favour of connected button groups.
Since then
Google's own contribution, shipped with its 2025 Android and Material updates.
Press and hold one: it widens and squishes, and its neighbours make room.
2025
3D, animated icon tabs
Category buttons with small dimensional icons that play a moment when pressed: tactile and playful after a decade of flat design.
Earliest documented
Airbnb's app relaunch (May 2025): a Homes / Experiences / Services switcher with 3D-rendered icons. The balloon breathes fire and the bell shakes when pressed.
<div role="tablist" aria-label="Categories">
<button role="tab" aria-selected="true"><svg>…</svg> Stays</button> …
</div>
/* Each icon plays its own short moment when its tab is pressed */
.balloon.anim .lift { animation: rise .9s cubic-bezier(.3,1.4,.5,1); }
.balloon.anim .flame { animation: flicker .3s 3; }
.bell.anim .ring { animation: shake .6s; transform-origin: 50% 15%; }
@media (prefers-reduced-motion: reduce) { .anim * { animation: none; } }
Generalised: line-art icons stand in for 3D renders.
2025
Glass buttons
Controls became a translucent layer that floats above content, bending what is behind it and reacting to touch. Beautiful over calm content, and harder to read over busy content.
Earliest documented
Apple's Liquid Glass, announced at WWDC on 9 June 2025: translucent, malleable controls that refract content and react to touch, as a layer above apps.
Since then
Reviewers raised contrast concerns over complex backgrounds, the same lesson neumorphism taught.
Confidence
High for the announcement · Apple's own docs to add
<button class="glass">Continue</button>
/* A generalised glass control, not Apple's material */
.glass {
min-height: 52px; padding: 0 26px; border-radius: 999px;
background: radial-gradient(80px circle at var(--px) var(--py),
rgb(255 255 255 / .35), transparent 70%), rgb(255 255 255 / .12);
border: 1px solid rgb(255 255 255 / .35);
backdrop-filter: blur(6px) saturate(1.6);
transition: transform .5s cubic-bezier(.3, 1.6, .5, 1); /* springy */
}
.glass:active { transform: scale(1.12, .94); } /* squashes like a drop */
/* JS sets --px/--py from the pointer, and stretches it while dragging */
Grab the Continue button and drag it between the striped and plain sides (or focus it and use the arrow keys).
Guide 02 · Interaction · Checked October 2026
How we learned to touch, swipe and ask
Ten changes in how we move through interfaces, from infinite feeds to AI working beside us. Each first is the earliest documented case, with sources; disputed ones are marked.
Changes
10, oldest first
Span
2006 origins to 2026
Demos
Live, with Design and Dev views
Sources
Company docs first, then press
Timeline
Oldest first. Hollow dot: where a pattern started. Solid dot: its latest big change. Point at a name to preview it; select it to jump there.
// Load the next page when a sentinel at the end scrolls into view
const io = new IntersectionObserver(([e]) => {
if (e.isIntersecting) loadMore();
}, { root: feed, rootMargin: '0px 0px 120px' });
io.observe(sentinel);
Scroll the feed: more items arrive before you reach the end.
2007
Pinch to zoom
Two fingers move apart and the content grows around the point between them. Direct manipulation replaced zoom buttons.
Earliest documented
In a mass-market phone: the original iPhone, announced 9 January 2007 with "multi-touch". Disputed as a "first": multi-touch research is much older, and Jeff Han demonstrated it publicly in February 2006.
Since then
The default way to zoom maps, photos and pages on every touch screen.
Confidence
High for the iPhone date · medium for the earlier history
// Two pointers: scale by the change in distance, around their midpoint
const d = Math.hypot(a.x - b.x, a.y - b.y);
scale = clamp(startScale * d / startDist, .1, 4); // 10% to 400%
pic.style.transformOrigin = `${mid.x}px ${mid.y}px`;
pic.style.transform = `scale(${scale})`;
pic.style.touchAction = 'none'; // the page itself must not zoom
Pinch on a touch screen, or use + and − (10% to 400%). Play shows two fingers.
2007 → 2014
Swipe actions on list rows
Swiping a row sideways reveals actions behind it, and a long swipe commits the action. Triage became a gesture.
Earliest documented
Swipe-to-delete existed in the first iPhone apps; Mailbox (2013) made swiping the main way to sort email; Apple's iOS 8 Mail (2014) added configurable swipe actions.
Since then
Standard in mail and list apps on iOS and Android.
Confidence
Low · no dated primary source for any of the three dates
// Follow the finger; past 40% of the width, commit on release
row.onpointermove = e => { dx = Math.min(0, e.clientX - x0); row.style.translate = `${dx}px 0`; };
row.onpointerup = () => dx < -row.offsetWidth * .4 ? archive(row) : snapBack(row);
/* Keyboard and screen readers get the same action as a real button */
Grab a row and drag it to the left: a short drag peeks at Archive, a long one archives it. Keyboard: Tab to the Archive button on each row.
2009 → 2012
Pull to refresh
Pull the top of a list down past a point and let go to load new items. The gesture became the button.
Earliest documented
Loren Brichter's Tweetie 2 for iPhone (2009). The patent was filed in 2010 and granted to Twitter in 2013, which promised to use it only defensively.
Since then
Apple added a system control in iOS 6 (2012) and it spread everywhere; many apps now refresh on their own instead.
// Fuzzy match: the typed letters appear in order
const match = (q, s) => { let i = 0; for (const c of s.toLowerCase()) if (c === q[i]) i++; return i === q.length; };
addEventListener('keydown', e => {
if ((e.metaKey || e.ctrlKey) && e.key === 'k') { e.preventDefault(); open(); }
});
Open it, type a few letters, use the arrow keys and Enter.
2016 → 2021
Sheets that stop at set heights
A panel slides up from the bottom and rests at a peek, half or full height, so the content behind stays in view.
Earliest documented
Apple Maps in iOS 10 (2016) replaced its search bar with a card dragged up from the bottom; developers noted it was not yet a system component. iOS 15 (WWDC21) gave every app sheets with "medium" and "large" stop points.
Since then
Used for maps, music and AI apps on both platforms.
/* Detents: the sheet rests at fixed heights */
.sheet { height: 90%; translate: 0 calc(100% - var(--detent)); transition: translate .5s; }
.sheet[data-d="1"] { --detent: 18%; } /* peek */
.sheet[data-d="2"] { --detent: 50%; } /* medium */
.sheet[data-d="3"] { --detent: 90%; } /* large */
// on release, snap to the nearest detent
Grab the grey handle at the top of the sheet and drag it up or down; it settles at the nearest height. Or press it to step through.
2017 → 2019
Gestures replace the home button
A thin bar at the bottom of the screen replaced the home button: swipe up to leave an app. The whole screen became content.
Earliest documented
iPhone X (September 2017): no home button, a home indicator, swipe up to go home. Google's own change: Android 9 (2018) added a pill, and Android 10 (3 September 2019) made full gesture navigation the default.
Since then
The norm on both platforms; apps leave room for the gesture area.
// The app follows the finger and shrinks; past a threshold it goes home
bar.onpointermove = e => {
const up = Math.max(0, y0 - e.clientY), k = Math.min(1, up / 160);
app.style.transform = `translateY(${-up * .6}px) scale(${1 - k * .35})`;
app.style.borderRadius = `${12 + k * 28}px`;
};
bar.onpointerup = () => up > 80 ? goHome() : reopen();
Grab the white bar at the bottom of the phone and drag it upward to go home. Tap the orange icon to open the app again.
2018 → 2021
Inline AI suggestions
The model guesses how your sentence ends and shows it in grey ahead of the cursor. One key accepts it; typing on ignores it.
Earliest documented
Gmail Smart Compose, announced at Google I/O on 8 May 2018. GitHub Copilot (technical preview, June 2021) brought it to code. Unconfirmed: Google's post does not describe the grey text or Tab-to-accept.
Draft a short launch note for the new pricing page.
Here is a draft. It is open beside the chat so we can edit it together.
Launch note
/* Chat alone, then chat and work side by side */
.work { display: grid; grid-template-columns: 1fr 0fr; transition: grid-template-columns .6s; }
.work.open { grid-template-columns: .8fr 1.2fr; }
.doc { overflow: clip; }
Send the prompt: the draft opens beside the chat.
Guide 03 · Spacing · Checked October 2026
The space between things
Ten changes in how interfaces are spaced, from column grids to concentric corners. Every demo is a real component whose gaps are revealed layer by layer, then labelled.
Changes
10, oldest first
Span
2008 origins to 2026
Demos
Layer by layer, then labelled
Sources
Specs and company docs first
Timeline
Oldest first. Hollow dot: where a pattern started. Solid dot: its latest big change. Point at a name to preview it; select it to jump there.
Layouts snapped to a fixed set of columns with equal gutters, so pages built by different people still lined up.
Earliest documented
The 960 Grid System by Nathan Smith (2008) popularised 12- and 16-column layouts. Bootstrap, released by Twitter in August 2011, made the 12-column grid a default.
Since then
CSS Grid (2017) let pages define columns natively.
Confidence
Medium · project sites, release posts not re-checked
Switch between Phone and Desktop: the padding and gaps step up.
2014
The 8-point grid
Every size and gap is a multiple of 8 (and 4 for the tightest), so a whole product shares one rhythm and nobody argues about 13 versus 15 pixels.
Earliest documented
As a platform rule: Google's Material Design (2014), where components align to an 8dp grid and type to a 4dp baseline. Disputed as a "first": Android's 2012 design guide already used a 48dp rhythm, and the habit spread through designers' articles.
Since then
Most design systems use 4 or 8 as their base unit.
Press Play: the padding, then section gaps, field gaps and the tight title gap, then all values.
c. 2014 → 2025
Design tokens
Spacing values got names, like space-400, shared by design files and code, so changing one value changes it everywhere.
Earliest documented
Commonly credited to Salesforce's Lightning Design System team around 2014 (their tool, Theo). Unconfirmed: no primary source for the date or the people was found. The W3C Design Tokens Community Group published its first stable specification (2025.10) on 28 October 2025.
Since then
Design tools and code share the same named values.
Press Play: each gap is labelled with its token name and value.
2017
The safe area
Edge-to-edge screens with notches, rounded corners and gesture bars meant content needed a guaranteed safe zone, then its own padding on top.
Earliest documented
iPhone X (2017). WebKit's "Designing Websites for iPhone X" introduced viewport-fit=cover and the safe-area insets, shipped as constant() then env() from iOS 11.2.
Since then
Every edge-to-edge app and site pads for the hardware.
<meta name="viewport" content="width=device-width, viewport-fit=cover">
.screen {
padding: env(safe-area-inset-top) env(safe-area-inset-right)
env(safe-area-inset-bottom) env(safe-area-inset-left);
}
.content { padding: 16px; } /* your own spacing, on top of the safe area */
Press Play: first the safe area the hardware needs, then the content padding.
2017 → 2021
Gap: spacing owned by the layout
Instead of every item carrying its own margin, the container sets one gap between its children. No doubled or leftover edges.
Earliest documented
CSS Grid shipped in all major browsers in March 2017 with grid-gap. Gap for flexbox followed, completing with Safari 14.1 in April 2021.
Since then
Design-system "stack" components and auto layout in design tools work the same way.
/* Before: each item spaces itself; edges and doubles creep in */
.list li { margin: 12px 0; }
/* After: the container owns the spacing */
.list { display: flex; flex-direction: column; gap: 12px; }
Compare Margins and Gap with the Design view: margins add space at the edges too.
2018 → 2023
Minimum touch target sizes
A small icon can still be easy to hit: the tappable area is padded out to a minimum size, and neighbours keep their distance.
Earliest documented
Apple's 44 × 44 point guidance came earlier, but its first date is unconfirmed. Earliest confirmed: WCAG 2.1 (2018), 44 × 44 CSS px at AAA. WCAG 2.2 (October 2023) added a 24 × 24 px minimum at AA. Material uses 48 × 48dp.
Since then
Icons keep their look but get a larger invisible hit area.
Press Play: the drawn icon, then the padding that makes a 44px target, then the gap between targets.
2020
Fluid spacing with clamp()
Instead of jumping at breakpoints, gaps grow smoothly with the screen between a minimum and a maximum.
Earliest documented
CSS clamp() became available across browsers in 2020 (MDN: July 2020). Utopia's article on using it for fluid type and space was published on 25 September 2020.
Since then
Common in design systems that want one scale for every screen.
Drag the width with the Design view on: the values change smoothly.
2021 → 2025
Roomier buttons
Component padding grew. Buttons got taller, rounder and wider inside, trading density for easier reading and tapping.
Earliest documented
Material 3 (2021): the standard button became 40dp tall, fully rounded, with 24dp side padding. Material 2 used 36dp, 16dp padding and 4dp corners; those older values should be re-checked against the archived spec.
Since then
M3 Expressive (2025) added five button sizes, each with its own padding.
Press Play: side padding, then height, then corner radius, compared.
2025
Concentric corners: padding sets the radius
A nested shape's corner radius is its container's radius minus the padding between them, so curves stay parallel at any padding.
Earliest documented
Apple, WWDC25, "Get to know the new design system" (session 356): fixed, capsule and concentric shapes, where a concentric radius is the parent's minus the padding.
Since then
SwiftUI's ConcentricRectangle applies it automatically.
Change the padding: the inner radius recalculates so the curves stay parallel.
How design systems document it
Spec sheets: padding and constraints
A design system documents each component the same way: its padding, the gaps inside it, any fixed or minimum sizes, and how it resizes: it hugs its content, fills its container, or stays fixed. Press Play on any component, or drag the frame width to watch the constraints work.
Height fixed at 56px; the two 44px buttons stay fixed while the title fills the middle and truncates instead of wrapping.
Guide 04 · Media players · Checked October 2026
How the video player learned to help you watch
Ten changes in how video players work on the web and on phones, many of them YouTube's, from the embeddable player to chapters and replay graphs. Each first is the earliest documented case, with sources; uncertain ones are marked.
Changes
10, oldest first
Span
2005 origins to 2026
Demos
One player, a feature per entry
Sources
Company posts first, then press
Timeline
Oldest first. Hollow dot: where a pattern started. Solid dot: its latest big change. Point at a name to preview it; select it to jump there.
YouTube let anyone paste its player into their own site. Video stopped being a file to download and became a box you could drop into a blog post.
Earliest documented
YouTube launched in 2005 with a Flash player whose embed code anyone could copy. Writing in 2006, investor Fred Wilson credited the embeddable player as a key reason for its growth. The exact launch-day embed markup is not confirmed.
Since then
In 2010 YouTube tested an iframe embed that could fall back to HTML5 or Flash; iframe embeds are now the standard. Clicking the picture itself to pause or play is the norm on every web player since; its first dated appearance was not found.
<!-- Since 2010: one iframe; the host serves the right player -->
<iframe src="https://www.youtube.com/embed/VIDEO_ID"
title="Our trip to the coast" allowfullscreen></iframe>
<!-- Flash era (typical form): a plugin object -->
<object data="player.swf" type="application/x-shockwave-flash">…</object>
The same video, embedded the old way and the current way. Click the picture to play or pause, as on every player from here on.
2009
Quality that adapts to your connection
Instead of one file, the player gets the video in several qualities and switches between them as your connection changes, so it keeps playing instead of stopping to buffer.
Earliest documented
Apple's HTTP Live Streaming, released with iPhone OS 3.0 in June 2009: the player measures bandwidth and switches bitrate during playback, in Safari with no extra app.
Since then
MPEG-DASH became the international standard for the same idea. YouTube's "Auto" quality works this way; the details of its rollout were not confirmed in this research.
#EXTM3U (an HLS playlist: one video, four qualities)
#EXT-X-STREAM-INF:BANDWIDTH=400000,RESOLUTION=426x240
240p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1500000,RESOLUTION=854x480
480p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=4000000,RESOLUTION=1280x720
720p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=8000000,RESOLUTION=1920x1080
1080p.m3u8
Play it, then slow the connection: the quality steps down instead of stopping.
2009 → 2010
Captions generated for every video
Speech recognition wrote captions automatically, so videos nobody had captioned could still be followed without sound, or in another language.
Earliest documented
Google announced automatic captions for YouTube on 19 November 2009, combining its speech recognition with the YouTube caption system, first for a group of partners.
Since then
Reported as available to all users from March 2010, then in more languages. Auto captions carry an "auto-generated" label because they make mistakes.
Turn on CC: captions follow the speech, labelled as auto-generated.
2010 → 2015
Video without a plugin
The browser itself learned to play video. Players no longer needed a plugin, which meant they worked on phones, and their controls could be styled and made accessible like the rest of the page.
Earliest documented
YouTube began testing an HTML5 video player in January 2010, opt-in at first.
Since then
On 27 January 2015 YouTube made HTML5 its default player in Chrome, Internet Explorer 11, Safari 8 and beta Firefox.
// The standard API (Chrome, Edge, Safari)
pipButton.onclick = async () => {
if (document.pictureInPictureElement) await document.exitPictureInPicture();
else await video.requestPictureInPicture();
};
Press the picture-in-picture button (bottom right of the player): the video floats above the page. Then grab it and drag it to any corner.
2016
Inline playback and muted autoplay on iPhone
On iPhone, every web video used to jump to fullscreen. From iOS 10 it could play inside the page, and silent videos could start on their own when scrolled into view.
Earliest documented
WebKit's "New video policies for iOS" (2016): videos marked playsinline play inside the page on iPhone; muted videos may autoplay, only while visible, and pause if unmuted without a tap.
Since then
Muted, inline autoplay became the standard way to show video previews and replace GIFs.
// Two taps within 300ms on one half of the video seek by 10s
screen.onpointerup = e => {
if (e.timeStamp - lastTap < 300) seek(e.offsetX < screen.clientWidth / 2 ? -10 : 10);
lastTap = e.timeStamp;
};
// Keyboard: J and L do the same
Double-click (or double-tap) either half to skip, or press J and L. A single click still pauses.
2017
Web video on the lock screen
A page playing media can show its title, artwork and controls on the phone's lock screen and in notifications, like a native app.
Earliest documented
The Media Session API in Chrome 57 for Android (stable March 2017): sites supply title, artist and artwork, and handle play, pause, seek and skip.
Since then
Supported in other browsers and on desktop, including the controls in picture-in-picture windows.
<!-- Chapters come from timestamps, e.g. in the description -->
0:00 Intro
0:12 The trail
0:31 The ridge
0:51 Wrap up
/* The bar is drawn as segments with small gaps between them */
Point at or focus the progress bar: each segment names its chapter.
2022
The most replayed moments
A small graph above the progress bar shows which parts other people replayed most, so viewers can find the highlight without scrubbing.
Earliest documented
YouTube's "Most replayed" graph, rolled out to all users on 18 May 2022 after an experiment: while seeking, a graph shows the most frequently replayed parts.
Since then
A standard part of YouTube's player on web and mobile.