polish

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

polish

润色与完善

Polish is not adding things. It is the list of things that are already wrong that nobody has looked at yet. Run it top to bottom; fix everything you find; do not skip an item because it seems small. Small is the point.
润色不是添加内容,而是把那些已经存在问题、却还没有人检查的地方列成清单。从上到下逐项执行;发现什么就修复什么;不要因为某项看起来很小就跳过。小处正是关键。

Document and metadata

文档与元数据

  • <title>
    is specific per page: "Settings — App", not "App". Updates on client navigation.
  • Title reflects state where useful: an unread count, an unsaved dot ("• Untitled").
  • Favicon: SVG with a dark-mode variant via
    prefers-color-scheme
    inside the SVG, plus a 32px PNG fallback and a 180px apple-touch-icon.
  • Open Graph and Twitter images exist, are 1200×630, and show the page's title in the site's type, not a generic logo.
  • theme-color
    meta for both schemes so the browser chrome matches.
  • lang
    on
    <html>
    .
    color-scheme
    on the root.
  • Canonical URLs; no duplicate content at
    /page
    and
    /page/
    .
  • A 404 page in the app's frame, with a way back and a search if the app has one.
  • <title>
    应按页面设置具体内容:使用“设置 — App”,而不是“App”。在客户端导航时更新。
  • 标题在有帮助时反映状态:未读计数、未保存圆点(“• 未命名”)。
  • Favicon:使用 SVG,并通过 SVG 内的
    prefers-color-scheme
    提供深色模式变体,另提供 32px PNG 备用图标和 180px apple-touch-icon。
  • 提供 Open Graph 和 Twitter 图片,尺寸为 1200×630,并使用站点字体显示页面标题,而不是通用 Logo。
  • 为两种配色方案都设置
    theme-color
    meta,让浏览器界面与主题一致。
  • <html>
    设置
    lang
    ,根元素设置
    color-scheme
    。
  • 使用 Canonical URL;
    /page
    和
    /page/
    不得产生重复内容。
  • 在应用框架内提供 404 页面,并提供返回入口;如果应用有搜索功能,也应提供搜索。

Text

文本

  • Sentence case in every button, label, heading and menu item.
  • No orphan words on titles:
    text-wrap: balance
    .
  • Tabular numerals on every number in a column, counter, price, timestamp or shortcut.
  • Real apostrophes and quotes (’ “ ”), en dashes for ranges, ellipsis character not three dots.
  • Empty states, error messages and loading text are written, not placeholder.
  • No "Lorem", no "TODO", no
    console.log
    in production.
  • Dates are formatted for the locale, relative when recent ("4m ago"), with the absolute time on hover.
  • 每个按钮、标签、标题和菜单项都使用 sentence case。
  • 标题中不出现孤词:使用
    text-wrap: balance
    。
  • 列、计数器、价格、时间戳或快捷键中的每个数字都使用等宽数字(tabular numerals)。
  • 使用真正的撇号和引号(’ “ ”),范围使用 en dash,省略号使用省略号字符,而不是三个句点。
  • 空状态、错误消息和加载文案都经过撰写,而不是占位内容。
  • 不出现“Lorem”“TODO”,生产环境中不出现
    console.log
    。
  • 日期按当前区域设置格式化;近期日期使用相对时间(“4 分钟前”),悬停时显示绝对时间。

Colour and surface

颜色与界面表面

  • ::selection
    set to match the palette.
  • Scrollbars themed:
    scrollbar-width: thin; scrollbar-color
    .
  • Focus ring visible on every surface: test on the darkest and lightest backgrounds.
  • Both themes reviewed on every screen. No
    #fff
    text on
    #000
    .
  • No flash of the wrong theme on load.
  • Form controls,
    <select>
    popups and date pickers match the theme (
    color-scheme
    ).
  • Disabled states are visibly disabled but still legible.
  • 将
    ::selection
    设置为与配色方案一致。
  • 滚动条使用主题样式:
    scrollbar-width: thin; scrollbar-color
    。
  • 每种表面上都能看到焦点环:在最深和最浅的背景上分别测试。
  • 每个界面都检查两种主题。不要出现
    #fff
    文字位于
    #000
    背景上的情况。
  • 加载时不出现错误主题闪烁。
  • 表单控件、
    <select>
    弹出层和日期选择器与主题保持一致(
    color-scheme
    )。
  • 禁用状态在视觉上明显处于禁用状态,同时仍保持清晰可读。

