코딩하는 김딸기
폼 관련 가상 클래스/ 체크박스와 라디오버튼 커스텀 본문
폼 관련 가상 클래스
폼과 관련된 가상 클래스는 사용자가 폼을 상호작용하는 동안 다양한 상태에 따른 스타일을 적용하는데 활용되어 웹 접근성 / 사용자 경험 향상에 도움을 줍니다.
- :focus
- :focus-within
- :focus-visible
- :checked
- :disabled
- :valid
- :invalid
- :required
focus
:focus 가상 클래스는 사용자가 입력 요소를 클릭하거나 키보드로 선택하여 포커스를 받았을 때 적용됩니다. 이 상태는 사용자가 입력을 시작할 준비가 되었음을 의미합니다.
:focus-within
:focus-within 가상 클래스는 해당 요소 또는 자식 요소 중 하나가 포커스를 받을 때 적용됩니다. 주로 폼 컨테이너나 그룹에 사용됩니다.
:focus-visible
:focus-visible 가상 클래스는 키보드로 포커스를 이동할 때만 스타일이 적용됩니다. 마우스로 포커스를 이동할 때는 스타일이 적용되지 않습니다.
:checked
:checked 가상 클래스는 체크박스(input[type="checkbox"])나 라디오 버튼(input[type="radio"])이 선택된 상태일 때 적용됩니다.
input[type="checkbox"]:checked {
background-color: #009688;
border-color: #004d40;
}
input[type="radio"]:checked {
border: 2px solid #00796b;
}
<input type="checkbox" id="subscribe" name="subscribe">
<label for="subscribe">Subscribe to newsletter</label>
<input type="radio" id="male" name="gender" value="male">
<label for="male">Male</label>
예제)

- aspect-ratio: 1 / 1;: 요소의 너비와 높이 비율을 1:1로 설정합니다. 즉, 이 요소는 정사각형이 됩니다.
- border-radius: 50%;: 요소의 모서리를 둥글게 만들어 원형으로 만듭니다.
- background-color: #caf0ff;: 요소의 배경색을 밝은 하늘색(hex 코드: #caf0ff)으로 설정합니다.
- display: block;: span 요소는 기본적으로 인라인 요소지만, block으로 설정하여 블록 레벨 요소로 만듭니다. 이는 요소가 줄바꿈되고, 너비와 높이를 가질 수 있게 합니다.
- overflow: hidden;: 자식 요소가 부모 요소의 크기를 벗어날 경우, 그 초과 부분을 숨깁니다.
- input:checked: input 요소가 선택된 상태를 의미합니다.
- + .choice-item-icon img: 선택된 input 요소의 바로 다음에 나오는 형제 .choice-item-icon 요소 안의 img 요소를 선택합니다.
- transform: scale(0.8) translateY(0px) rotate(30deg);: 이미지에 변환 효과를 적용합니다.
- scale(0.8): 이미지를 원래 크기의 80%로 축소합니다.
- translateY(0px): Y축을 기준으로 이미지의 위치를 이동하지 않습니다.
- rotate(30deg): 이미지를 시계 방향으로 30도 회전시킵니다.
- transition: all .4s;: 모든 CSS 속성이 0.4초 동안 부드럽게 전환되도록 설정합니다. 이는 이미지가 변환될 때 애니메이션 효과가 적용되도록 합니다.
- transform: scale(0.5) translateY(300px);: 이미지에 기본 변환 효과를 적용합니다.
- scale(0.5): 이미지를 원래 크기의 50%로 축소합니다.
- translateY(300px): Y축을 기준으로 이미지 위치를 아래로 300픽셀 이동시킵니다.
- <label class="choice-item">: label 태그는 사용자 인터페이스에서 특정 입력 요소(input)와 연결됩니다. 여기서 class="choice-item"은 CSS 스타일링을 적용하기 위해 사용된 클래스입니다.
- <input type="radio" name="favorite">: radio 타입의 입력 요소로, 그룹 내에서 하나의 옵션만 선택할 수 있습니다. name="favorite"은 여러 라디오 버튼을 그룹화하는 역할을 합니다.
- <span class="choice-item-icon">: span 태그는 인라인 요소이며, class="choice-item-icon"은 CSS 스타일링을 적용하기 위한 클래스입니다.
- <img src="images/cat.png">: img 태그는 이미지를 표시하기 위한 태그입니다. 여기서는 images/cat.png 경로에 있는 이미지를 불러옵니다.
- 이전 코드(+ 인접 형제 콤비네이터)와의 차이점:
- + 인접 형제 콤비네이터는 선택자가 특정 요소의 바로 다음에 나오는 형제 요소를 선택할 때 사용됩니다. 즉, input:checked 상태가 되면, 바로 다음에 나오는 .choice-item-icon 내의 img 요소에 스타일이 적용됩니다.
- 반면, :has() 가상 클래스는 부모 요소 내에서 자식 요소를 기준으로 부모를 선택할 수 있게 해줍니다. 이 경우, input:checked 상태의 input을 포함한 .choice-item 내의 모든 img 요소에 스타일을 적용할 수 있습니다.=>마크업구성에 종속되지 않고 부모 기준으로 실행 가능
요약
이 코드의 목적은 input이 선택된 상태에서 그 input을 포함하는 .choice-item 요소 내의 img 태그에 특정 변환 효과를 적용하는 것입니다. 이를 통해 특정 요소가 선택되었을 때 발생하는 애니메이션이나 변환 효과를 좀 더 유연하게 구현할 수 있습니다.
:disabled
:disabled 가상 클래스는 비활성화된(disabled 속성을 가진) 폼 요소에 적용됩니다. 비활성화된 폼 상태의 스타일링을 하여 사용자가 비활성 상태를 인지할 수 있도록 합니다.
:valid & :invalid
:valid 가상 클래스는 입력된 값이 폼 필드의 유효성 검사 규칙을 통과했을 때 적용됩니다. 반대로, :invalid 가상 클래스는 유효성 검사를 통과하지 못했을 때 적용됩니다.
<form>
<label for="email">Email:</label>
<input type="email" id="email" required>
<label for="username">Username:</label>
<input type="text" id="username" pattern="[A-Za-z]{3,}" required>
<input type="submit" value="Submit">
</form>
사용자가 올바른 이메일 주소를 입력하면 입력 필드에 녹색 테두리가 적용됩니다. 반대로, 이메일 형식이 잘못되었거나 pattern 규칙에 맞지 않으면 빨간색 테두리가 표시됩니다.
:required
:required 가상 클래스는 required 속성이 적용된 필수 입력 필드에 적용됩니다. 사용자가 필드를 채우지 않은 상태에서 제출하려고 할 때 유효성 검사가 진행됩니다.

