<input type=radio>
Custom강의를 보다가 radio 버튼을 커스텀해보라는 것이 미션이었는데, 꽤나 애먹었다.
도저히 감이 잡히지가 않았었다..
감이 잡히지 않을만도 했었던 것이, 처음보는 css 접근자로 커스텀이 가능했던 것이었다.
이 방법은 웹 접근성까지 고려하여 커스텀 할 수 있기 때문에 앞으로 ui작업하는 데 매우 유용할 것 같다.
1. html 구조
<TestRadioCustomWrap> {/* styled-components */}
<div className="wrap">
<label htmlFor="email_radio">이메일</label>
<input
value="email"
name="contact"
type="radio"
id="email_radio"
defaultChecked
/>
</div>
<div className="wrap">
<label htmlFor="phone_radio">전화</label>
<input value="phone" name="contact" type="radio" id="phone_radio" />
</div>
<div className="wrap">
<label htmlFor="fax_radio">팩스</label>
<input
value="fax"
name="contact"
type="radio"
id="fax_radio"
disabled
/>
</div>
<div className="wrap">
<label htmlFor="mail_radio">우편</label>
<input value="mail" name="contact" type="radio" id="mail_radio" />
</div>
</TestRadioCustomWrap>
2. css 구조
const TestRadioCustomWrap = styled.fieldset`
display: flex;
.wrap {
display: flex;
align-items: center;
margin-right: 12px;
}
label {
font-size: 20px;
line-height: 2rem;
padding: 0 4px;
}
label:hover {
cursor: pointer;
}
[type="radio"] {
appearance: none;
border: 1px solid gray;
border-radius: 50%;
width: 1.25rem;
height: 1.25rem;
/* transition: outline 0.5s ease-in-out; */
}
[type="radio"]:checked {
/* border: 4px solid #ffa520; */
background: #ffa520;
/* outline 속성은 요소 주위에 테두리 형태의 외곽선을 추가하는 데 사용된다. */
outline: 2px solid #fff;
outline-offset: -4px;
}
/* 키보드로 포커스를 변경했을 때 보여지는 css. 클릭했을 때는 보이지 않는다. */
[type="radio"]:focus-visible {
outline: 2px dotted tomato;
outline-offset: 2px;
}
/* 라디오버튼에 커서를 가져다 대었을 때 css */
[type="radio"]:hover {
box-shadow: 0 0 0 4px yellowgreen;
cursor: pointer;
}
/* 선택할 수 없는 라디오 버튼의 css */
[type="radio"]:disabled {
background: lightgray;
box-shadow: none;
cursor: not-allowed;
opacity: 0.5;
}
`;
결과
appearance: none;
과 display: none;
의 차이1️⃣ appearance: none;
appearance
속성은 웹 브라우저가 기본적으로 제공하는 스타일을 재정의하는데 사용한다.form 요소 그 중 input
등 기타 브라우저가 기본적으로 스타일을 적용하는 요소에 사용한다. appearance
속성은 기본적으로 브라우저가 적용하ㅏ는 버튼 스타일을 제거하고 커스텀 할 때 사용된다./* 기본적으로 브라우저가 적용하는 스타일 제거 */
button, input[type="radio"] {
appearance: none;
}
2️⃣. display: none;
display
속성은 요소를 화면에 보이지 않도록 하는 데 사용한다.display: none;
를 적용한 요소는 개발자 도구에서 보면 요소 자체가 사라져있음을 확인할 수 있다.Key Point
1.[type="radio"]...
가상 선택자로 input을 커스텀 할 수 있다.
2.appearance : none;
은display : none;
보다 웹 접근성을 고려한 css 속성이다.
appearance: none;
은 브라우저가 적용하는 기본적인 스타일을 재정의하고,display: none;
은 요소를 화면에서 완전히 제거하여 숨기는 데 사용한다.
css 선택자에서
[type="radio"]
와input[type="radio"]
는 동등한 선택자인가요?
[type="radio"]
와input[type="radio"]
는 동등한 선택자입니다. 둘 다 HTML에서<input>
요소 중에서 type 속성 값이 "radio"인 요소를 선택합니다.
HTML 요소를 선택할 때, 요소의 이름만으로도 선택할 수 있지만, 특정 속성 값에 기반하여 선택할 수도 있습니다.[type="radio"]
는 type 속성이"radio"
인 모든 요소를 선택하고,input[type="radio"]
는<input>
요소 중에서 type 속성이"radio"
인 요소를 선택합니다.
라디오 버튼은 name
속성이 같은 경우 그룹으로 간주되어, 그룹 내에서는 하나의 버튼만 선택될 수 있습니다.
<div className="wrap">
<label htmlFor="email_radio">이메일</label>
<input
value="email"
name="contact" ✅
type="radio"
id="email_radio"
defaultChecked
/>
</div>
<div className="wrap">
<label htmlFor="phone_radio">전화</label>
<input value="phone" name="contact" ✅ type="radio" id="phone_radio" />
</div>
<div className="wrap">
<label htmlFor="fax_radio">팩스</label>
<input
value="fax"
name="contact" ✅
type="radio"
id="fax_radio"
disabled
/>
</div>
<div className="wrap">
<label htmlFor="mail_radio">우편</label>
<input value="mail" name="contact" ✅ type="radio" id="mail_radio" />
</div>
name = contact
인 그룹으로 간주되므로 해당 라디오 버튼은 중복체크가 되지 않음.
라디오 버튼인데 중복체크가 된다면, input
의 name
속성을 확인해볼 것.