:not 셀렉터

1 2 3 4 5
| <ul class="grid"> <li class="grid__child"></li> <li class="grid__child"></li> <li class="grid__child"></li> </ul>
|
1 2 3 4 5 6 7 8 9 10 11
| .grid { display: grid; grid-template-columns: repeat(auto-fit, 15rem); grid-gap: 1rem; }
.grid__child { background: rgba(0, 0, 0, 0.1); border-radius: 0.5rem; aspect-ratio: 1/1; }
|
- 이렇게 생긴 그리드 아이템에 마우스 올린 요소만 hover 효과를 주고 나머지 요소는 공통적으로 다른 효과를 주고 싶을 때, :not, :hover 셀렉터가 유용하다.
1 2 3
| .grid:hover .grid__child:not(:hover) { opacity: 0.3; }
|

- 이렇게 마우스가 올라간 요소만 제외하고 opacity가 변경되는 것을 볼 수 있다.
하지만 한가지 문제점은 grid의 gap이 있을 경우 item에 마우스가 올라갔을 때 뿐만 아니라 gap에 마우스가 올라갔을 때에도 해당 css가 적용된다.
이를 해결하기 위해서 부모 요소에는 pointer-events: none
을 주고 자식 요소에는 pointer-events: auto
를 줘서 해결할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| .grid { display: grid; grid-template-columns: repeat(auto-fit, 15rem); grid-gap: 2rem; pointer-events: none; } .grid__child { background: rgba(0, 0, 0, 0.1); border-radius: 0.5rem; aspect-ratio: 1/0.5; pointer-events: auto; transition: opacity 0.3s; }
.grid:hover .grid__child:not(:hover) { opacity: 0.3; }
|
TroubleShooting
pointer-events: none
속성은 hover이벤트 뿐만 아니라 다른 모든 이벤트도 무시한다. 그래서 scroll이 되어야하는 경우에 스크롤이 되지 않는 문제가 발생할 수 있다.
이를 해결하기 위해서는 해당 부모요소를 감싸는 container 박스를 생성하는 것이다.
1 2 3 4 5 6 7 8 9 10 11
| <div class="container"> <ul class="grid"> <li class="grid__child"></li> <li class="grid__child"></li> <li class="grid__child"></li> <li class="grid__child"></li> <li class="grid__child"></li> <li class="grid__child"></li> <li class="grid__child"></li> </ul> </div>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| .container { width: 400px; height: 300px; overflow: auto; }
.grid { display: grid; grid-template-columns: repeat(auto-fit, 15rem); grid-gap: 2rem; pointer-events: none; } .grid__child { background: rgba(0, 0, 0, 0.1); border-radius: 0.5rem; aspect-ratio: 1/0.5; // 가로 세로 비율 pointer-events: auto; transition: opacity 0.3s; }
.grid:hover .grid__child:not(:hover) { opacity: 0.3; }
li { list-style-type: none; }
|
- grid 요소를 감싸는 container 요소에 scroll을 가능하게
overflow:auto
속성을 주면 스크롤도 작동하고 gap 부분에서 hover 이벤트도 방지할 수 있다.
댓글 공유