กรณีศึกษา :has()

Swetha Gopalakrishnan
Swetha Gopalakrishnan
Saurabh Rajpal
Saurabh Rajpal

เป็นที่รู้กันว่า CSS ไม่มีวิธีเลือกองค์ประกอบหลักโดยตรง เด็กๆ ของพวกเขา นี่เป็นคำขอจากนักพัฒนาซอฟต์แวร์มากที่สุดมาหลายปีแล้ว ตัวเลือก :has() ซึ่งเบราว์เซอร์หลักๆ ทั้งหมดรองรับก็ช่วยแก้ปัญหานี้ได้ ก่อน :has() คุณมักจะผูกตัวเลือกแบบยาวหรือเพิ่มคลาสสำหรับการจัดรูปแบบฮุก เริ่มเลย คุณสามารถจัดรูปแบบตามความสัมพันธ์ขององค์ประกอบกับองค์ประกอบสืบทอด อ่านเพิ่มเติม เกี่ยวกับตัวเลือก :has() ใน CSS ในปี 2023 และ ข้อมูลโค้ด CSS 5 รายการที่นักพัฒนาซอฟต์แวร์ฟรอนท์เอนด์ควรทราบ

แม้ว่าตัวเลือกนี้จะดูเหมือนไม่มากนัก แต่ก็สามารถทำให้เกิด Use Case ได้มากมาย บทความนี้จะแสดงกรณีการใช้งานที่บริษัทอีคอมเมิร์ซปลดล็อกด้วย ตัวเลือก :has()

:has() เป็นส่วนหนึ่งของเกณฑ์พื้นฐานใหม่

การรองรับเบราว์เซอร์

  • Chrome: 105
  • ขอบ: 105
  • Firefox: 121
  • Safari: 15.4

แหล่งที่มา

ดูซีรีส์ฉบับเต็มที่อยู่ในบทความนี้ ซึ่งพูดถึงวิธี บริษัทอีคอมเมิร์ซได้เพิ่มประสิทธิภาพเว็บไซต์ของตนโดยใช้ฟีเจอร์ใหม่ของ CSS และ UI

ตลาดนโยบาย

ด้วยตัวเลือก :has() เราจึงกำจัดการตรวจสอบความถูกต้องด้วย JavaScript ได้ ของผู้ใช้ และแทนที่ด้วยโซลูชัน CSS ที่ทำงานได้ดี ได้อย่างราบรื่นสำหรับเราด้วยประสบการณ์ที่เหมือนแต่ก่อน Aman Soni หัวหน้าฝ่ายเทคโนโลยีของ Policybazaar

ทีมการลงทุนของ Policybazaar ได้ใช้ตัวเลือก :has() อย่างชาญฉลาดเพื่อแสดง ข้อมูลที่ชัดเจนสำหรับผู้ใช้ที่กำลังเปรียบเทียบแพ็กเกจต่างๆ รูปภาพต่อไปนี้ แสดงแผน 2 ประเภทภายใน UI การเปรียบเทียบ (สีเหลืองและสีน้ำเงิน) แต่ละแพ็กเกจ สามารถเปรียบเทียบกับประเภทของตนเองเท่านั้น โดยการใช้ :has() เมื่อผู้ใช้เลือก ประเภทแพ็กเกจที่เลือกประเภทแพ็กเกจอื่นไม่ได้

การใช้ :has() เพื่อจัดรูปแบบองค์ประกอบระดับบนสุดและองค์ประกอบย่อยเพื่อสร้าง ฟังก์ชันการเลือกที่ผูกกับหมวดหมู่

รหัส

:has() ให้สิทธิ์คุณจัดรูปแบบองค์ประกอบระดับบนสุดและองค์ประกอบย่อยได้ โค้ดต่อไปนี้จะตรวจสอบว่าคอนเทนเนอร์หลักมีชุดคลาส .disabled-group หรือไม่ ถ้าตรง การ์ดจะเป็นสีเทา และปุ่ม "เพิ่ม" มีการป้องกันปุ่มจาก ตอบสนองต่อการคลิกโดยการตั้งค่า pointer-events เป็น none

.plan-group-container:has(.disabled-group) {
  opacity: 0.5;
  filter: grayscale(100%);
}

.plan-group-container:has(.disabled-section) .button {
  pointer-events: none;
  border-color: #B5B5B5;
  color: var(--text-primary-38-color);
  background: var(--input-border-color);
}

ทีมสุขภาพที่ Policybazaar ใช้ กรณีการใช้งานที่แตกต่างเล็กน้อย โดยมีแบบทดสอบแบบอินไลน์สำหรับผู้ใช้และการใช้ :has() เพื่อตรวจสอบสถานะช่องทำเครื่องหมายคำถามเพื่อดูว่าคำถาม ตอบ หากใช่ ระบบจะใช้ภาพเคลื่อนไหวเพื่อเปลี่ยนไปยังคำถามถัดไป

