CSS Container Queries ยังคงได้รับแรงผลักดันและพวกเราหลายคนก็เปียกโชกไปกับมัน แม้ว่าจะเป็นการทดลองเล็กน้อยหรืออะไรก็ตาม พวกเขามีที่ดี แต่ไม่เต็ม การสนับสนุนเบราว์เซอร์ — เพียงพอที่จะพิสูจน์ว่าใช้มันในบางโครงการ แต่อาจจะไม่ถึงขนาดที่เราอาจถูกล่อลวงให้เริ่มแทนที่ คำถามสื่อ จากโครงการที่ผ่านมาด้วยข้อความค้นหาขนาดคอนเทนเนอร์ใหม่ที่เป็นประกาย
พวกเขาแน่ใจว่ามีประโยชน์! อันที่จริง ฉันได้พบเจอบางสถานการณ์แล้วที่ฉันอยากจะเข้าถึงสถานการณ์เหล่านี้จริงๆ แต่ก็ไม่สามารถเอาชนะข้อกำหนดการสนับสนุนได้ ถ้าฉันสามารถใช้มันได้ มันจะเป็นอย่างนี้ในสถานการณ์เหล่านั้น
การสาธิตทั้งหมดต่อไปนี้จะดูดีที่สุดใน Chrome หรือ Safari ในขณะที่เขียนบทความนี้ Firefox วางแผนที่จะ สนับสนุนเรือ ในเวอร์ชัน 109
กรณีที่ 1: ตารางการ์ด
คุณต้องคาดหวังสิ่งนี้ใช่ไหม มันเป็นรูปแบบทั่วไปที่พวกเราทุกคนดูเหมือนจะพบเจอในบางจุด แต่ความจริงก็คือว่าข้อความค้นหาขนาดคอนเทนเนอร์จะช่วยประหยัดเวลาได้มากสำหรับฉันและให้ผลลัพธ์ที่ดีกว่าหากฉันสามารถใช้มันกับข้อความค้นหาสื่อมาตรฐานได้
สมมติว่าคุณได้รับมอบหมายให้สร้างตารางการ์ดนี้โดยมีข้อกำหนดว่าการ์ดแต่ละใบต้องมีอัตราส่วนภาพ 1:1:
มันยากกว่าที่คิด! ปัญหาคือการปรับขนาดเนื้อหาของคอมโพเนนต์บนความกว้างของวิวพอร์ต ทำให้คุณไม่ต้องคำนึงถึงการตอบสนองของคอมโพเนนต์ต่อวิวพอร์ต เช่นเดียวกับวิธีที่คอนเทนเนอร์บรรพบุรุษอื่นๆ ตอบสนอง ตัวอย่างเช่น หากคุณต้องการให้ขนาดแบบอักษรของส่วนหัวของการ์ดลดลงเมื่อการ์ดถึงขนาดอินไลน์ที่กำหนด ไม่มีทางที่เชื่อถือได้
คุณสามารถกำหนดขนาดตัวอักษรใน vw
ฉันคิดว่าหน่วย แต่ส่วนประกอบยังคงเชื่อมโยงกับความกว้างวิวพอร์ตของเบราว์เซอร์ และนั่นอาจทำให้เกิดปัญหาเมื่อมีการใช้ตารางกริดอื่นๆ ในบริบทที่อาจไม่มีเบรกพอยต์เดียวกัน
ในโครงการในโลกแห่งความเป็นจริงของฉัน ฉันใช้แนวทาง JavaScript ที่จะ:
- ฟังเหตุการณ์ปรับขนาด
- คำนวณความกว้างของการ์ดแต่ละใบ
- เพิ่มขนาดฟอนต์แบบอินไลน์ให้กับการ์ดแต่ละใบตามความกว้าง
- ตกแต่งทุกอย่างภายในโดยใช้
em
หน่วย
ดูเหมือนงานเยอะใช่ไหม? แต่เป็นโซลูชันที่เสถียรเพื่อให้ได้มาตราส่วนที่ต้องการตามขนาดหน้าจอต่างๆ ในบริบทต่างๆ
ข้อความค้นหาคอนเทนเนอร์น่าจะดีกว่านี้มากเพราะพวกเขาให้ข้อมูลแก่เรา หน่วยแบบสอบถามคอนเทนเนอร์, เช่น cqw
หน่วย. คุณอาจได้รับแล้ว แต่ 1cqw
เท่ากับ 1%
ของความกว้างของคอนเทนเนอร์ นอกจากนี้เรายังมี cqi
หน่วยวัดความกว้างอินไลน์ของคอนเทนเนอร์ และ cqb
สำหรับความกว้างของบล็อกคอนเทนเนอร์ ดังนั้นหากเรามีที่เก็บการ์ดนั่นคือ 500px
กว้าง ก 50cqw
คำนวณค่าเป็น 250px
.
ถ้าฉันสามารถใช้การค้นหาคอนเทนเนอร์ในตารางการ์ดของฉันได้ ฉันก็สามารถตั้งค่า .card
ส่วนประกอบเป็นคอนเทนเนอร์:
.card {
container: card / size;
}
จากนั้นฉันสามารถตั้งค่ากระดาษห่อด้านในด้วย padding
ซึ่งปรับขนาดได้ที่ 10%
ของ .card
ความกว้างโดยใช้ cqw
หน่วย:
.card__inner {
padding: 10cqw;
}
นั่นเป็นวิธีที่ดีในการปรับระยะห่างระหว่างขอบของการ์ดและเนื้อหาให้สอดคล้องกันไม่ว่าจะใช้การ์ดที่ใดในความกว้างของวิวพอร์ตใดก็ตาม ไม่ต้องใช้แบบสอบถามสื่อ!
ความคิดอื่น? ใช้ cqw
หน่วยสำหรับขนาดตัวอักษรของเนื้อหาภายใน แล้วใช้การเติมเข้าไป em
หน่วย:
.card__inner {
font-size: 5cqw;
padding: 2em;
}
5cqw
เป็นค่าโดยพลการ - เป็นค่าเดียวที่ฉันตัดสิน ช่องว่างภายในนั้นยังคงเท่ากับ 10cqw
ตั้งแต่ em
หน่วยสัมพัทธ์กับ .card__inner
ขนาดตัวอักษร!
คุณจับที่? เดอะ 2em
มีความสัมพันธ์กับ 5cqw
ขนาดตัวอักษรที่ตั้งไว้ ในภาชนะเดียวกัน. ตู้คอนเทนเนอร์ทำงานแตกต่างจากที่เราคุ้นเคย เช่น em
หน่วยจะสัมพันธ์กับองค์ประกอบเดียวกัน font-size value
. แต่สิ่งที่ฉันสังเกตได้อย่างรวดเร็วคือหน่วยคิวรี่คอนเทนเนอร์เกี่ยวข้อง พาเรนต์ที่ใกล้ที่สุดที่เป็นคอนเทนเนอร์ด้วย.
ตัวอย่างเช่น 5cqw
ไม่ได้ปรับขนาดตาม .card
ความกว้างขององค์ประกอบในตัวอย่างนี้:
.card {
container: card / size;
container-name: card;
font-size: 5cqw;
}
แต่จะปรับขนาดตามพาเรนต์ที่ใกล้ที่สุดที่กำหนดเป็นคอนเทนเนอร์ นั่นเป็นเหตุผลที่ฉันตั้งค่า .card__inner
กระดาษห่อ
กรณีที่ 2: เค้าโครงสลับกัน
ฉันต้องการส่วนประกอบการ์ดอื่นในโครงการอื่น ครั้งนี้ ฉันต้องการการ์ดเพื่อเปลี่ยนจากเลย์เอาต์แนวนอนเป็นเลย์เอาต์แนวตั้ง... จากนั้นกลับไปเป็นแนวนอน และกลับไปเป็นแนวตั้งอีกครั้งเมื่อหน้าจอเล็กลง
ฉันทำงานสกปรกในการทำให้ส่วนประกอบนี้เป็นแนวตั้งที่ช่วงวิวพอร์ตเฉพาะสองช่วงนั้น (ตะโกนออกไปที่ ไวยากรณ์ช่วงแบบสอบถามสื่อใหม่!) แต่ปัญหาก็คือว่ามันจะถูกล็อคไปยังคำสั่งสื่อที่ตั้งค่าไว้ พาเรนต์ของมัน และสิ่งอื่นๆ ที่อาจตอบสนองต่อความกว้างของวิวพอร์ต เราต้องการบางสิ่งที่ใช้งานได้ในทุกสภาวะโดยไม่ต้องกังวลว่าเนื้อหาจะเสียหายตรงไหน!
ข้อความค้นหาคอนเทนเนอร์จะทำให้สิ่งนี้ง่ายขึ้น ต้องขอบคุณ @container
กฎ:
.info-card {
container-type: inline-size;
container-name: info-card;
}
@container info-card (max-width: 500px) {
.info-card__inner {
flex-direction: column;
}
}
หนึ่งคำค้นหา ความลื่นไหลไม่สิ้นสุด:
แต่เดี๋ยวก่อน! มีบางอย่างที่คุณอาจต้องระวัง โดยเฉพาะอย่างยิ่ง อาจเป็นเรื่องยากที่จะใช้คิวรีคอนเทนเนอร์เช่นนี้ภายในระบบการออกแบบที่ใช้อุปกรณ์ประกอบฉาก ตัวอย่างเช่นสิ่งนี้ .info-card
คอมโพเนนต์อาจมีส่วนประกอบย่อยที่อาศัยอุปกรณ์ประกอบฉากเพื่อเปลี่ยนรูปลักษณ์
ทำไมเป็นเรื่องใหญ่? เลย์เอาต์แนวตั้งของการ์ดอาจต้องใช้สไตล์อื่น แต่คุณไม่สามารถเปลี่ยนพร็อพ JavaScript ด้วย CSS ด้วยเหตุนี้ คุณจึงเสี่ยงที่จะทำซ้ำสไตล์ที่ต้องการ ฉันได้สัมผัสกับสิ่งนี้และ วิธีแก้ไขในบทความอื่น. หากคุณจำเป็นต้องใช้ข้อความค้นหาในคอนเทนเนอร์สำหรับการจัดรูปแบบจำนวนมาก คุณอาจต้องยึดระบบการออกแบบทั้งหมดของคุณโดยอ้างอิงจากสิ่งเหล่านั้น แทนที่จะพยายามยัดเยียดให้พวกเขาเข้าสู่ระบบการออกแบบที่มีอยู่ซึ่งหนักไปที่ข้อความค้นหาสื่อ
กรณีที่ 3: จังหวะ SVG
นี่เป็นอีกรูปแบบหนึ่งที่ฉันเคยใช้บ่อยมาก ซึ่งการสอบถามขนาดคอนเทนเนอร์อาจส่งผลให้ผลิตภัณฑ์มีความสวยงามมากขึ้น สมมติว่าคุณมีไอคอนที่ถูกล็อคด้วยหัวเรื่อง:
Heading
ค่อนข้างตรงไปตรงมาในการปรับขนาดไอคอนด้วยขนาดของชื่อเรื่อง แม้จะไม่มีคำค้นหาจากสื่อก็ตาม ปัญหาคือว่า SVG ของ stroke-width
อาจบางเกินไปที่จะสังเกตได้ดีในขนาดที่เล็กกว่า และอาจดึงดูดความสนใจมากเกินไปด้วยระยะชักที่หนาเป็นพิเศษในขนาดที่ใหญ่ขึ้น
ฉันต้องสร้างและใช้คลาสกับแต่ละอินสแตนซ์ของไอคอนเพื่อกำหนดขนาดและความกว้างของเส้นขีด ไม่เป็นไรถ้าไอคอนอยู่ถัดจากหัวข้อที่มีสไตล์ด้วยขนาดตัวอักษรคงที่ ฉันเดาว่ามันไม่ค่อยดีนักเมื่อทำงานกับประเภทของเหลวที่เปลี่ยนแปลงตลอดเวลา
ขนาดแบบอักษรของส่วนหัวอาจขึ้นอยู่กับความกว้างของวิวพอร์ต ดังนั้นไอคอน SVG จึงจำเป็นต้องปรับตามตำแหน่งที่เส้นขีดใช้งานได้ในทุกขนาด คุณสามารถสร้างความกว้างของเส้นขีดให้สัมพันธ์กับส่วนหัวได้ font-size
โดยตั้งค่าเป็น em
หน่วย แต่ถ้าคุณมีชุดของขนาดสโตรกที่คุณต้องยึดไว้ วิธีนี้จะไม่ได้ผลเพราะมิฉะนั้นจะสเกลเป็นเส้นตรง — ไม่มีทางที่จะปรับให้เป็นขนาดเฉพาะเจาะจงได้ stroke-width
ค่าที่จุดใดจุดหนึ่งโดยไม่ต้องอาศัยการสืบค้นสื่อบนความกว้างของวิวพอร์ต
แต่นี่คือสิ่งที่ฉันจะทำหากฉันมีคอนเทนเนอร์การค้นหาที่หรูหราในเวลานั้น:
.icon {
container: icon / size;
width: 1em;
height: 1em;
}
.icon svg {
width: 100%;
height: 100%;
fill: none;
stroke: #ccc;
stroke-width: 0.8;
}
@container icon (max-width: 70px) {
.icon svg {
stroke-width: 1.5;
}
}
@container icon (max-width: 35px) {
.icon svg {
stroke-width: 3;
}
}
เปรียบเทียบการใช้งานและดูว่าคอนเทนเนอร์คิวรีเวอร์ชันสแน็ปจังหวะของ SVG เป็นความกว้างเฉพาะที่ฉันต้องการตามความกว้างของคอนเทนเนอร์อย่างไร
โบนัส: แบบสอบถามขนาดคอนเทนเนอร์ประเภทอื่น
ตกลง ดังนั้นฉันไม่ได้เจอสิ่งนี้ในโครงการจริง แต่ในขณะที่ฉันค้นหาข้อมูลเกี่ยวกับการค้นหาคอนเทนเนอร์ ฉันสังเกตเห็นว่ามีสิ่งเพิ่มเติมที่เราสามารถสอบถามเกี่ยวกับคอนเทนเนอร์ที่เกี่ยวข้องกับขนาดหรือมิติทางกายภาพของคอนเทนเนอร์
ตัวอย่างส่วนใหญ่ที่ฉันเคยเห็นค้นหา width
, max-width
และ min-width
, height
, block-size
และ inline-size
อย่างที่ฉันได้ทำมาตลอดบทความนี้
@container info-card (max-width: 500px) {
.info-card__inner {
flex-direction: column;
}
}
แต่ MDN สรุปอีกสองสิ่ง เราสามารถสอบถามกับ หนึ่งคือ orientation
ซึ่งเหมาะสมอย่างยิ่งเพราะเราใช้มันตลอดเวลาในการสืบค้นสื่อ ไม่ต่างอะไรกับข้อความค้นหาคอนเทนเนอร์:
@media screen (orientation: landscape) {
.info-card__inner {
/* Style away! */
}
}
@container info-card (orientation: landscape) {
.info-card__inner {
/* Style away! */
}
}
อื่น ๆ? มันคือ aspect-ratio
, เชื่อหรือไม่:
@container info-card (aspect-ratio: 3/2) {
.info-card__inner {
/* Style away! */
}
}
นี่คือตัวอย่างที่แก้ไขได้เพื่อทดลองกับทั้งสองตัวอย่าง:
ฉันยังไม่พบกรณีการใช้งานที่ดีสำหรับสิ่งเหล่านี้ หากคุณมีไอเดียหรือรู้สึกว่าสิ่งนี้สามารถช่วยคุณได้ในโครงการของคุณ โปรดแจ้งให้เราทราบในความคิดเห็น!