Một Hiệu ứng Trọng tâm Thư viện CSS thuần túy với: not

Nút nguồn: 1723238

Thông thường trước đây, tôi cần tìm cách thêm kiểu vào tất cả các phần tử bên trong vùng chứa nhưng không cái lơ lửng.

Demo về hiệu ứng “mờ dần” dự kiến ​​đối với anh chị em để cho phép người dùng “tập trung” vào một yếu tố cụ thể.

Hiệu ứng này yêu cầu chọn các anh chị em của một phần tử được di chuột qua. Tôi đã từng áp dụng JavaScript cho việc này, thêm hoặc xóa lớp xác định các quy tắc CSS thích hợp trên mouseentermouseleave sự kiện, tương tự như thế này:

Mặc dù mã thực hiện thủ thuật, nhưng cảm giác ruột của tôi luôn nói với tôi rằng phải có một số cách thuần CSS để đạt được kết quả tương tự. Một vài năm trước, khi làm việc trên một thanh trượt nhất định cho công ty của tôi, tôi đã nghĩ ra một giải pháp tương tự như Chris Geelhoed đã tạo lại hoạt hình nổi tiếng trên trang chủ Netflix như thế nào và tôi hiểu rằng tôi không cần JavaScript cho việc này nữa.

Một vài tháng trước, tôi đang cố gắng triển khai cùng một cách tiếp cận đối với nguồn cấp dữ liệu dựa trên lưới trên trang web của công ty tôi và - bùng nổ - nó không hoạt động do khoảng cách giữa các yếu tố!

Thật may mắn cho tôi, có vẻ như nó không phải tiếp tục như thế này, và một lần nữa tôi không cần JavaScript cho nó.

Đánh dấu và CSS cơ sở

Hãy bắt đầu viết mã bằng cách chuẩn bị đánh dấu thích hợp:

  • .grid dựa trên lưới

      danh sách;

    • .grid__child các yếu tố là
    • trẻ em mà chúng tôi muốn tương tác.

    Đánh dấu trông như thế này:

    Phong cách sẽ như thế này:

    .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;
    }

    Mã ví dụ này sẽ tạo ba mục danh sách chiếm ba cột trong một lưới.

    Sức mạnh của bộ chọn CSS

    Bây giờ, hãy thêm một số tương tác. Cách tiếp cận mà tôi áp dụng ban đầu dựa trên hai bước:

    1. di chuột trên vùng chứa sẽ thay đổi kiểu của tất cả các phần tử bên trong…  
    2. … Ngoại trừ con trỏ đang di chuột vào lúc này.

    Hãy bắt đầu với việc lấy từng con khi con trỏ di chuột qua vùng chứa:

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

    Thứ hai, hãy loại trừ mục hiện được di chuột qua và giảm opacity của bất kỳ đứa trẻ nào khác:

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

    Và điều này sẽ là đủ hoàn hảo cho các vùng chứa không có khoảng cách giữa các phần tử con:

    GIF động của con trỏ chuột tương tác với các phần tử không bị phân tách bởi bất kỳ khoảng trống nào.
    Demo của một giải pháp hoạt động mà không có lỗ hổng.

    Tuy nhiên, trong trường hợp của tôi, tôi không thể xóa những khoảng trống này:

    Ảnh động GIF của con trỏ chuột di chuột qua các phần tử. Tuy nhiên, khi chuột đi vào khoảng trống giữa hai phần tử, hiệu ứng sẽ kết thúc khi chuột rời khỏi phần tử.
    Demo của vấn đề gặp phải khi các khoảng trống được giới thiệu.

    Khi tôi di chuyển chuột giữa các ô, tất cả các phần tử con đều mờ dần.

    Bỏ qua những khoảng trống

    Chúng ta có thể giả định rằng các khoảng trống là các phần của vật chứa không được các con của nó che phủ. Chúng tôi không muốn chạy hiệu ứng mỗi khi con trỏ vào vùng chứa, mà là khi nó di chuột qua một trong các phần tử bên trong. Sau đó chúng ta có thể bỏ qua con trỏ di chuyển trên các khoảng trống không? 

    Có, chúng tôi có thể, bằng cách sử dụng pointer-events: none trên .grid thùng chứa và mang chúng trở lại với pointer-events: auto trên con cái của nó:

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

    Hãy chỉ thêm một số chuyển đổi thú vị về độ mờ và chúng ta đã có một thành phần sẵn sàng:

    Nó có lẽ còn tuyệt hơn khi chúng tôi thêm nhiều ô và tạo bố cục 2 chiều:

    CSS cuối cùng trông như thế này:

    .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;
    }

    Chỉ với 2 dòng mã bổ sung, chúng tôi đã khắc phục được vấn đề khoảng cách!

    Các vấn đề có thể xảy ra

    Mặc dù đó là một giải pháp nhỏ gọn, nhưng có một số tình huống mà nó có thể yêu cầu một số giải pháp thay thế.

    Thật không may, thủ thuật này sẽ không hoạt động khi bạn muốn vùng chứa có thể cuộn được, chẳng hạn như trong một loại thanh trượt ngang nào đó. Các pointer-events: none style sẽ không chỉ bỏ qua sự kiện di chuột mà còn bỏ qua tất cả các sự kiện khác. Trong những tình huống như vậy, bạn có thể bọc .grid trong một vùng chứa khác, như thế này:

    Tổng kết

    Tôi thực sự khuyến khích bạn thử nghiệm và cố gắng tìm ra một cách tiếp cận đơn giản và nguyên bản hơn cho các nhiệm vụ thường được mong đợi là có một số mức độ phức tạp. Các công nghệ web, như CSS, ngày càng trở nên mạnh mẽ hơn và bằng cách sử dụng các giải pháp gốc sẵn có, bạn có thể đạt được kết quả tuyệt vời mà không cần phải duy trì mã của mình và nhượng lại cho các nhà cung cấp trình duyệt.

    Tôi hy vọng rằng bạn thích hướng dẫn ngắn này và thấy nó hữu ích. Cảm ơn!

    Tác giả đã chọn Tech Đào tạo để nhận được một khoản đóng góp như một phần của Viết để quyên góp chương trình.

    Dấu thời gian:

    Thêm từ Thủ thuật CSS