라디오 버튼 스타일 가이드
CSS로 HTML의 라디오 버튼을 색상이나 크기, 모양 등 원하는 디자인으로 스타일하는 방법에 대해 알아보겠습니다.
CSS를 적용하면 나만의 스타일이 적용된 라디오 버튼을 디자인할 수 있습니다.
HTML의 라디오 버튼에 CSS 적용 시 고려할 점
HTML의 라디오 버튼은 <input type="radio">
로 표현됩니다.
<p>체크되어 있지 않은 라디오 버튼</p>
<input type="radio">
<hr>
<p>체크되어 있는 라디오 버튼</p>
<input type="radio" checked>
checked
는 라디오 버튼이 기본적으로 체크되어 있는지 여부를 나타내는 속성입니다. 페이지가 처음 로드될 때 라디어 버튼이 체크된 상태로 시작하려면 checked
속성을 사용합니다.
체크되어 있지 않은 라디오 버튼
체크되어 있는 라디오 버튼
브라우저에서 실제 표시된 모습의 라디오 버튼은 일반적으로 작은 원으로 렌더링되며, 선택 시 채워지거나 강조 표시됩니다.
브라우저에서 제공하는 기본 모양의 스타일 지정 한계점
지금 보고 있는 HTML의 라디오 버튼은 각 브라우저에서 제공하는 기본 모양이 있습니다.
이 기본 모양을 '네이티브 모양(native appearance)'이라고 합니다. 네이티브 모양은 브라우저마다 약간씩 다른 스타일로 제공하며, 라디오 버튼이 체크되어 있는 상태처럼 CSS만으로는 완벽히 호환되어 표현할 수 없는 것도 있습니다.

