인터페이스 사운드

UI sound

버튼 클릭·토글·스와이프 같은 조작 하나하나에 붙는 짧은 소리. 손끝의 촉감을 귀로 확인시켜 줍니다.

다른 이름: Interaction soundFeedback soundClick sound
···
html
<div class="wrap">
  <div class="row">
    <span class="lbl">알림</span>
    <div class="sw" id="sw"><span class="knob"></span><span class="pulse" id="pulse"></span></div>
  </div>
  <button class="play" id="play" type="button" aria-label="play sound"><span class="tri"></span></button>
</div>
css
.wrap{position:relative;width:88%;height:82%;display:grid;place-items:center}
.row{display:flex;align-items:center;gap:12px;padding:14px 18px;border:1px solid var(--line);border-radius:14px;background:var(--surface)}
.lbl{font-size:13px;color:var(--fg)}
.sw{position:relative;width:44px;height:26px;border-radius:13px;background:var(--line);transition:background .18s}
.sw[data-on]{background:var(--accent-3)}
.knob{position:absolute;top:2px;left:2px;width:22px;height:22px;border-radius:50%;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.3);transition:left .18s ease}
.sw[data-on] .knob{left:20px}
.pulse{position:absolute;inset:-6px;border-radius:16px;border:1.5px solid var(--accent-3);opacity:0}
.pulse.go{animation:pulse .5s ease-out}
@keyframes pulse{0%{opacity:.7;transform:scale(.9)}100%{opacity:0;transform:scale(1.3)}}
@media (min-width:460px){
  .row{gap:22px;padding:26px 34px;border-radius:20px}
  .lbl{font-size:22px}
  .sw{width:84px;height:48px;border-radius:24px}
  .knob{width:40px;height:40px;top:4px;left:4px}
  .sw[data-on] .knob{left:40px}
  .pulse{inset:-10px;border-radius:26px}
}
.play{position:absolute;right:0;bottom:0;width:clamp(28px,15%,40px);aspect-ratio:1;border-radius:50%;border:1px solid var(--line);background:var(--surface);display:grid;place-items:center;cursor:pointer;box-shadow:0 2px 8px rgba(0,0,0,.12)}
.play .tri{width:0;height:0;border-style:solid;border-width:6px 0 6px 9px;border-color:transparent transparent transparent var(--fg);margin-left:2px}
.play:active{transform:scale(.92)}
js
const sw = document.getElementById('sw');
const pulse = document.getElementById('pulse');
let on = false;
function flip() {
  on = !on;
  sw.toggleAttribute('data-on', on);
  pulse.classList.remove('go');
  void pulse.offsetWidth;
  pulse.classList.add('go');
}
setInterval(flip, 1700);
document.getElementById('play').addEventListener('click', () => {
  flip();
  const ctx = new (window.AudioContext || window.webkitAudioContext)();
  const size = Math.floor(ctx.sampleRate * 0.03);
  const buf = ctx.createBuffer(1, size, ctx.sampleRate);
  const d = buf.getChannelData(0);
  for (let i = 0; i < size; i++) d[i] = (Math.random() * 2 - 1) * (1 - i / size);
  const src = ctx.createBufferSource();
  src.buffer = buf;
  const filter = ctx.createBiquadFilter();
  filter.type = 'highpass';
  filter.frequency.value = 2200;
  const gain = ctx.createGain();
  gain.gain.value = 0.14;
  src.connect(filter).connect(gain).connect(ctx.destination);
  src.start();
  src.onended = () => ctx.close();
});

인터페이스 사운드는 이어콘보다 좁은 개념으로, 상태 변화가 아니라 "지금 이 조작이 등록됐다"는 즉각적인 촉감을 대신하는 소리입니다. iOS 키보드 타건음, 카메라 셔터음, 토글 스위치의 "딸깍" 소리가 대표적입니다. 물리 버튼이 사라진 터치스크린 시대에 촉각의 빈자리를 청각으로 메우는 역할을 합니다.

조작음은 반응 속도가 생명이라 지연 없이(가능하면 50ms 이내) 재생돼야 하고, 음량은 아주 작게(피크 -20dB 안팎) 잡아 배경음처럼 스쳐 지나가야 합니다. 같은 화면에서 초당 여러 번 울릴 수 있는 조작(스크롤, 슬라이더 드래그)에는 아예 소리를 빼거나 아주 미세하게 줄이는 게 낫습니다 — 누적되면 소음이 됩니다. 무음 모드·저시력·청각장애 사용자를 위해 조작 성공 여부는 항상 시각적 변화(색·크기·위치)로도 확인 가능해야 합니다.

키보드 타건음, 스위치 On/Off, 삭제·완료 버튼, 카메라 셔터, 잠금 해제 소리 등 OS 레벨 인터랙션 전반에 쓰입니다.

언제 쓰나

탭·토글·스와이프처럼 사용자가 직접 만지는 원자적 조작에. 연속 제스처(드래그·스크롤)에는 쓰지 않거나 아주 작게.