Layout

布局

  • Nothing shifts on load: images have dimensions, fonts have metric fallbacks, skeletons match content.
  • Sticky header offset applied to anchors and focus targets (
    scroll-margin-top
    ).
  • No horizontal scroll at 375px.
  • Side gutters 16px on phones, never 0.
  • Safe areas respected for fixed bottom elements.
  • Long content tested: the longest name, the longest error, 0 items, 10,000 items.
  • Scrollbar gutter compensated when a dialog locks scroll (no 15px jump).
  • 加载时内容不发生位移:图片设置尺寸,字体设置度量兼容回退,骨架屏与实际内容匹配。
  • 为锚点和焦点目标应用粘性头部偏移(
    scroll-margin-top
    )。
  • 在 375px 宽度下不出现水平滚动。
  • 手机端左右边距为 16px,绝不为 0。
  • 固定在底部的元素遵守安全区域。
  • 测试长内容:最长的名称、最长的错误信息、0 个条目、10,000 个条目。
  • 对话框锁定页面滚动时补偿滚动条槽宽度(避免 15px 跳动)。

Interaction

交互

  • Every button has
    :active
    feedback.
  • Hover effects gated to
    @media (hover: hover)
    .
  • Every icon-only control has an
    aria-label
    and a tooltip.
  • Keyboard shortcuts shown somewhere visible: tooltips, menu items, a footer hint.
  • Copy actions confirm inline (icon swap) and handle clipboard failure.
  • External links open in a new tab with an arrow marker and
    rel="noopener"
    .
  • Links have
    cursor: pointer
    ; drag handles have
    grab
    .
  • Escape closes the top layer; focus returns to the trigger.
  • Double submit prevented.
  • Toasts pause on hover and when the tab is hidden.
  • 每个按钮都有
    :active
    反馈。
  • 悬停效果通过
    @media (hover: hover)
    门控。
  • 每个仅含图标的控件都有
    aria-label
    和 tooltip。
  • 在可见位置显示键盘快捷键:tooltip、菜单项或页脚提示均可。
  • 复制操作通过内联方式确认(切换图标),并处理剪贴板失败。
  • 外部链接在新标签页中打开,并带箭头标记和
    rel="noopener"
    。
  • 链接使用
    cursor: pointer
    ;拖动手柄使用
    grab
    。
  • Escape 键关闭最上层内容;焦点返回触发元素。
  • 防止重复提交。
  • Toast 在鼠标悬停或标签页隐藏时暂停计时。

Motion

动效

  • prefers-reduced-motion
    handled globally and nothing is hidden behind an animation that never runs.
  • No
    transition: all
    .
  • Entrances ease out; exits are shorter.
  • Nothing animates on every re-render (check list filters, tab switches, sorts).
  • Page-load animations happen once, on the first paint, not on every navigation back.
  • No animation on keyboard-driven actions.
  • 全局处理
    prefers-reduced-motion
    ,且不能有内容因永远不会执行的动画而一直隐藏。
  • 不使用
    transition: all
    。
  • 入场动画采用缓出效果;退场动画时长更短。
  • 每次重新渲染时都不触发动画(检查列表筛选、标签切换和排序)。
  • 页面加载动画只在首次绘制时执行一次,而不是每次返回上一页时都执行。
  • 键盘触发的操作不播放动画。

Icons and imagery

