บ่อยครั้งในอดีต ฉันต้องหาวิธีเพิ่มสไตล์ให้กับองค์ประกอบทั้งหมดภายในคอนเทนเนอร์ แต่ ไม่ โฉบหนึ่ง
เอฟเฟกต์นี้ต้องเลือกพี่น้องขององค์ประกอบที่โฮเวอร์ ฉันเคยใช้ JavaScript สำหรับสิ่งนี้ เพิ่มหรือลบคลาสที่กำหนดกฎ CSS ที่เหมาะสมใน mouseenter
และ mouseleave
เหตุการณ์ที่คล้ายกันนี้:
แม้ว่าโค้ดจะใช้ได้ผล แต่ความรู้สึกในอุทรของฉันมักจะบอกฉันว่าต้องมีวิธี 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;
}
โค้ดตัวอย่างนี้จะสร้างรายการสามรายการที่มีสามคอลัมน์ในตาราง
พลังของตัวเลือก CSS
ตอนนี้ มาเพิ่มการโต้ตอบกัน แนวทางที่ฉันใช้ในตอนแรกนั้นขึ้นอยู่กับสองขั้นตอน:
- การวางเมาส์ไว้บนคอนเทนเนอร์ควรเปลี่ยนรูปแบบขององค์ประกอบทั้งหมดภายใน...
- …ยกเว้นเคอร์เซอร์ที่เลื่อนอยู่ในขณะนี้
เริ่มต้นด้วยการจับเด็กทุกคนในขณะที่เคอร์เซอร์วางเมาส์เหนือคอนเทนเนอร์:
.grid:hover .grid__child {
/* ... */
}
ประการที่สอง แยกรายการที่โฮเวอร์อยู่ในขณะนี้และลด opacity
ของเด็กคนอื่น ๆ :
.grid:hover .grid__child:not(:hover) {
opacity: 0.3;
}
และนี่จะเพียงพอสำหรับคอนเทนเนอร์ที่ไม่มีช่องว่างระหว่างองค์ประกอบย่อย:
อย่างไรก็ตาม ในกรณีของฉัน ฉันไม่สามารถลบช่องว่างเหล่านี้ได้:
เมื่อฉันเลื่อนเมาส์ไปมาระหว่างแผ่นกระเบื้อง องค์ประกอบของลูกๆ ทั้งหมดก็ค่อยๆ จางลง
ละเว้นช่องว่าง
เราสามารถสรุปได้ว่าช่องว่างเป็นส่วนหนึ่งของภาชนะที่ลูกไม่ได้ซ้อนทับ เราไม่ต้องการเรียกใช้เอฟเฟกต์ทุกครั้งที่เคอร์เซอร์เข้าสู่คอนเทนเนอร์ แต่เมื่อมันวางเหนือองค์ประกอบใดองค์ประกอบหนึ่งภายใน เราสามารถเพิกเฉยต่อเคอร์เซอร์ที่เคลื่อนที่เหนือช่องว่างได้หรือไม่?
ใช่ เราทำได้ โดยใช้ pointer-events: none
บน .grid
ภาชนะแล้วนำกลับมาด้วย pointer-events: auto
เกี่ยวกับลูก ๆ ของมัน:
.grid {
/* ... */
pointer-events: none;
}
/* ... */
.grid__child {
/* ... */
pointer-events: auto;
}
มาเพิ่มทรานซิชันเจ๋งๆ บน opacity และเรามีส่วนประกอบพร้อมแล้ว:
มันอาจจะเจ๋งกว่านี้ด้วยซ้ำเมื่อเราเพิ่มไทล์และสร้างเลย์เอาต์ 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
สไตล์จะไม่สนใจเหตุการณ์โฮเวอร์เท่านั้นแต่จะไม่สนใจเหตุการณ์อื่นๆ ทั้งหมดด้วย ในสถานการณ์เช่นนี้ คุณสามารถห่อ .grid
ในคอนเทนเนอร์อื่นดังนี้:
สรุป
ฉันขอแนะนำอย่างยิ่งให้คุณทดลองและพยายามค้นหาแนวทางที่เรียบง่ายและเป็นธรรมชาติมากขึ้นสำหรับงานที่คาดว่าจะมีความซับซ้อนในระดับหนึ่ง เทคโนโลยีเว็บ เช่น CSS นั้นมีประสิทธิภาพมากขึ้นเรื่อยๆ และด้วยการใช้โซลูชันดั้งเดิมที่พร้อมใช้งานทันที คุณสามารถบรรลุผลลัพธ์ที่ยอดเยี่ยมโดยไม่ต้องบำรุงรักษาโค้ดของคุณ และยกให้ผู้จำหน่ายเบราว์เซอร์
ฉันหวังว่าคุณจะชอบบทแนะนำสั้นๆ นี้และพบว่ามีประโยชน์ ขอบคุณ!
ผู้เขียนเลือก เทคโนโลยี การศึกษา เพื่อรับเงินบริจาคเป็นส่วนหนึ่งของ เขียนเพื่อบริจาค โครงการ