:not을 사용한 순수 CSS 갤러리 포커스 효과

소스 노드 : 1723238

종종 과거에는 컨테이너 내부의 모든 요소에 스타일을 추가하는 방법을 알아야 했지만 지원 떠 있는 것.

사용자가 특정 요소에 "집중"할 수 있도록 형제에 대한 예상되는 "페이드아웃" 효과의 데모.

이 효과는 호버링된 요소의 형제를 선택해야 합니다. 적절한 CSS 규칙을 정의한 클래스를 추가하거나 제거하여 이를 위해 JavaScript를 적용했습니다. mouseentermouseleave 다음과 유사한 이벤트:

코드가 트릭을 수행하지만 내 직감은 항상 동일한 결과를 달성하기 위해 순수 CSS 방식이 있어야 한다고 말했습니다. 몇 년 전 회사에서 특정 슬라이더를 작업하는 동안 다음과 유사한 솔루션을 생각해 냈습니다. Chris Geelhoed가 유명한 Netflix 홈페이지 애니메이션을 재창조한 방법 그리고 더 이상 JavaScript가 필요하지 않다는 것을 이해했습니다.

몇 달 전에 저는 회사 웹사이트에서 그리드 기반 피드에 대해 동일한 접근 방식을 구현하려고 시도했지만 — 붐 — 요소 간의 간격 때문에 작동하지 않았습니다!

운 좋게도 이 상태로 있을 필요는 없는 것 같았고 다시 한 번 JavaScript가 필요하지 않았습니다.

마크업 및 기본 CSS

적절한 마크업을 준비하여 코딩을 시작하겠습니다.

  • .grid 그리드 기반이다

      명부;

    • .grid__child 요소는
    • 소통하고 싶은 아이들.

    마크업은 다음과 같습니다.

    스타일은 다음과 같아야 합니다.

    .grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, 15rem);
      grid-gap: 1rem;
    }
    
    .grid__child {
      background: rgba(0, 0, 0, .1);
      border-radius: .5rem;
      aspect-ratio: 1/1;
    }

    이 예제 코드는 그리드에서 XNUMX개의 열을 차지하는 XNUMX개의 목록 항목을 생성합니다.

    CSS 선택기의 힘

    이제 상호 작용을 추가해 보겠습니다. 내가 처음에 적용한 접근 방식은 두 단계를 기반으로 했습니다.

    1. 컨테이너 위로 마우스를 가져가면 내부의 모든 요소 스타일이 변경됩니다...  
    2. ...현재 커서가 떠 있는 것을 제외하고.

    커서가 컨테이너 위에 있는 동안 모든 자식을 잡는 것으로 시작하겠습니다.

    .grid:hover .grid__child {
      /* ... */
    }

    둘째, 현재 호버링된 항목을 제외하고 opacity 다른 어린이의:

    .grid:hover .grid__child:not(:hover) {
      opacity: 0.3;
    }

    그리고 이것은 자식 요소 사이에 간격이 없는 컨테이너에 대해 완벽하게 충분할 것입니다.

    간격으로 구분되지 않은 요소와 상호 작용하는 마우스 커서의 애니메이션 GIF입니다.
    공백 없이 작동하는 솔루션의 데모.

    그러나 제 경우에는 이러한 간격을 제거할 수 없었습니다.

    요소 위로 마우스 커서를 가져가는 애니메이션 GIF입니다. 그러나 마우스가 두 요소 사이의 간격에 들어가면 마우스가 요소를 떠나면서 효과가 종료됩니다.
    갭이 도입될 때 발생하는 문제의 데모입니다.

    타일 ​​사이에서 마우스를 움직일 때 모든 자식 요소가 페이드 아웃되었습니다.

    공백 무시

    간격은 자식에 의해 오버레이되지 않는 컨테이너의 일부라고 가정할 수 있습니다. 커서가 컨테이너에 들어갈 때마다 효과를 실행하는 것이 아니라 내부 요소 중 하나를 가리킬 때 효과를 실행하고 싶습니다. 그러면 간격 위로 이동하는 커서를 무시할 수 있습니까? 

    예, 할 수 있습니다. pointer-events: none 를 시청하여 이에 대해 더 많은 정보를 얻을 수 있습니다. .grid 컨테이너와 함께 다시 가져오기 pointer-events: auto 자식에 대해:

    .grid {
      /* ... */
      pointer-events: none;
    }
    
    /* ... */
    
    .grid__child {
      /* ... */
      pointer-events: auto;
    }

    불투명도에 멋진 전환을 추가하면 준비된 구성 요소가 있습니다.

    타일을 더 추가하고 2차원 레이아웃을 만들면 더 멋질 것입니다.

    최종 CSS는 다음과 같습니다.

    .grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, 15rem);
      grid-gap: 3rem;
      pointer-events: none;
    }
    
    .grid:hover .grid__child:not(:hover) {
      opacity: 0.3;
    }
    
    .grid__child {
      background: rgba(0, 0, 0, .1);
      border-radius: .5rem;
      aspect-ratio: 1/1;
      pointer-events: auto;
      transition: opacity 300ms;
    }

    단 2줄의 추가 코드로 간격 문제를 극복했습니다!

    가능한 문제

    컴팩트한 솔루션이지만 몇 가지 해결 방법이 필요할 수 있는 상황이 있습니다.

    불행히도 이 트릭은 컨테이너를 스크롤 가능하게 하려는 경우(예: 일종의 수평 슬라이더에서처럼) 작동하지 않습니다. 그만큼 pointer-events: none style은 hover 이벤트뿐만 아니라 다른 모든 이벤트도 무시합니다. 이러한 상황에서 랩핑할 수 있습니다. .grid 다음과 같이 다른 컨테이너에서

    요약

    일반적으로 어느 정도의 복잡성이 예상되는 작업에 대해 더 간단하고 기본적인 접근 방식을 실험하고 찾아보기를 강력히 권장합니다. CSS와 같은 웹 기술은 점점 더 강력해지고 있으며 즉시 사용 가능한 기본 솔루션을 사용하면 코드를 유지 관리하고 브라우저 공급업체에 양도할 필요 없이 훌륭한 결과를 얻을 수 있습니다.

    이 짧은 튜토리얼이 마음에 드셨기를 바라며 도움이 되었기를 바랍니다. 감사!

    작가가 선택한 기술 교육 의 일환으로 기부금을 받기 위해 기부를 위해 쓰기 프로그램)

    타임 스탬프 :

    더보기 CSS 트릭

    CSS 지옥

    소스 노드 : 873885
    타임 스탬프 : 2021 년 5 월 21 일