health.policybazaar.com/

รหัส

ในตัวอย่างการเปรียบเทียบแผน มีการใช้ :has() เพื่อตรวจสอบว่ามี นอกจากนี้ คุณยังสามารถตรวจสอบสถานะขององค์ประกอบอินพุต เช่น ช่องทำเครื่องหมาย โดยใช้ :has(input:checked) ในภาพที่แสดงแบบทดสอบ แต่ละคำถามใน แบนเนอร์สีม่วงเป็นช่องทำเครื่องหมาย Policybazaar จะตรวจสอบว่าคำถาม ตอบโดยใช้ :has(input:checked) และหากมี ให้ทริกเกอร์ภาพเคลื่อนไหวโดยใช้ animation: quesSlideOut 0.3s 0.3s linear forwards เพื่อเลื่อนไปยังรายการถัดไป คำถาม ดูวิธีการทำงานได้ในโค้ดต่อไปนี้

.segment_banner__wrap__questions {
 position: relative;
 animation: quesSlideIn 0.3s linear forwards;
}

.segment_banner__wrap__questions:has(input:checked) {
 animation: quesSlideOut 0.3s 0.3s linear forwards;
}


@keyframes quesSlideIn {
 from {
   transform: translateX(50px);
   opacity: 0;
 }
 to {
   transform: translateX(0px);
   opacity: 1;
 }
}

@keyframes quesSlideOut {
 from {
   transform: translateX(0px);
   opacity: 1;
 }
 to {
   transform: translateX(-50px);
   opacity: 0;
 }
}

Tokopedia

Tokopedia ใช้ :has() เพื่อสร้างภาพซ้อนทับหากภาพปกของผลิตภัณฑ์ มีวิดีโอ หากภาพขนาดย่อของผลิตภัณฑ์มีคลาส .playIcon ระบบ CSS เพิ่มการวางซ้อน ในที่นี้ ตัวเลือก :has() จะถูกใช้ร่วมกับ & ตัวเลือกการวางซ้อนภายในคลาส .thumbnailWrapper ที่ครอบคลุมซึ่งจะมีผล กับภาพปกทั้งหมด วิธีนี้จะช่วยให้เกิด CSS แบบแยกส่วนและอ่านได้ง่ายขึ้น

วันที่ ภาพหน้าจอของหน้า Tokopedia ก่อนและหลังการใช้ตัวเลือกมี
ก่อนและหลังใช้ :has()

รหัส

โค้ดต่อไปนี้ใช้ ตัวเลือก CSS และชุดค่าผสม (& และ >) แล้วซ้อนกับ :has() เพื่อจัดรูปแบบภาพขนาดย่อ สำหรับคนที่ไม่รองรับ เบราว์เซอร์ กฎคลาส CSS เพิ่มเติมปกติจะถูกนำมาใช้เป็นรายการสำรอง นอกจากนี้ยังใช้กฎ @supports selector(:has(*)) เพื่อตรวจสอบการรองรับเบราว์เซอร์ด้วย ดังนั้น ประสบการณ์การใช้งานโดยรวมจึงจะเหมือนกันในทุกเวอร์ชันของเบราว์เซอร์

export const thumbnailWrapper = css`
  padding: 0;
  margin-right: 7px;
  border: none;
  outline: none;
  background: transparent;

  > div {
    width: 64px;
    height: 64px;
    overflow: hidden;
    cursor: pointer;
    border-color: ;
    position: relative;
    border: 2px solid ${NN0};
    border-radius: 8px;
    transition: border-color 0.25s;

    &.active {
      border-color: ${GN500};
    }

    @supports selector(:has(*)) {
      &:has(.playIcon) {
        &::after {
          content: '';
          display: block;
          background: rgba(0, 0, 0, 0.2);
          position: absolute;
          top: 0;
          left: 0;
          right: 0;
          bottom: 0;
        }
      }
    }

    & > .playIcon {
      position: absolute;
      top: 25%;
      left: 25%;
      width: 50%;
      height: 50%;
      text-align: center;
      z-index: 1;
    }
  }
`;

สิ่งที่ต้องพิจารณาเมื่อใช้ :has()

รวม :has() กับตัวเลือกอื่นๆ เพื่อสร้างเงื่อนไขที่ซับซ้อนขึ้น ตรวจสอบ ดูตัวอย่างบางส่วนใน has() ตัวเลือกครอบครัว

แหล่งข้อมูล

อ่านบทความอื่นๆ ในชุดนี้ ซึ่งจะพูดถึงวิธีที่อีคอมเมิร์ซ บริษัทที่ได้รับประโยชน์จากการใช้ฟีเจอร์ใหม่ของ CSS และ UI เช่น การทำงานของการเลื่อน ภาพเคลื่อนไหว ดูการเปลี่ยน ป๊อปโอเวอร์และข้อความค้นหาคอนเทนเนอร์