CSS มีชื่อเสียงว่าไม่มีวิธีเลือกองค์ประกอบหลักโดยตรงตามองค์ประกอบย่อย ซึ่งเป็นสิ่งที่นักพัฒนาแอปต้องการมาหลายปีแล้ว ตัวเลือก :has()
ที่เบราว์เซอร์หลักทุกรายรองรับในตอนนี้จะช่วยแก้ปัญหานี้ได้ ก่อนหน้านี้
:has()
คุณมักจะใช้เชนตัวเลือกแบบยาวหรือเพิ่มคลาสสำหรับฮุกการจัดสไตล์ ตอนนี้คุณจัดสไตล์ตามความสัมพันธ์ขององค์ประกอบกับองค์ประกอบที่สืบทอดได้แล้ว อ่านเพิ่มเติมเกี่ยวกับตัวเลือก :has()
ใน CSS Wrapped 2023 และ 5 ข้อมูลโค้ด CSS ที่นักพัฒนาซอฟต์แวร์ฝั่งหน้าทุกคนควรทราบ
แม้ว่าตัวเลือกนี้จะดูเหมือนไม่มากนัก แต่ก็สามารถทำให้เกิด Use Case ได้จำนวนมาก
บทความนี้แสดงกรณีการใช้งานบางส่วนที่บริษัทอีคอมเมิร์ซปลดล็อกด้วยตัวเลือก :has()
:has()
เป็นส่วนหนึ่งของเกณฑ์พื้นฐานที่กลับมาเปิดให้จองอีกครั้ง
ดูชุดบทความฉบับเต็มที่บทความนี้เป็นส่วนหนึ่งของบทความที่กล่าวถึงวิธีที่บริษัทอีคอมเมิร์ซปรับปรุงเว็บไซต์โดยใช้ฟีเจอร์ CSS และ UI ใหม่
ตลาดนโยบาย
ตัวเลือก
:has()
ช่วยให้เรากำจัดการตรวจสอบที่อิงตาม JavaScript ของการเลือกของผู้ใช้ และแทนที่ด้วยโซลูชัน CSS ที่ทำงานได้อย่างราบรื่นและมอบประสบการณ์การใช้งานแบบเดิม — Aman Soni หัวหน้าทีมเทคโนโลยีของ Policybazaar
ทีมการลงทุนของ Policybazaar ใช้ตัวเลือก :has()
อย่างชาญฉลาดเพื่อแสดงภาพอย่างชัดเจนสำหรับผู้ใช้ที่เปรียบเทียบแผน รูปภาพต่อไปนี้แสดงแผน 2 ประเภทใน UI การเปรียบเทียบ (สีเหลืองและสีน้ำเงิน) แผนแต่ละแผนจะเปรียบเทียบได้กับแผนประเภทเดียวกันเท่านั้น เมื่อใช้ :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 ใช้ Use Case ที่แตกต่างออกไปเล็กน้อย โดยจะมีแบบทดสอบย่อยในบทเรียนสำหรับผู้ใช้ และใช้ :has()
เพื่อตรวจสอบสถานะช่องทำเครื่องหมายของคำถามเพื่อดูว่าผู้ใช้ตอบคำถามแล้วหรือยัง หากใช่ ระบบจะใช้ภาพเคลื่อนไหวเพื่อเปลี่ยนไปยังคำถามถัดไป
รหัส
ในตัวอย่างการเปรียบเทียบแผน มีการใช้ :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 แบบแยกส่วนและอ่านได้ง่ายขึ้น
รหัส
โค้ดต่อไปนี้ใช้ตัวเลือก 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 Wrapped 2023
- :has(): ตัวเลือกครอบครัว
- การสาธิต :has()
- คุณต้องการรายงานข้อบกพร่องหรือขอฟีเจอร์ใหม่ เราอยากฟังความคิดเห็นจากคุณ
สำรวจบทความอื่นๆ ในชุดนี้ซึ่งพูดถึงวิธีที่บริษัทอีคอมเมิร์ซได้รับประโยชน์จากการใช้ฟีเจอร์ CSS และ UI ใหม่ เช่น ภาพเคลื่อนไหวที่ทำงานตามการเลื่อน การเปลี่ยนมุมมอง การแสดงผลแบบป๊อปอัป และการค้นหาคอนเทนเนอร์