สรุปไวๆ
- เราสามารถใช้ subgrid เพื่อสร้าง card ที่มี layout ที่สวยและ flexible ตามเนื้อหาได้ โดย
- เซ็ท layout ของเนื้อหาการ์ด ที่ parent ของการ์ด
- เซ็ท การ์ดแต่ละใบให้ใช้ layout เดียวกัน
- ลองดูตัวอย่างการ์ดที่ทำเสร็จแล้วได้ที่ท้ายบทความ
…
🤔 โจทย์: เราอยากออกแบบ card ที่อ่านง่ายและดูดี แต่เราควบคุมความยาวของเนื้อหาไม่ได้
ในเว็บทั่วไป เรามักใช้ UI pattern ที่เรียกว่า card (การ์ด) กันบ่อยๆ
ซึ่งมักมีรูป + คำอธิบาย + call to action เล็กๆน้อย
โดยโจทย์ในการออกแบบ (และ acceptance criteria ในการโค้ด) มักจะเป็น
-
section ในการ์ดจะต้อง align กัน → เพื่อให้ดูสวย และง่ายที่จะเปรียบเทียบข้อมูลประเภทเดียวกัน
-
layout จะต้อง flexible ตามเนื้อหาที่ใส่เข้าไป → เพื่อรองรับเนื้อหาที่อาจจะสั้นยาวไม่เท่ากัน
ในบทความนี้ เราจะใช้ subgrid
มาแก้โจทย์ 2 ข้อนี้กัน
…
มี alternative solution อื่นๆด้วย เช่น Truncate หรือ Fix บรรทัด
นอกจาก subgrid
แล้ว จริงๆแล้วยังมีท่าอื่นๆที่ใช้ได้ ซึ่งอาจเหมาะกับบางบริบท เช่น
1. การทำ Truncate (ตัดบรรทัดด้วย …)
คือ ทำให้ layout มันดูเรียงกันสวยงาม โดยตัดเนื้อหาทิ้งไปถ้ายาวเกิน
ถ้าเนื้อหาไม่ได้สำคัญมาก อาจะใช้วิธีนี้ได้
แต่ถ้าเนื้อหาสำคัญ เราควรทำให้เนื้อหาครบถ้วน แล้วปรับ layout ตามเนื้อหาดีกว่า (function before form)
2. การ Fix บรรทัดไว้เลย
คือ fix ความสูงไว้เลย (เช่น แต่ละเนื้อหาจะสูง 2 บรรทัด)
วิธีนี้จะรอดได้ในบาง layout เช่น เวลามีเนื้อหามันสูงๆต่ำๆผสมกัน
แต่ถ้าเมื่อไร การ์ดมีเนื้อหามันน้อยๆ มันจะเกิดช่องว่างที่กว้างเกิน
…
📐 วิธีการสร้างการ์ดด้วย subgrid
subgrid
เป็นค่า css ที่ได้รับการซัพพอร์ทใน browser ทั่วๆไปเรียบร้อย (เช็คได้ที่ Can I use)
หลักการของ subgrid คือ: ทำให้ element ต่างๆ ใช้ grid ร่วมกัน
ในกรณีนี้คือ ทำให้การ์ดแต่ละใบ (ถึงแม้จะเป็นคนละ element กัน) ใช้ grid ร่วมกันได้
โดย grid จะถูกเซ็ทที่ parent ของ element เหล่านั้น
1. ใส่ template ให้ parent เพื่อกำหนดลักษณะของ grid ที่จะใช้ร่วมกัน
.container {
grid-template-rows: repeat(6, auto);
}
อันนี้คือเราตั้งว่า: ในแต่ละการ์ดที่อยู่ใน .container
→ เราจะให้มันมี template แบบ 6 แถวเรียงกันลงมา, ซึ่งแต่ละแถวจะยืดยุ่นได้แบบ auto
ที่เราตั้งให้เป็น 6 แถวก็เพราะ เรามี 6 elements อยู่ใน .card
แต่ละตัว → ซึ่งก็คือ รูป, ชื่อหนังสือ, คำอธิบาย, ราคา, เหมาะสำหรับ, ปุ่ม
แต่เราจะยังไม่เห็นการเปลี่ยนแปลง จนกว่าเราจะสั่งให้ .card
ใช้งาน template นี้
2. ใส่ subgrid ให้ลูกๆ บอกว่าทุก element จะผูกกัน
.card {
grid-template-rows: subgrid;
grid-row: span 6;
}
อันนี้เราสั่งให้ .card
ทำ 2 อย่าง
-
เราสั่งแต่ละการ์ดให้มันเป็น
subgrid
คือ ทำให้ทุกตัวอยู่บน template เดียวกัน (ซึ่งก็คือ template ที่เราเซ็ทไว้ที่.container
) -
เราสั่งให้แต่ละการ์ดยืดตัวให้ครอบคลุม template ทั้ง 6 แถว → ถ้าเราไม่เซ็ทอันนี้ element ทั้งหมดในการ์ดจะไปกระจุกรวมกันในแถวเดียว
เซ็ทแค่ 2 อย่างนี้ เราก็จะได้การ์ดสวยๆที่ยืดหยุ่นมาใช้ละ!
…
🖼️ ตัวอย่างการ์ดที่ layout สวยและยืดหยุ่นตามจำนวนเนื้อหา
ลองเล่นตัวอย่างข้างล่างนี้ได้ (ลองกดเพิ่ม/ลดเนื้อหา) หรือ resize หน้าจอดู
Story ที่เธอเขียนนั้น มี AC ให้ชั้นรึป่าว
เรื่องราวของ "อาจัย" BA สาวสวย ที่ย้ายมาทำงานในบริษัทใหม่เพราะอยากหาความมั่นคง แต่กลับได้เจอกับความรักแทน
ราคา
456 บาท
เหมาะสำหรับ
Business Analyst, Product Manger, คนทำเทคที่ตามหาความหมายในชีวิต
สนใจหนังสือเล่มนี้
Dev มือใหม่กะยัย QA ตัวร้าย
"เทรวิน" เป็นพึ่งหัดเขียนโปรแกรม แต่จะต้องมาทำงานกับ "บุษตา" QA + แฟนเก่าที่จับผิดเค้าได้ทุกครั้งเวลานอกลู่นอกทาง!
ราคา
235 บาท
เหมาะสำหรับ
Junior Dev, Junior QA
สนใจหนังสือเล่มนี้
…
🙇 สรุป
- เรามักต้องการให้ layout ของ product card มันสวย แต่มักเจอปัญหาที่เราคุมความยาวของเนื้อหาไม่ได้
- วิธีการแก้คือใช้ท่า
subgrid
โดยเซ็ท CSS ดังนี้:
.container {
grid-template-rows: repeat(6, auto);
}
.card {
grid-template-rows: subgrid;
grid-row: span 6;
}