Computer >> 컴퓨터 >  >> 프로그래밍 >> CSS

CSS :focus-within 가상 클래스로 포커스된 요소의 부모 스타일링하기

웹 개발을 하다 보면 포커스를 받은 입력 요소 자체가 아니라, 그 요소를 감싸고 있는 부모 요소에 스타일을 적용해야 하는 경우가 종종 있습니다. 이럴 때 유용하게 사용할 수 있는 것이 바로 CSS의 :focus-within 가상 클래스입니다.

:focus-within은 해당 요소 자신 또는 그 하위 요소 중 하나라도 포커스를 받으면 활성화됩니다. 즉, 사용자가 폼 필드나 버튼을 클릭하는 순간 부모 컨테이너의 배경색이나 그림자 등을 손쉽게 변경할 수 있습니다.

예제 1: form 요소에 적용하기

<!DOCTYPE html>
<html>
<head>
<style>
form {
   margin: 2%;
   padding: 2%;
   display: flex;
   flex-direction: column;
   background: thistle;
}
input {
   margin: 2%;
}
form:focus-within {
   background-color: burlywood;
   box-shadow: 0 0 12px rgba(0,0,0,0.6)
}
input:focus {
   box-shadow: 0 0 12px rgba(0,0,0,0.6)
}
</style>
</head>
<body>
<form>
<input type="text" placeholder="name"/>
<input type="email" placeholder="email"/>
</form>
</body>
</html>

출력 결과

위 코드를 실행하면 다음과 같은 결과가 출력됩니다 −

CSS :focus-within 가상 클래스로 포커스된 요소의 부모 스타일링하기

이 예제에서는 form 태그에 :focus-within을 적용했습니다. name 또는 email 입력 필드 중 하나라도 클릭하여 포커스를 받으면, 폼 전체의 배경색이 thistle에서 burlywood로 변경되고 은은한 박스 그림자가 함께 나타납니다. 동시에 input:focus 덕분에 포커스된 입력 필드 자체에도 그림자 효과가 적용됩니다.

예제 2: div 컨테이너에 적용하기

<!DOCTYPE html>
<html>
<head>
<style>
div {
   width: 40%;
   margin: 2%;
   padding: 2%;
   display: flex;
   flex-direction: column;
   background: lavenderblush;
}
div > * {
   margin: 2%;
}
div:focus-within {
   background-color: aliceblue;
   box-shadow: 0 0 12px rgba(0,0,0,0.6)
}
</style>
</head>
<body>
<div>
<textarea></textarea>
<button>Click</button>
</div>
</body>
</html>

출력 결과

위 코드를 실행하면 다음과 같은 결과가 출력됩니다 −

CSS :focus-within 가상 클래스로 포커스된 요소의 부모 스타일링하기

두 번째 예제는 div 컨테이너 안에 textareabutton을 배치한 경우입니다. 텍스트 영역이든 버튼이든 어느 쪽이 포커스를 받더라도 부모인 div의 배경색이 lavenderblush에서 aliceblue로 바뀌며 박스 그림자가 추가되는 것을 확인할 수 있습니다.

:focus-within 핵심 정리

:focus-within:focus와 달리 하위 요소의 포커스 상태까지 감지한다는 점이 핵심입니다. 이를 활용하면 JavaScript 없이도 순수 CSS만으로 다음과 같은 UI 효과를 구현할 수 있습니다.

- 포커스 시 폼 전체 강조 효과
- 검색창 컨테이너 하이라이트
- 카드형 레이아웃에서 입력 요소 선택 시 카드 테두리 변경

또한 :focus-within은 Chrome, Firefox, Safari, Edge 등 주요 최신 브라우저에서 모두 지원되므로 실무 프로젝트에서도 안심하고 사용할 수 있습니다.