본문 바로가기

선택자 심화

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;
}
선택자 심화 - HTML/CSS 에센셜 | 위니버시티