Loading Copy

로딩 문구

"Loading..." on repeat starts to feel frozen. Saying what's loading and how much shrinks the perceived wait.

Also known as: Progress copy
···
html
<div class="stage">
  <div class="pane bad"><span class="mark">✕</span><span class="label">Before</span>
    <div class="loadrow"><span class="spin"></span><p class="copy" id="bt"></p></div>
    <p class="why" id="bw"></p></div>
  <div class="pane good"><span class="mark">✓</span><span class="label">After</span>
    <div class="loadrow"><span class="spin good-spin"></span><p class="copy" id="gt"></p></div>
    <p class="why" id="gw"></p></div>
</div>
css
.stage{width:94%;height:88%;display:flex;gap:4%}
.pane{position:relative;flex:1;border-radius:14px;border:1px solid var(--line);background:var(--surface);padding:16px 14px 12px;display:flex;flex-direction:column;justify-content:center;align-items:center;gap:10px}
.mark{position:absolute;top:10px;right:12px;font:800 16px/1 system-ui;color:var(--accent-2)}
.good .mark{color:var(--accent-3)}
.label{position:absolute;top:10px;left:12px;font:700 10px/1 monospace;color:var(--muted);text-transform:uppercase;letter-spacing:.06em}
.loadrow{display:flex;align-items:center;gap:10px}
.spin{width:16px;height:16px;flex:none;border-radius:50%;border:2px solid var(--line);border-top-color:var(--accent-2);animation:spin .9s linear infinite}
.good-spin{border-top-color:var(--accent-3)}
@keyframes spin{to{transform:rotate(360deg)}}
.copy{margin:0;font:600 clamp(10px,2.7vmin,13px)/1.35 -apple-system,sans-serif;color:var(--fg)}
.why{margin:0;font:500 11px/1.3 -apple-system,sans-serif;color:var(--muted);text-align:center}
js
const bt = document.getElementById('bt'), bw = document.getElementById('bw');
const gt = document.getElementById('gt'), gw = document.getElementById('gw');
const koBad = '\uB85C\uB529\uC911...';
const enBad = 'Loading...';
let lang = 'ko', step = 0;
function paint() {
  const n = (step % 5) + 1;
  bt.textContent = lang === 'ko' ? koBad : enBad;
  bw.textContent = lang === 'ko' ? '계속 같은 말만 반복' : 'repeats the same phrase forever';
  gt.textContent = lang === 'ko' ? '이미지를 불러오는 중이에요 (' + n + '/5)' : 'Fetching images (' + n + ' of 5)';
  gw.textContent = lang === 'ko' ? '대상 + 진행률이 눈에 보임' : 'shows the target and visible progress';
}
paint();
setInterval(() => { step++; if (step % 5 === 0) lang = lang === 'ko' ? 'en' : 'ko'; paint(); }, 700);

Perceived wait time is driven by **uncertainty**, not the clock (see perceived-performance). "Loading..." gives no sense of what's happening or how much is left, so 3 seconds and 30 feel equally anxious.

Specific loading copy names the target ("images") and shows progress ("2 of 5"), so users can estimate the end. Multiple studies back the same finding: just knowing what's happening shrinks the perceived wait.

The demo's ✕ repeats the same phrase forever; ✓ visibly updates as progress moves.

When to use

Show a concrete target and progress for anything over ~2 seconds. Under a second, a bare spinner is enough — copy would just add noise.