"크롬 브라우저에서 표현되는 라디오 버튼 캡쳐화면"을 기준으로 살펴보겠습니다. 라디오 버튼의 둥근 테두리나 채워져 있는 둥근 원형의 색상을 파란색에서 빨간색으로 바꾸려고 CSS의 border-color: red;
와 background-color: red;
를 적용하더라도 바뀌지 않습니다.
[type="radio"] {
border-color: red;
background-color: red;
}
이와 같은 현상은 비단 "크롬 브라우저" 이외에도 "Safari 브라우저", 그 밖의 다른 브라우저에서도 마찬가지입니다.
이러한 현상이 생기는 이유는 HTML의 라디오 버튼은 각 브라우저에서 제공하는 기본 모양이 있기 때문이며, 기본 모양을 일반적인 CSS 속성으로 제어할 때 일부 속성만을 사용할 수 있기 때문입니다.
width
와 height
스타일 속성으로 크기를 지정할 수 있음
HTML의 라디오 버튼은 브라우저에서 제공하는 기본 모양 중에서 기본적으로 동일한 값의 width
와 height
속성으로 크기를 바꿀 수 있습니다.
[type="radio"] {
width: 50px;
height: 50px;
}
체크되어 있지 않은 라디오 버튼
체크되어 있는 라디오 버튼
accent-color
스타일 속성으로 강조되는 색상을 지정할 수 있음
HTML의 라디오 버튼은 브라우저에서 제공하는 기본 모양 중에서 accent-color
스타일 속성으로 '강조되는 색상'을 지정할 수 있습니다.
라디오 버튼에서 '강조되는 색상'이란 라디오 버튼이 체크된 상태일 때의 색상을 말합니다.
그렇다면, HTML의 라디오 버튼은 브라우저에서 제공하는 기본 모양(네이티브 모양, native appearance) 중에서 크기만을 커스텀으로 변경할 수 있다고는 생각하지 마세요. 라디오 버튼을 커스텀 스타일링하는 방법에 대해 알아보겠습니니다.
[type="radio"] {
width: 50px;
height: 50px;
accent-color: red;
}
체크되어 있지 않은 라디오 버튼
체크되어 있는 라디오 버튼
그렇다고 HTML의 라디오 버튼은 브라우저에서 제공하는 기본 모양(네이티브 모양, native appearance) 중에서 크기와 강조되는 색상만을 커스텀으로 변경할 수 있다고는 생각하지 마세요. 라디오 버튼을 CSS로 커스텀 스타일링하는 방법에 대해 알아보겠습니니다.
라디오 버튼을 커스텀 스타일링하는 방법
라디오 버튼을 CSS로 커스텀 스타일링하는 방법이 있습니다. 다음의 두 가지 방법입니다.
appearance: none;
속성으로 네이티브 모양을 제어하는 방법- HTML의 라디오 버튼을 화면에서 숨기고 대체 스타일 요소를 사용하는 방법
appearance: none;
속성으로 네이티브 모양을 제어하는 방법
라디오 버튼에 appearance: none;
으로 지정하면
기본 모양을 제공하고 있는 요소는 본래의 모양이 제거합니다. 대신 일반적인 CSS 규칙에 따라 렌더링됩니다. appearance
속성에 대한 자세한 설명은 CSS appearance 속성 - 브라우저에서 제공하는 기본 UI 요소 모양을 제어를 참고하세요.
다음은 라디오 버튼에 appearance: none
을 사용해서 사용자 정의 스타일하는 간단한 예제입니다.
<input type="radio" name="radio-test"> <!--체크되지 않은 라디오 버튼 -->
<input type="radio" name="radio-test" checked> <!--체크되어 있는 상태의 라디오 버튼 -->
[type="radio"] {
appearance: none; /* 기본(네이티브) 모양을 제거 */
border-radius: 50%;
box-sizing: border-box;
width: 20px;
height: 20px;
border: 1px solid gray;
cursor: pointer;
}
[type="radio"]:checked {
border: 6px solid yellowgreen;
}
[type="radio"]:checked
는 CSS :checked 가상 클래스 선택자 사용 방법을 참고하세요!
HTML의 라디오 버튼을 화면에서 숨기고 대체 스타일 요소를 사용하는 방법
appearance: none;
속성을 사용해서 본래의 모양이 제거하더라도 HTML의 라디오 버튼 요소 하나에 스타일링하는 것은 디자인적인면에서 한계가 분명 있습니다.
HTML의 라디오 버튼인 <input type="radio">
는 하위 콘텐츠를 가질 수 없는 빈 요소(Void element)입니다.
하위 콘텐츠를 가질 수 없는 빈 요소(Void element)는 CSS의 가상 요소 선택자인 ::before
나 ::after
를 사용할 수 없다는 한계점도 있습니다.
이러한 한계를 고려할 때 HTML의 라디오 버튼을 화면에서 숨기고 대체 스타일 요소를 사용할 수 있습니다.
웹 접근성 주의!
HTML의 라디오 버튼을 화면에서 숨기더라도 웹 접근성을 반드시 고려해야 합니다.
요소를 숨길 때 CSS의 display: none
이나 visibility: hidden
등의 스타일 속성이나 요소에 HTML hidden
속성을 사용할 경우에는 스크린 리더를 사용하는 시각 장애인은 해당 요소에 접근할 수 없습니다.
다음은 HTML의 라디오 버튼을 화면에서 숨기고 대체 스타일 요소를 사용해서 스타일하는 간단한 예제입니다.
<div class="control-container">
<input type="radio" checked name="favorite" id="html" class="screen-reader">
<div class="label-box">
<span class="check-icon" aria-hidden="true"></span>
<label for="html">HTML</label>
</div>
</div>
<div class="control-container">
<input type="radio" name="favorite" id="css" class="screen-reader">
<div class="label-box">
<span class="check-icon" aria-hidden="true"></span>
<label for="css">CSS</label>
</div>
</div>
aria-hidden="true"
는 스크린 리더 및 보조 기술을 사용하는 것으로, aria-hidden
속성의 값이 true
로 설정되면 해당 요소와 그 안에 포함된 콘텐츠는 접근성 기술을 통해 감지되지 않습니다.
.control-container {
display: flex;
position: relative;
}
.control-container + .control-container {
margin-top: 0.7em;
}
.screen-reader { /* 스크린 리더를 고려해서 라디오 버튼을 화면에서 숨김 */
position: absolute;
width: 1px;
height: 1px;
padding: 0;
border: 0;
overflow: hidden;
margin: -1px;
clip-path: inset(50%);
}
.label-box {
position: relative;
}
.check-icon {
width: 1.4em;
height: 1.4em;
border-radius: 50%;
background-color: #fff;
border: 1px solid gray;
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
}
.check-icon::before {
content: "";
position: absolute;
box-sizing: border-box;
width: 30%;
height: 55%;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-70%) rotateZ(40deg);
border-right: 1.7px solid gray;
border-bottom: 1.7px solid gray;
}
label {
padding-left: 2.2em;
position: relative;
cursor: pointer;
}
[type="radio"]:checked + .label-box .check-icon {
border-color: yellowgreen;
background-color: yellowgreen;
}
[type="radio"]:checked + .label-box .check-icon::before {
border-color: #fff;
}
[type="radio"]:checked + .label-box label {
color: yellowgreen;
}