command과 commandfor는 버튼이 다른 요소를 제어하도록 HTML만으로 연결해 주는 새 속성입니다. 자바스크립트로 addEventListener를 붙여 팝오버를 열고 닫던 코드를, <button commandfor="menu" command="toggle-popover"> 한 줄로 대체합니다. 이른바 '인보커(invoker) 커맨드'라 부르는 기능이죠.
솔직히 처음 봤을 땐 '또 마크업 장난인가' 싶었는데, 써보니 다이얼로그·팝오버 여닫는 자잘한 JS가 통째로 사라지는 게 꽤 시원했습니다.
어떻게 생겼나
버튼에 두 속성을 붙입니다. commandfor는 제어할 대상의 id, command는 시킬 동작입니다.
<button commandfor="help" command="show-popover">도움말</button>
<div id="help" popover>
<p>여기가 도움말입니다.</p>
<button commandfor="help" command="hide-popover">닫기</button>
</div>
보다시피 스크립트가 한 줄도 없습니다. 버튼을 누르면 브라우저가 알아서 팝오버를 띄우고, 안쪽 닫기 버튼이 그걸 닫습니다. 접근성 배선(aria-expanded, 포커스 이동, Esc 처리)도 브라우저가 챙깁니다.
기본으로 제공되는 명령들
| command 값 | 대상 | 동작 |
|---|---|---|
show-popover / hide-popover / toggle-popover | popover 요소 | 팝오버 열기·닫기·토글 |
show-modal / close | <dialog> | 모달 열기·닫기 |
request-close | <dialog> | 취소 이벤트를 거쳐 닫기 |
다이얼로그를 예로 들면 이렇게 됩니다.
<button commandfor="dlg" command="show-modal">열기</button>
<dialog id="dlg">
<form method="dialog"><button>OK</button></form>
<button commandfor="dlg" command="close">X</button>
</dialog>
커스텀 명령도 만든다
내장 명령으로 부족하면 두 글자 이상에 하이픈이 든 이름(-- 접두)을 직접 정의할 수 있습니다. 이때는 대상 요소에서 command 이벤트가 발생하고, 거기에 리스너를 답니다.
<button commandfor="player" command="--play">재생</button>
<script>
document.getElementById('player')
.addEventListener('command', (e) => {
if (e.command === '--play') e.target.play();
});
</script>
여기서 이득이 있습니다. 이벤트가 대상 요소에서 나므로, 리스너를 버튼마다 다는 게 아니라 대상에 하나만 달면 됩니다. 버튼이 동적으로 늘어나도 배선이 안 깨져요.
지원 현황과 대비
2026년 기준 크로미엄 계열(Chrome·Edge)에서 먼저 들어왔고 나머지는 따라오는 중입니다. 그래서 아직은 점진적 향상으로 씁니다. 미지원 브라우저를 위해 기존 JS 폴백을 병행하거나, 최소한 버튼이 <button>이라 클릭은 되게 두세요.
핵심은 '접근 가능한 상호작용을 마크업에 담는다'는 방향입니다. Popover API·다이얼로그와 한 세트로 보면 이해가 빠릅니다.
자주 묻는 질문
onclick과 뭐가 다른가요?
onclick은 여러분이 열기·닫기·포커스·aria 상태를 직접 코딩해야 합니다. command는 그 표준 동작(모달 열기, 팝오버 토글, 포커스 트랩, Esc 닫기)을 브라우저가 대신 처리합니다. 접근성 실수를 줄여주는 게 가장 큰 차이입니다.
아무 요소나 command 대상이 되나요?
내장 명령은 대상이 정해져 있습니다. show-popover 계열은 popover 속성이 붙은 요소, show-modal/close는 <dialog>에만 유효합니다. 임의 요소를 제어하려면 --로 시작하는 커스텀 명령을 정의하고 command 이벤트를 받으세요.
버튼이 form 안에 있으면 폼이 제출되나요?
아니요. command/commandfor가 붙은 버튼은 자동으로 제출 기본동작을 갖지 않습니다. 굳이 type="button"을 명시하지 않아도 폼이 전송되는 사고는 나지 않습니다.

댓글 0