Mobile wallet UI patterns
Practical mobile wallet patterns for bottom sheets, thumb reach, touch targets, biometric confirmation, QR scanning and token rows that fit small screens.
5 min read
A mobile wallet is often used one-handed, on the move, on a screen around 360 to 430 CSS pixels wide, for actions that move real money. That combination shapes almost every design decision: where buttons go, how big they are, how confirmations work, and how much fits in a row next to a token logo.
This guide covers the patterns that have become common in mobile wallets and mobile web dApps, and the details that make them work.
Bottom sheets for focused tasks
Bottom sheets, panels that slide up from the bottom edge, suit most secondary tasks in a wallet: picking a token, choosing a network, reviewing a transaction, showing a receive address. They keep the person's context visible behind them and put the content where the thumb already is.
Guidelines that keep sheets usable:
- Size to the content. A network picker with five options shouldn't fill the screen. Let longer content, like a token list with search, expand to near full height.
- Offer a visible close button, not only a drag handle and swipe-down gesture. WCAG 2.5.7 Dragging Movements (AA) requires a single-pointer alternative to dragging, and a close button is also clearer for everyone.
- Don't stack sheets. Opening a sheet from a sheet makes "back" ambiguous. Replace the content inside the same sheet, with a back arrow, or close the first sheet before opening the next.
- Manage focus. When a sheet opens, move focus into it; when it closes, return focus to the control that opened it. Treat it as a dialog for assistive technology.
A transaction review sheet should show the summary in words first, then the details: "Send 50 USDC to 0x5aAe…eAed on Base", fee, then the confirm button at the bottom.
Primary actions within thumb reach
On a phone held in one hand, the bottom of the screen is easiest to reach and the top corners are hardest. Put primary actions, such as Send, Confirm and Swap, in a sticky bar at the bottom. Keep destructive or rarely used actions out of the easiest positions.
On devices with a home indicator or rounded corners, respect the safe area so the button doesn't sit under system UI:
.action-bar {
position: sticky;
bottom: 0;
padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
background: var(--surface);
}
For env(safe-area-inset-bottom) to return a value on iOS, the page needs viewport-fit=cover in its viewport meta tag:
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
Sticky bars can also cover focused fields and links when someone navigates with a keyboard or switch control. Leave room for them with scroll-padding-bottom on the scroll container, as described in focus not obscured.
Touch targets
Small icon buttons are everywhere in wallets: copy address, show QR, hide balance, close. They need to be easy to hit without hitting the neighbor.
| Reference | Minimum size |
|---|---|
| WCAG 2.5.8 Target Size (Minimum), AA | 24 by 24 CSS pixels, with exceptions such as enough spacing |
| WCAG 2.5.5 Target Size (Enhanced), AAA | 44 by 44 CSS pixels |
| Apple Human Interface Guidelines | 44 by 44 points |
| Material Design | 48 by 48 dp |
For a wallet, aim for 44px or more on anything you tap often, especially near amounts and addresses where a mistap has consequences. A 20px copy icon can keep its visual size while the button around it is 44px:
.icon-button {
display: inline-grid;
place-items: center;
min-width: 44px;
min-height: 44px;
}
Target size: how big should clickable icons be? goes through the WCAG exceptions in detail.
Biometric confirmation
Native wallets often use Face ID, Touch ID or Android biometrics to authorize a transaction or reveal a recovery phrase. Biometrics confirm who is acting. They don't explain what is being approved, so the order matters:
- Show the full summary: what, how much, to whom, on which network, the fee.
- The person taps Confirm.
- The biometric prompt appears.
- On success, the transaction is signed and sent.
Never trigger the biometric prompt as the screen opens, before the person has read the summary. It trains people to approve by reflex. Always provide the device passcode or a wallet PIN as a fallback, since biometrics fail with gloves, wet fingers and changes in appearance. For web apps, passkeys through WebAuthn bring similar device-level confirmation, and the same order applies.
QR scanning
Scanning a QR code is one of the most common ways to enter an address on a phone. A scanned code can contain several formats, and the wallet has to understand them and show what it found before acting:
0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed
ethereum:0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed@8453
bitcoin:<address>?amount=0.001
solana:<recipient>?amount=1
The first is a bare address. The second is an EIP-681 payment URI, which can include a chain ID, here Base. The third and fourth are BIP-21 and Solana Pay URIs. Parse what you support, and then:
- Show the parsed result on a confirmation screen: the address, the network, and any amount from the code. Never send directly from a scan.
- Catch network mismatches. If the code specifies Base and the person is sending from Ethereum, say so before they continue.
- Explain the camera permission before the system prompt appears: "Allow camera access to scan QR codes."
- Offer paste as an alternative right on the scanner screen, for people who have the address on their clipboard.
Showing the scanned address in full, grouped in fours, lets people compare it with the source. Displaying wallet addresses explains why truncation alone isn't enough on confirmation screens.
Token rows on small screens
The token list is the main screen of many wallets, and each row has to fit an icon, a name, a ticker, a balance and a fiat value into roughly 360px. A three-column grid handles it:
.token-row {
display: grid;
grid-template-columns: 32px minmax(0, 1fr) auto;
align-items: center;
gap: 12px;
min-height: 64px;
padding: 8px 16px;
}
.token-row .name {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.token-row .amounts {
text-align: right;
font-variant-numeric: tabular-nums;
}
The minmax(0, 1fr) column lets long names truncate instead of pushing the amounts off screen. Stack the name over the ticker on the left, and the fiat value over the token amount on the right, or the other way round if your users care more about units than value. Use a 32px icon for the main list, and drop to 24px only in denser secondary lists. Shorten very large balances with compact notation in the row, and show the exact figure on the token's detail screen. More on sizes, styles and unknown tokens in these rows is in showing token logos in a wallet interface.
Test every screen at 320px wide with large text enabled in the system settings. If rows still fit and buttons are still reachable, the layout will hold on nearly every phone.