图标与图像

  • One icon set, one stroke width,
    currentColor
    .
  • Icons optically aligned with text (usually 1px up).
  • Decorative icons
    aria-hidden
    .
  • Images:
    alt
    written,
    loading="lazy"
    below the fold, modern formats,
    srcset
    for retina.
  • Avatars have a fallback (initials on a neutral surface) that matches the size exactly.
  • Favicons for external items fetched from the site's own declared icon, with a fallback letter tile.
  • 统一使用一套图标、一种描边宽度和
    currentColor
    。
  • 图标在视觉上与文字对齐(通常上移 1px)。
  • 装饰性图标设置
    aria-hidden
    。
  • 图片:编写
    alt
    ,首屏以下的图片使用
    loading="lazy"
    ,采用现代格式,并使用
    srcset
    支持 Retina。
  • 头像提供回退方案(中性表面上的姓名首字母),且尺寸完全匹配。
  • 外部项目的 Favicon 从其站点自己声明的图标获取,并提供字母磁贴作为回退。

Performance you can feel

可感知的性能

  • Fonts preloaded (the two weights above the fold),
    font-display: swap
    with metric overrides.
  • Route transitions do not white-flash; the frame persists.
  • Interaction to next paint under 100ms on a throttled CPU for the primary actions.
  • Large lists virtualised; large images not decoded on the main thread on scroll.
  • content-visibility: auto
    on long below-the-fold sections.
  • No layout thrash from measuring in loops.
  • 预加载首屏使用的两种字体字重,使用
    font-display: swap
    并设置度量覆盖。
  • 路由切换不出现白屏闪烁;界面框架保持存在。
  • 在 CPU 降速条件下,主要操作从交互到下一次绘制的延迟低于 100ms。
  • 大型列表采用虚拟化;滚动时,大图片不在主线程中解码。
  • 对首屏以下的长内容段使用
    content-visibility: auto
    。
  • 不因在循环中测量元素而造成布局抖动。

Machine readers

面向机器读取

  • Headings form an outline (one
    h1
    , then
    h2
    …).
  • Landmarks:
    header
    ,
    nav
    ,
    main
    ,
    footer
    , with
    aria-label
    when there is more than one of a kind.
  • A skip link to main content.
  • Structured data if the content is a list, article or product.
  • robots
    ,
    sitemap
    , and if the site is a resource,
    llms.txt
    .
  • 标题构成清晰的层级结构(一个
    h1
    ,然后是
    h2
    ……)。
  • 设置地标元素:
    header
    、
    nav
    、
    main
    、
    footer
    ;同类元素有多个时使用
    aria-label
    区分。
  • 提供跳转到主内容的 skip link。
  • 内容为列表、文章或产品时,提供结构化数据。
  • 提供
    robots
    、
    sitemap
    ;如果站点是资源型站点,还应提供
    llms.txt
    。

The no-JavaScript and slow-network pass

无 JavaScript 与慢速网络检查

  • Every word and link is in the HTML. Turn JavaScript off and read the page.
  • Elements hidden for a reveal animation are visible without JS (
    html:not(.js) [data-reveal] { opacity: 1 }
    ).
  • Throttle to Slow 3G once and watch the load order. Nothing critical arrives last.
  • 每个文字和链接都包含在 HTML 中。关闭 JavaScript 后,页面内容仍可阅读。
  • 为揭示动画而隐藏的元素在没有 JS 时也可见(
    html:not(.js) [data-reveal] { opacity: 1 }
    )。
  • 将网络限速至 Slow 3G 一次并观察加载顺序。关键内容不得最后到达。

Ship gate

发布门禁

The interface is finished when you can:
  1. Tab through every screen without a mouse.
  2. Use it at 375px with one thumb.
  3. Switch theme on every screen and nothing looks wrong.
  4. Turn on reduced motion and nothing is missing.
  5. Read every state: loading, empty, error, done.
  6. Find no value that is not a token: colours, spacing, easing, duration, radius.
当你能够做到以下事项时,界面才算完成:
  1. 不使用鼠标,仅通过 Tab 键浏览每个界面。
  2. 在 375px 宽度下使用单手拇指完成操作。
  3. 在每个界面上切换主题,且没有任何内容显得异常。
  4. 开启减少动态效果后,没有任何内容缺失。
  5. 每种状态都可阅读:加载、空状态、错误和完成。
  6. 所有值都使用 token:颜色、间距、缓动、时长和圆角。

From the catalogue

相关资源