- 첫 번째 <div>: 회의실 크기를 선택하는 라디오 버튼 그룹을 나타냅니다. 같은 name="size"를 가진 라디오 버튼은 동일한 데이터 그룹을 의미하며, 한 번에 하나만 선택할 수 있습니다.
- "2-8인", "9-20인", "21-100인"의 세 가지 선택지가 제공됩니다.
- 두 번째 <div>: 필요한 장비를 선택하는 체크박스 그룹을 나타냅니다. 체크박스는 다중 선택이 가능하며, 사용자가 "빔프로젝터", "화이트보드", "전등데스크" 중 하나 이상을 선택할 수 있습니다.
- 기본적으로 "빔프로젝터"는 선택된 상태입니다 (checked 속성).
- .choice 클래스: 라디오 버튼과 체크박스가 인라인 블록으로 표시되도록 설정됩니다. 즉, 라벨이 가로로 나란히 배치됩니다.
- .choice::before:
- 각 선택지 앞에 기본적으로 '⬜' (빈 사각형)을 표시합니다. 이 가상 요소는 선택지를 시각적으로 표시하는 역할을 합니다.
- .choice:has(:checked)::before:
- :has(:checked)는 라디오 버튼이나 체크박스가 선택된 상태일 때 그 부모 .choice 요소를 선택합니다.
- 선택된 경우 ::before 가상 요소의 내용이 '✅' (체크된 상태)로 바뀌어 시각적으로 선택되었음을 나타냅니다.
요약
- 이 코드는 라디오 버튼과 체크박스를 사용해 회의실 크기와 필요한 장비를 선택하는 폼을 구성합니다.
- 선택지 앞에 기본적으로 빈 사각형(⬜)이 표시되고, 선택되면 체크 표시(✅)로 바뀝니다.
- .choice 클래스와 :has() 가상 클래스, ::before 가상 요소를 활용해 선택 상태를 시각적으로 표현합니다.

- input[type="radio"], input[type="checkbox"]:
- pointer-events: none;: 라디오 버튼과 체크박스가 사용자와의 상호작용을 차단합니다. 즉, 클릭 등의 마우스 이벤트가 발생하지 않습니다.
- position: absolute;: 버튼들이 절대 위치로 배치되어 문서 흐름에서 제거되고, 화면에 보이지 않게 됩니다.
- .choice:
- display: inline-flex;: 선택지들이 인라인으로 나란히 배치되며, flex 레이아웃을 사용하여 배치됩니다.
- gap: 10px;: 각 선택지 간에 10픽셀의 간격을 둡니다.
- .choice::before:
- content: ' ';: 가상 요소를 생성합니다.
- width: 24px; height: 24px;: 가상 요소의 크기를 24x24 픽셀로 설정합니다.
- border: 2px solid #ddd; border-radius: 4px;: 가상 요소에 회색 테두리를 두르고, 모서리를 둥글게 만듭니다.
- background-image: url(icon01.png);: 배경 이미지로 icon01.png를 설정합니다.
- background-size, background-position, background-repeat: 배경 이미지를 가운데에 배치하고 반복 없이 크기를 맞춥니다.
- transition: all .4s;: 모든 속성에 0.4초 동안 부드러운 전환 효과를 적용합니다.
- .choice:has(:checked)::before:
- :has(:checked)는 선택된 상태의 라디오 버튼이나 체크박스를 포함하는 .choice 요소를 선택합니다.
- background-position: center center;: 선택된 경우 배경 이미지를 가운데로 정확하게 정렬합니다.
요약
- 이 코드는 라디오 버튼과 체크박스를 화면에서 숨기고, 대신 커스텀 스타일의 가상 요소로 선택지 앞에 나타냅니다.
- 선택지 앞에 나타나는 사각형이 있으며, 선택된 경우 배경 이미지가 중앙에 배치됩니다.
- pointer-events: none;으로 숨겨진 버튼들이 사용자와의 상호작용을 막고, 커스텀 디자인이 안전하게 적용됩니다.