Menu

HTML 버튼 링크: 다른 페이지로 이동하는 버튼 만들기

다른 페이지로 이동하는 버튼은 버튼처럼 꾸민 링크로 만드는 게 맞아요. 링크 안의 버튼과 onclick 이동이 왜 문제인지, 폼 버튼이 맞는 경우는 언제인지, 링크 버튼을 꾸미고 비활성화하는 법을 알아봐요.

이 페이지에는 실행 가능한 에디터가 있습니다 - 편집하고 실행하면 결과를 바로 볼 수 있습니다.

다른 페이지로 이동하는 버튼 만드는 법

일반 링크 <a href>를 쓰고 CSS로 버튼처럼 보이게 꾸미세요. 여느 링크처럼 페이지로 이동하고, 새 탭에서 열기, 링크 주소 복사, 마우스를 올렸을 때 URL 미리보기 같은 링크 기능도 모두 유지돼요.

링크를 버튼으로 바꾸는 규칙은 이래요.

  • display: inline-block은 padding이 상자를 넓히게 하면서도 텍스트 줄 안에 머물게 해요.
  • text-decoration: none은 밑줄을 없애요.
  • color와 background가 파란 링크 색을 대신해요.
  • :focus-visible은 키보드 사용자에게 분명한 포커스 링을 보여 줘요.

같은 클래스를 <button>에도 쓸 수 있어서, 폼의 제출 버튼과 다른 페이지로 가는 링크를 똑같이 보이게 하면서 각자 제 역할을 하게 할 수 있어요.

버튼일까, 링크일까

중요한 건 어떻게 보이느냐가 아니라 클릭했을 때 무슨 일이 일어나느냐예요.

클릭하면쓸 요소예
다른 URL로 이동<a href>회원가입, 더 보기, 요금제 보기, 다운로드
이 페이지의 무언가를 바꿈<button type="button">메뉴 열기, 재생, 장바구니 담기, 비밀번호 보기
폼을 보냄<button type="submit">로그인, 검색, 저장

"링크"라고 알려 주는 링크와 "버튼"이라고 알려 주는 버튼은 스크린 리더 사용자에게 무슨 일이 일어날지 말해 줘요. 키보드 동작도 달라요. Enter는 둘 다 실행하지만 Space는 버튼만 실행해요(링크에서 Space를 누르면 페이지가 스크롤돼요). button 요소 자체는 HTML button 태그에서 다뤄요.

링크 안에 버튼을 넣으면 안 되는 이유

대부분의 사람이 처음 시도하는 패턴이에요.

<!-- Invalid: interactive content inside <a> -->
<a href="/signup"><button>Sign up</button></a>

<!-- Invalid the other way round, too -->
<button><a href="/signup">Sign up</a></button>

HTML 표준은 둘 다 금지해요. <a>와 <button>은 인터랙티브 요소를 담을 수 없어요. 실제로는 컨트롤 하나에 키보드 탭 정지가 두 번 생기고, 스크린 리더가 "링크, 버튼, Sign up"처럼 알려 줄 수 있고, 클릭했을 때 링크로 이동할지는 브라우저에 따라 달라요. 요소 하나만 고르세요.

onclick과 location.href를 쓰면 안 되는 이유

또 다른 흔한 우회법은 JavaScript로 URL을 설정하는 버튼이에요. 링크와 똑같아 보여요.

(미리보기가 다른 곳으로 이동하면 안 되기 때문에 예제에서는 window.open을 썼어요. 보통 코드는 location.href = '...'예요.) 두 요소에 마우스를 올리고 오른쪽 클릭을 해 보세요. 진짜 링크만 URL을 보여 주고 "새 탭에서 링크 열기"와 "링크 주소 복사"를 제공해요. 버튼은 Ctrl+클릭이나 가운데 클릭도 안 되고, 브라우저가 방문한 링크로 표시하지도 않고, 검색 엔진도 링크로 따라가지 않아요. 목적지가 URL이라면 <a href>를 쓰세요.

URL을 여는 폼 버튼

다른 페이지로 가는 <button>이 맞는 경우가 하나 있어요. 데이터를 함께 보낼 때예요. 검색창이 대표적인 예예요. 폼의 action이 URL이고, method="get"이 입력값을 쿼리 문자열에 넣어요.

