Tech/Styling

[SCSS] 관계 선택자로 인한 nesting 삽질 후기와 해결

닝닝깅 2024. 3. 13. 20:31

TailwindCSS에서 SCSS로 바꾸는 도중 문제가 발생했다.!! 근데 해결하고 보니 어처구니 없는 기초적인 실수라서 다시는 같은 실수를 하지 않기 위해 부끄럽지만 기록해보려 한다.

 

🚨 문제 발생

토글 버튼을 직접 구현하는 과정에서 css가 적용되지 않는 문제가 발생했다.

원래대로라면 체크박스 형식의 input 선택 유무에 따라 .btnInputBody 와 .btnInputBall의 속성이 바뀌어야 한다. 하지만 속성이 바뀌지 않았다..ㅜㅜ

 

tailwindCSS로는 무난하게 구현했었는데 왜 문제가 발생했을까?

import styles from "./input.module.scss"

<span className={styles.btnInput}>
  <input id="toggleBtn" type="checkbox" onClick={handleIsPositive} />
  <div className={styles.btnInputBody}></div>
  <div className={styles.btnInputBall}></div>
</span>;
.btnInput {
  input{
    display:none
  }
  input:checked {
    .btnInputBody{
    	background-color: red
    }
    .btnInputBall{
    	background-color: yellow
    }
  }
}

 

🔫 원인 찾기

속성이 적용되었는데 유효성이 없는 건지 아예 적용된지도 않은 건지 확인해보기 위해 관리자도구를 살펴보았고, 아예 적용되지 않은 것을 확인하였다.

input:checked{
  display:block
}

해당 구문은 제대로 동작하는 것을 확인하고 이것은 input과 div의 관계 선택자 문제일 것이라는 생각을 했다.

 

input과 div는 같은 부모요소를 갖기 때문에 형제관계이다. 이때 html 문서에 먼저 쓰여지는대로 형요소와 동생요소가 나뉘어지게된다. input은 형요소, div는 동생요소가 되는 것이다.

 

내가 작성한 scss 구문을 살펴보자

scss는 nesting(중첩)구조를 지원하여 다음과 같은 구문을 작성할 수 있다. 나는 이 구문이 부모-자식 간의 관계뿐만 아니라 형제 관계에서도 적용이 되는 것인줄 알았다. 이것이 문제였다.

input:checked {
    .btnInputBody{
    	background-color: red
    }
    .btnInputBall{
    	background-color: yellow
    }
}

scss의 nesting구조는 부모-자식간의 관계에만 적용된다. 해당 구문을 css로 변환시켜보면 다음과 같다.

input:checked .btnInputBody{ background-color: red; }

 

결론적으로 형제 선택자 요소를 사용해서 스타일을 적용하는 것이 옳다는 것을 알게 되었다.

 

이때 주의해야할 것은 인접 형제 선택자가 아닌 일반 형제 선택자로 써야한다. 인접 형제 선택자를 사용할 때 사이에 다른 요소가 존재하면 선택되지 않기 때문이다. 두번째 div에 인접 형제 선택자를 사용하면 사이에 첫번째 div가 있기 때문에 또 적용되지 않을 것이다.

인접 형제 선택자(+)는 형제 중 첫번째 동생 요소가 조건을 충족시킬 때에 스타일을 적용하고, 
일반 형제 선택자(~)는 조건을 충족하는 모든 동생 요소에 스타일을 적용한다.

 

✅ 해결완료!

일반 형제 선택자로 통일하여 해결 완료! 스타일이 잘 적용된다.

.btnInput {
  input{
    display:none
  }
  
  input[type="checkbox"]:checked ~ .btnInputBody {
    background-color: $yellow;
  }

  input[type="checkbox"]:checked ~ .btnInputBall {
    right: 0;
    left: auto;
  }
}

 

😂 후기

문제를 금방 알아챌 수 있었지만, 알아채고 보니 기초적인 문법 실수를 저질렀다는 사실이 참 부끄러웠다. 하지만 이번 기회를 통해 다른 css와 scss의 기초적인 문법에 대하여 자세히 알아봤기 때문에 결국엔 도움이 된 시간이기도 했다.

다시는 이런 기초적인 실수를 하지 않겠다고 굳게 마음을 먹게 되었다!! 네버!