선택자 심화
1. 고급 포커스 선택자
고급 포커스 선택자는 웹 접근성을 높이면서도 깔끔한 UI를 유지하기 위한 CSS 가상 클래스들입니다.
1.1 :focus-visible
:focus와 유사하지만 :focus는 포커스된 요소에 항상 적용되는 반면, :focus-visible은 좀 더 선택적으로 작동합니다.
:focus-visible은 주로 키보드를 사용하여 페이지를 탐색할 때나 스크립트를 통해 포커스가 관리될 때 활성화됩니다. 이는 사용자가 현재 어떤 요소에 포커스가 있는지 시각적으로 확인해야 하는 상황에서 유용합니다. 그러나 마우스나 터치 인터페이스를 사용하여 요소에 물리적으로 포커스를 설정할 때는 일반적으로 :focus-visible이 활성화되지 않습니다. 이는 사용자가 이미 자신이 어떤 요소를 선택했는지 알고 있기 때문입니다.
:focus-visible의 주요 목적은 사용자 경험을 개선하는 것입니다. 이 가상 클래스를 사용함으로써 불필요한 시각적 표시를 줄여 인터페이스를 깔끔하게 유지할 수 있습니다. 동시에 키보드 사용자에게는 명확한 포커스 표시를 제공하여 웹 접근성을 향상시킬 수 있습니다.
<div class="container">
<button class="btn">버튼</button>
<a href="#" class="link">Link 버튼</a>
<input
type="text"
class="input"
placeholder=" 텍스트 입력창"
autocomplete="off"
/>
<div class="custom-button" tabindex="0">사용자 정의 포커스 가능 요소</div>
</div>
.container {
display: flex;
flex-direction: column;
gap: 15px;
padding: 20px;
background-color: #f0f0f0;
}
.btn,
.link,
.input,
.custom-button {
padding: 10px 15px;
border: 2px solid lightgray;
border-radius: 5px;
font-size: 16px;
transition: all 0.3s ease;
}
/* Focus 스타일 */
.btn:focus,
.link:focus,
.input:focus,
.custom-button:focus {
outline: none;
box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.5);
}
/* Focus-visible 스타일 */
/* 키보드 포커스를 받는 경우에만 적용할 스타일 */
.btn:focus-visible,
.link:focus-visible,
.input:focus-visible,
.custom-button:focus-visible {
outline: none;
border-color: dodgerblue;
box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.5);
}
/* 구체적인 스타일 부여 */
.btn {
background-color: skyblue;
color: white;
cursor: pointer;
}
.link {
background-color: transparent;
color: skyblue;
text-decoration: none;
}
.input {
background-color: white;
}
.custom-button {
background-color: royalblue;
cursor: pointer;
}
/* 마우스 호버 스타일 */
.btn:hover,
.link:hover,
.custom-button:hover {
opacity: 0.8;
box-shadow: 0 0 0 1px rgba(66, 153, 225, 0.3);
}
주의
:focus-visible의 정확한 동작은 브라우저에 따라 약간 다를 수 있습니다. 일부 브라우저에서는 마우스 클릭으로도 :focus-visible이 트리거될 수 있습니다.
1.2 :focus-within
요소 또는 그 자식 요소가 포커스를 받았을 때 적용됩니다.
<div class="form-group">
<label for="name">이름:</label>
<input type="text" id="name" autocomplete="off" />
</div>
<div class="form-group">
<label for="email">이메일:</label>
<input type="email" id="email" autocomplete="off" />
</div>
.form-group {
margin-bottom: 15px;
padding: 10px;
transition: background-color 0.3s ease;
border: 1px solid #ddd;
}
.form-group:focus-within {
background-color: lightblue;
border-color: cornflowerblue;
}
label {
display: block;
margin-bottom: 5px;
}
input {
padding: 5px;
border: 1px solid #ccc;
width: 100%;
}
/* 내부 요소가 포커스를 받으면 적용할 스타일 */
input:focus-visible {
outline: 2px solid cornflowerblue;
border-color: cornflowerblue;
}
:focus-within은 폼 디자인에 특히 유용합니다. 사용자가 특정 입력 필드에 포커스를 맞출 때 전체 폼 그룹의 스타일을 변경할 수 있습니다.
2. 상태 관련 가상 클래스 선택자
2.1 :enabled
활성화된 상태의 폼 요소를 선택합니다.
2.2 :disabled
비활성화된 상태의 폼 요소를 선택합니다.
<form>
<div class="form-group">
<label for="username">닉네임:</label>
<input type="text" id="username" class="form-control" autocomplete="off" />
</div>
<div class="form-group">
<label for="password">비밀번호:</label>
<input
type="password"
id="password"
class="form-control"
autocomplete="off"
/>
</div>
<div class="form-group">
<label for="country">국가:</label>
<select id="country" class="form-control">
<option value="">거주 국가를 선택하세요</option>
<option value="ko">한국</option>
<option value="us">미국</option>
<option value="au">호주</option>
</select>
</div>
<button type="submit" class="btn-submit">제출하기</button>
<button type="button" class="btn-reset" disabled>초기화</button>
</form>
.form-group {
margin-bottom: 15px;
}
.form-control {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}
.form-control:enabled {
background-color: #fff;
}
.form-control:disabled {
background-color: lightgray;
cursor: not-allowed;
}
button {
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
transition: all 0.3s ease;
}
.btn-submit:enabled {
background-color: cornflowerblue;
color: white;
}
.btn-submit:enabled:hover {
background-color: royalblue;
}
.btn-reset:disabled {
background-color: #ddd;
color: lightgray;
cursor: not-allowed;
}
2.3 :checked
체크된 상태의 라디오 버튼이나 체크박스를 선택합니다.
<div class="option-container">
<h3>체크박스 예제</h3>
<div class="item">
<input type="checkbox" id="apple" autocomplete="off" />
<label for="apple">사과</label>
</div>
<div class="item">
<input type="radio" id="banana" autocomplete="off" />
<label for="banana">바나나</label>
</div>
</div>
/* 기본 스타일 */
.option-container {
margin: 20px;
font-family: Arial, sans-serif;
}
/* 체크박스가 체크되었을 때 라벨 스타일 변경 */
input[type='checkbox']:checked + label {
color: royalblue;
font-weight: bold;
}
/* 라디오 버튼이 선택되었을 때 라벨 스타일 변경 */
input[type='radio']:checked + label {
color: royalblue;
font-weight: bold;
}
/* 라벨 스타일 */
label {
margin-left: 5px;
cursor: pointer;
}
/* 각 항목 간격 */
.item {
margin-bottom: 10px;
}
3. 속성 선택자
속성 선택자는 HTML 요소의 속성을 기반으로 요소를 선택하는 강력한 도구입니다. 이를 통해 특정 속성을 가진 요소나 속성 값이 특정 패턴을 가진 요소를 선택할 수 있습니다.
3.1 기본 속성 선택자 [속성이름]
해당 속성을 가진 모든 요소를 선택합니다.
<p title="Hello">This paragraph has a title.</p>
<p>This paragraph doesn't have a title.</p>
<a href="#" title="Link">This is a link</a>
[title] {
border-bottom: 2px dotted #333;
}
3.2 속성값 선택자
3.2.1 [속성이름="속성값"] 선택자
해당 속성에 해당 속성값을 가진 모든 요소를 선택합니다.
<div class="btn">Primary Button</div>
<div class="btn secondary">Secondary Button</div>
<div class="button tertiary">Tertiary Button</div>
<div class="btn">Primary Button</div>
[class='btn'] {
padding: 10px;
margin: 5px 0;
border-radius: 5px;
background-color: rgb(255, 168, 168);
}
3.2.2 [속성이름~="속성값"] 선택자
공백으로 구분된 단어 목록 중 특정 단어를 포함하는 요소를 선택합니다.
<div class="btn primary">Primary Button</div>
<div class="btn secondary">Secondary Button</div>
<div class="button tertiary">Tertiary Button</div>
[class~='btn'] {
padding: 10px;
border-radius: 5px;
background-color: #f0f0f0;
}
3.2.3 [속성이름|="속성값"] 선택자
특정 문자열만 포함하거나, 특정 문자열로 시작하면서 바로 하이픈(-)이 오는 요소를 선택합니다.
<div lang="en">English</div>
<div lang="en-US">American English</div>
<div lang="en-GB">British English</div>
<div lang="enKo">English 한국어</div>
<div lang="fr">French</div>
[lang|='en'] {
color: blue;
}
3.2.4 [속성이름^="속성값"] 선택자
특정 문자열로 시작하는 요소를 모두 선택합니다.
<div class="btn-primary">Primary Button</div>
<div class="btn-secondary">Secondary Button</div>
<div class="button-tertiary">Tertiary Button</div>
[class^='btn'] {
font-weight: bold;
color: #333;
}
3.2.5 [속성이름$="속성값"] 선택자
특정 문자열로 끝나는 요소를 모두 선택합니다.
<div class="text-primary">Primary Text</div>
<div class="bg-primary">Primary Background</div>
<div class="border-secondary">Secondary Border</div>
[class$='primary'] {
background-color: #e6f7ff;
}
3.2.6 [속성이름*="속성값"] 선택자
특정 문자열을 포함하는 요소를 모두 선택합니다.
<div class="btn-large">Large Button</div>
<div class="large-btn">Another Large Button</div>
<div class="button-large-primary">Large Primary Button</div>
[class*='btn'] {
cursor: pointer;
padding: 5px 10px;
}