Search를 눌러 보세요. 실제 페이지라면 브라우저가 https://duckduckgo.com/?q=html+button+link로 이동해요. 미리보기는 페이지를 떠나지 않고 대신 데이터를 보여 줘요. formaction은 두 번째 버튼에서 같은 폼을 다른 URL로 보내요.

비활성화된 링크 버튼

링크에는 disabled 속성이 없어서 <a disabled>는 아무 효과가 없어요. 링크 버튼을 끄려면 href를 지우고(href 없는 <a>는 링크가 아니라서 클릭도 포커스도 안 돼요), 스타일과 스크린 리더 모두 알 수 있도록 aria-disabled="true"로 표시하세요.

미리보기에서 Tab을 눌러 보세요. 포커스는 첫 번째 버튼에만 가요. 어떤 사이트는 href를 그대로 두고 대신 pointer-events: none을 주는데, 이건 마우스만 막아요. 링크는 여전히 Tab으로 갈 수 있고 Enter를 누르면 이동해요.

새 탭 버튼과 다운로드 버튼

버튼처럼 꾸민 링크에서도 링크 속성은 모두 동작해요.

<a class="btn" href="/files/guide.pdf" download>Download the guide</a>
<a class="btn" href="https://github.com/" target="_blank" rel="noopener">GitHub</a>

이것도 <a>를 쓰는 이유예요. <button>에는 download나 target이 없어요. target은 새 탭에서 링크 열기에서 더 다뤄요.

자주 하는 실수

  • 링크 안의 버튼, 또는 버튼 안의 링크. 동작을 예측할 수 없는 올바르지 않은 HTML이에요.
  • 단순 이동에 <button onclick="location.href=...">를 씀. 새 탭도, 링크 복사도, 크롤링도 안 돼요.
  • 이동하는 링크에 role="button"을 줌. 스크린 리더 사용자에게 버튼이 있다고 알려 놓고 페이지가 바뀌어요. 링크로 두세요.
  • "삭제"나 "메뉴 열기" 같은 동작에 href="#"인 버튼 모양 링크를 씀. 아무것도 불러오지 않는다면 <button type="button">을 쓰세요.
  • <a disabled>. 링크에는 이 속성이 없어요. href를 지우세요.
  • display: inline-block을 빼먹음. 위아래 padding이 위아래 줄과 겹쳐요.

자주 묻는 질문

HTML에서 다른 페이지로 이동하는 버튼은 어떻게 만드나요?

링크를 쓰고 버튼처럼 꾸미세요. <a href="/signup" class="btn">Sign up</a>에 padding, 배경, 모서리 둥글기, text-decoration: none을 CSS로 주면 돼요. 버튼처럼 보이고 링크처럼 동작하는데, 실제로 링크이니까요.

a 태그 안에 button을 넣어도 되나요?

안 돼요. HTML 표준은 <a> 안에 <button> 같은 인터랙티브 콘텐츠를 허용하지 않아요. 브라우저마다 처리가 다르고, 키보드 사용자에게는 컨트롤 하나에 탭 정지가 두 번 생기고, 스크린 리더는 헷갈리게 알려 줘요. 요소 하나만 쓰세요.

button에 href 속성이 있나요?

없어요. <button>에는 href가 없어요. 브라우저를 URL로 보내려면 <a href>를 쓰거나, 버튼을 action이 있는 <form>에 넣으세요(버튼의 formaction 속성이 그 값을 덮어써요).

버튼에 onclick과 location.href를 쓰면 안 좋은가요?

동작은 하지만, 링크가 주는 것을 독자가 모두 잃어요. 가운데 클릭과 Ctrl+클릭으로 새 탭 열기, 링크 주소 복사, 마우스를 올렸을 때 URL 미리보기가 없고, 검색 엔진도 링크로 따라가지 않아요. 목적지가 URL이라면 <a>를 쓰세요.

버튼처럼 보이는 링크는 어떻게 비활성화하나요?

링크에는 disabled 속성이 없어요. href를 지워서 링크가 아니게 만들고, aria-disabled="true"를 추가하고, 비활성화된 모양으로 꾸미세요. 다시 동작해야 할 때 href를 되돌려 놓으면 돼요.

Coddy programming languages illustration

Coddy로 코딩 배우기

시작하기