HOWTO · HTML

HTML 버튼을 링크처럼 작동하게 만드는 방법

HTML에서 버튼 모양의 앵커, JavaScript 버튼, 폼 제출 컨트롤을 언제 사용하는지 알아봅니다.

이 페이지의 내용

HTML 컨트롤로 URL을 여는 방법은 원하는 결과에 따라 달라집니다. 페이지를 이동하려면 href가 있는 <a>를 사용하고 CSS로 버튼처럼 보이게 만드세요. 동작을 실행하려면 <button>, 폼 데이터를 전송하려면 제출 컨트롤을 사용합니다. <button>이나 <input><a> 안에 넣지 마세요. 모두 대화형 요소이므로 의미와 키보드 동작이 충돌합니다.

결과에 따라 앵커와 버튼을 선택하기

주소를 바꾸거나 문서와 파일을 열고 다른 페이지로 이동하는 경우에는 앵커가 알맞습니다. href에 실제 목적지가 있으면 사용자가 새 탭으로 열거나 주소를 복사하고 북마크하거나 키보드로 접근할 수 있습니다.

현재 페이지를 바꾸거나 대화 상자와 패널을 열거나 스크립트를 실행하는 경우에는 <button type="button">을 사용합니다. 직사각형 모양이라고 해서 button이 링크가 되는 것은 아닙니다. 요소의 역할은 실제 동작과 일치해야 합니다.

탐색을 위해 <a>를 버튼처럼 꾸미기

단순히 페이지를 이동하는 컨트롤이라면 이 방법을 권장합니다. 목적지는 href에 두고 의미 있는 링크 텍스트와 눈에 보이는 포커스 스타일을 제공하세요. /docs/를 실제 주소로 바꾸면 됩니다.

<a class="button-link" href="/docs/">Open the documentation</a>
.button-link {
  display: inline-block;
  padding: 0.65rem 1rem;
  border-radius: 0.35rem;
  background: #1769aa;
  color: #fff;
  text-decoration: none;
}

.button-link:hover {
  background: #0d4f80;
}

.button-link:focus-visible {
  outline: 3px solid #f5b700;
  outline-offset: 2px;
}

결과는 버튼처럼 보이지만 링크로 남습니다. 새 탭에서 열리는 경우에는 텍스트에도 표시하세요.

<a href="https://example.com/docs" target="_blank" rel="noopener">
  Open the documentation (new tab)
</a>

버튼을 흉내 내려고 href="#" 또는 href="javascript:void(0)"를 사용하지 마세요. 실제 목적지가 아니며 스크롤과 북마크에서 예상하지 못한 동작이 생길 수 있습니다. href는 상대 경로, 절대 HTTPS URL, 프래그먼트 등이 될 수 있습니다. CSS는 모양만 바꾸므로 링크의 기본 브라우저 기능은 유지됩니다.

실제 버튼 동작일 때만 <button>과 JavaScript 사용하기

이동 전에 상태를 확인하거나 다른 작업을 해야 한다면 button을 유지할 수 있습니다. 타입을 명시하고 addEventListener로 리스너를 등록하세요. window.location.assign()이 이동을 수행합니다.

<button type="button" id="docs-button">Open the documentation</button>

<script>
  document.querySelector("#docs-button").addEventListener("click", () => {
    window.location.assign("https://example.com/docs");
  });
</script>

이 예제는 포인터, Enter, Space로 활성화되지만 JavaScript가 필요합니다. 단순한 탐색에는 JavaScript가 꺼져도 사용할 수 있는 앵커를 선택하세요. 큰 애플리케이션에서는 인라인 onclick 대신 모듈에서 리스너를 등록합니다. 비어 있거나 잘못된 목적지는 경계 조건이므로 assign() 전에 동적 값을 검증하세요.

데이터를 전송할 때는 폼 사용하기

서버로 필드를 보낼 때는 폼의 action에 목적지를 지정하고 제출 컨트롤을 사용합니다. 이는 일반 링크 탐색이 아니라 폼 제출입니다.

<form action="/search" method="get">
  <label for="query">Search</label>
  <input id="query" name="q" type="search">
  <button type="submit">Search</button>
</form>

CSS button을 제출하면 폼 인코딩에 따라 /search?q=CSS+button 같은 요청이 됩니다. 모양만을 위해 빈 폼을 사용하지 마세요. 특정 type="submit" 버튼에 다른 목적지를 주려면 formaction을 사용할 수 있습니다.

기존 프로젝트가 value 기반 표현을 요구한다면 <input type="submit">도 유효합니다.

<form action="/docs/" method="get">
  <input type="submit" value="Open the documentation">
</form>

value가 표시 라벨이 됩니다. 이 input을 앵커로 감싸지 마세요. <input type="button">은 단독으로 제출하거나 이동하지 않으므로 스크립트가 필요합니다.

링크를 열지 않는 버튼 문제 해결하기

  • 이동이 목적이면 CSS로 버튼처럼 보여도 마크업은 <a href="...">여야 합니다.
  • 폼에서 제출하지 않는 동작에는 type="button"을 지정하세요. 타입을 생략하면 submit이 되어 페이지를 다시 로드할 수 있습니다.
  • JavaScript button이 작동하지 않으면 콘솔, 선택자, 스크립트 로드를 확인하세요. JavaScript가 꺼져 있으면 handler는 실행되지 않습니다.
  • 키보드 사용자가 포커스를 알 수 있도록 :focus-visible을 유지하세요.
  • 일반 링크에 중첩된 <button>이나 <input>을 사용하지 마세요.

정리하면 탐색에는 <a href="...">, 동작에는 <button type="button">, 데이터 전송에는 폼 안의 submit button을 사용합니다. 이렇게 구분하면 브라우저와 보조 기술이 예측 가능한 의미를 얻습니다.