算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
forgiveness【设计与创意】Use this skill whenever a design lets users do something they might regret — delete, send, publish, charge, transfer, archive, overwrite, irrecoverably commit. Trigger when designing destructive actions, undo systems, confirmation dialogs, soft-delete recovery, draft-saving, transaction reversal, "are you sure?" patterns, or any flow where a wrong mo…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Forgiveness is the property of a design that helps users avoid mistakes and recover gracefully from the ones they make. The opposite — an unforgiving design — punishes errors with lost work, irreversible changes, or hostile error states. Since human error is inevitable, forgiving design is what determines whether the product is pleasant to use over time or a constant source of low-grade anxiety.
A forgiving design recognizes that users will make mistakes — slips (correct intent, wrong action), mistakes (wrong intent because of wrong model), and accidents (the cat walked across the keyboard). It builds in mechanisms to prevent errors before they happen, minimize their consequences when they do happen, and recover from them when prevention and minimization both fail. The principle's central insight: error is a property of the design, not of the user. A design that produces lots of user error is a poorly-designed design, even if every user "could have been more careful."
Roughly ordered from preferred to least preferred — preferred ones reduce the need for the others:
If the design makes the wrong action impossible or hard to do by accident, the error never occurs. A USB connector that can't be inserted upside-down (USB-C). A dialog where the destructive button is small and far from the safe one. A control that's only enabled when the operation makes sense.
This is the highest level of forgiveness because it requires no user attention or recovery — the error is structurally prevented.
If the user can undo, the error costs only the time to notice and reverse. Cmd-Z is the canonical example; soft-delete with a recovery window is its data-layer counterpart. Version history is its document counterpart.
Reversibility is preferred to confirmation because it doesn't punish exploration. Users who feel safe to try things learn faster and use the product more confidently.
A system or feature that minimizes damage when an error does happen and isn't reversible. Crumple zones in cars. Auto-saving drafts. Trash with a recovery window. Backup systems. The pilot's ejection seat in a fighter jet.
Safety nets are insurance against the unanticipated. They cost design and engineering effort but pay off when prevention and reversibility weren't enough.
The user is asked to verify before a high-stakes action commits. "Are you sure you want to delete?" "Type DELETE to confirm." "Enter your password to authorize."
Confirmation is the most-overused forgiveness mechanism and the easiest to abuse. Confirmations applied to routine reversible actions get dismissed on autopilot, training users to ignore them when they finally apply to a real destructive action.
Visual or auditory cues that something dangerous is about to happen. A "you have unsaved changes" prompt before navigating away. A warning label on industrial equipment. A road sign for a sharp curve.
Warnings work when applied sparingly to genuinely high-consequence moments. They become wallpaper when applied to everything.
Documentation, error messages with remediation steps, support chat, recovery flows. The lowest-preferred level because it kicks in after the error has already happened and disrupted the user's task.
A useful diagnostic: the amount of help required is inversely proportional to the quality of the design. If users need extensive help to use your product, the help is compensating for missing forgiveness at the higher levels.
The goal isn't maximum confirmation; it's appropriate friction calibrated to the action's stakes.
Most modern apps prefer reversibility over confirmation for routine destructive actions.
<button onclick="archive(item)">Archive</button>
<script>
async function archive(item) {
const previous = items.slice();
items = items.filter(i => i.id !== item.id);
render();
await api.archive(item.id);
showToast(`"${item.name}" archived`, {
action: { label: 'Undo', onClick: () => unarchive(item, previous) },
duration: 7000,
});
}
function unarchive(item, previous) {
items = previous;
render();
api.unarchive(item.id);
}
</script>
The action is one click; if wrong, one click in the toast restores. Most users never need the undo; the few who do have a 7-second window. No confirmation dialog, no friction on the common path.
Some actions genuinely can't be undone (or shouldn't be made undoable for security/compliance reasons). For these, raise friction deliberately.
<button onclick="openDeleteDialog()">Delete account</button>
<dialog id="delete-dialog">
<h2>Delete account permanently?</h2>
<p>This deletes your account, all your projects (12), and revokes access for your team (38 members). It cannot be undone.</p>
<p>To confirm, type your account email below:</p>
<input id="confirm-input" placeholder="you@example.com" />
<div class="actions">
<button onclick="closeDialog()">Cancel</button>
<button id="confirm-btn" disabled class="destructive">
Delete account permanently
</button>
</div>
</dialog>
<script>
const input = document.getElementById('confirm-input');
const btn = document.getElementById('confirm-btn');
input.addEventListener('input', () => {
btn.disabled = input.value !== currentUser.email;
});
</script>
The user must (a) intend to open the dialog, (b) read the consequences laid out, (c) actively type their email, (d) click the destructive button. Each step is a chance to step back. For genuinely irreversible high-stakes actions, this stack is appropriate.
A form that auto-saves drafts protects the user from navigation accidents, browser crashes, and second-guessing.
<form id="post-editor">
<input name="title" placeholder="Title" />
<textarea name="body" placeholder="Write your post..."></textarea>
<p class="save-status" aria-live="polite">All changes saved</p>
<button>Publish</button>
</form>
<script>
const form = document.getElementById('post-editor');
const status = form.querySelector('.save-status');
form.addEventListener('input', debounce(async () => {
status.textContent = 'Saving...';
await api.saveDraft(serialize(form));
status.textContent = `Saved at ${formatTime(new Date())}`;
}, 600));
</script>
The user never thinks about saving; the system saves continuously. If they navigate away, the draft survives. If they refresh, the draft restores. The "Publish" button is the only commit; everything else is reversible.
When the user has unsaved work and tries to leave, a warning is appropriate friction.
window.addEventListener('beforeunload', (e) => {
if (form.dataset.dirty === 'true') {
e.preventDefault();
e.returnValue = ''; // browsers show their own confirmation
}
});
The browser's native dialog appears. The user can cancel and stay, or confirm and lose changes. If you've also implemented auto-save, this dialog appears only briefly between auto-saves — and the saved draft is still there if they leave.
A poorly-designed error message says "Error 503." A forgiving error message names the problem, explains what went wrong, and offers the next step.
<div class="error-card">
<h3>We couldn't process your payment</h3>
<p>
Your card (ending in 4242) was declined. This usually means insufficient
funds or a billing-address mismatch.
</p>
<p>
<button>Try a different card</button>
<a href="/help/declined-payments">Why was my card declined?</a>
</p>
</div>
The error doesn't blame the user; it explains, offers an action, and provides a path to deeper help.
The ultimate safety net. The pilot can't undo a structural failure, but they can leave the aircraft. The seat itself is a forgiveness mechanism — designed for the moment everything else has failed.
The front and rear of a car are deliberately weakened to absorb collision energy through controlled deformation, protecting the cabin and occupants. This is "weakest link" applied to forgiveness — the chosen failure point preserves what matters.
Medication errors are a leading cause of preventable hospital harm. Forgiveness mechanisms include weekly pill organizers (good affordance — visible state of taken vs. untaken), barcode scanning (verification), and the "five rights" workflow (right patient, right drug, right dose, right route, right time).
Before maintenance on hazardous equipment, workers physically lock and tag the energy source so it can't be activated until the lock is removed. A forcing function that prevents accidental energizing — a pure prevention strategy.
Microsoft Word and successors normalized undo as standard. Modern systems extend this to version history (Google Docs, Notion) — the user can not only undo recent changes but visit any prior state.
Gmail introduced an "Undo send" feature with a default 5-second window (configurable up to 30). The send doesn't actually go out for that period; cancel reverses it. A reversibility mechanism applied to a previously-irreversible action.
affordance — good affordances prevent errors; this is the highest level of forgiveness.constraint — constraints prevent invalid actions structurally.errors — slip vs. mistake distinction shapes which forgiveness mechanism applies.feedback-loop — feedback after an action lets the user catch errors quickly.factor-of-safety (process) — engineering version of the same idea: design with margin so normal operation isn't at the edge of failure.weakest-link (process) — crumple-zone logic; deliberately failing at a chosen point.accessibility-understandable (process) — error identification and recovery are accessibility requirements.forgiveness-undo-and-soft-delete — designing reversibility: undo systems, soft delete, version history, the "Undo Send" pattern.forgiveness-confirmation-and-prevention — when confirmation is appropriate, how to design it, and how to prevent confirmation fatigue.Forgiveness is the principle that determines whether a product is loved or feared. Loved products let users explore, undo, and recover; users develop confidence and use them daily without anxiety. Feared products punish exploration; users develop anxious habits and stick to the obvious paths. Build for the loved version: prevent first, reverse second, confirm only when you must.