ภาพรวม
การ์ดจะจัดกลุ่มเนื้อหาที่เกี่ยวข้อง 1 รายการหรือตัวเลือก 1 รายการ ซึ่งเป็นรูปแบบภาพ ไม่ใช่โมเดลความหมายหรือการโต้ตอบที่ตายตัว ดังนั้นให้คงความหมายของเนื้อหาไว้และใช้การโต้ตอบแบบเนทีฟที่ตรงกับวัตถุประสงค์
หลักเกณฑ์
เลือกความหมายของเนื้อหาและการโต้ตอบแยกกัน ดังนี้
- ใช้
<article>เป็นรูทของการ์ด ไม่ว่าจะลิงก์ไปยังปลายทางหรือไม่ก็ตาม - ใช้ลิงก์แบบเนทีฟสำหรับการนำทาง เมื่อการ์ดทั้งใบเป็นปลายทางเดียว ลิงก์เดียวอาจรวม
<article>ไว้เฉพาะในกรณีที่การ์ดไม่มีองค์ประกอบแบบอินเทอร์แอกทีฟอื่นๆ (a,button,input,select,textarea) - เก็บลิงก์และปุ่มสำหรับการดำเนินการอิสระไว้เป็นตัวควบคุมแบบเนทีฟแยกต่างหาก
- ใช้ปุ่มตัวเลือกหรือช่องทำเครื่องหมายที่มี
<label>ที่เชื่อมโยง หรือoptionใน<select>แบบเนทีฟ เมื่อการ์ดเป็นตัวเลือก
จัดเรียงสื่อ ชื่อ เนื้อหาสนับสนุน และการดำเนินการตามลำดับแหล่งที่มาที่มีความหมาย อย่าใช้ CSS order เพื่อขัดแย้งกับลำดับดังกล่าว (ดูเลย์เอาต์ CSS และการออกแบบที่ปรับเปลี่ยนตามอุปกรณ์)
การใช้งาน
ใช้มาร์กอัปให้น้อยที่สุดและให้ตัวเลือก CSS จดจำแต่ละภูมิภาค เพื่อให้การ์ดแบบง่ายยังคงเรียบง่ายและ Rich Card ยังคงเป็นไปได้ การ์ดมีได้สูงสุด 4 ส่วนตามลำดับแหล่งที่มานี้ และสามารถละเว้นส่วนใดก็ได้ ภูมิภาคเป็นองค์ประกอบย่อยโดยตรงของการ์ด ไม่ได้จัดกลุ่มในองค์ประกอบ Wrapper เช่น .card__body ซึ่งจะป้องกันไม่ให้วางและจัดรูปแบบภูมิภาคตามตัวเลือก ขอบเขตที่มีองค์ประกอบเดียวคือองค์ประกอบนั้นเอง ไม่ได้รวมอยู่ด้วย โดยย่อหน้าเดียวคือ <p> ใช้ Wrapper เฉพาะเมื่อภูมิภาคมีองค์ประกอบหลายรายการ
- สื่อ:
<img>,<picture>,<video>หรือ<svg>เป็นองค์ประกอบย่อยแรก เพิ่มคลาส.mediaลงในเนื้อหา Hero ที่กำหนดเองซึ่งไม่ใช่องค์ประกอบใดองค์ประกอบหนึ่งข้างต้นเท่านั้น และอย่ารวม<img>ธรรมดาไว้ในองค์ประกอบ.media - ส่วนหัว: ส่วนหัวที่อยู่เดี่ยวๆ ใช้
<hgroup>เฉพาะเมื่อส่วนหัวมีคำบรรยายหรือแท็กไลน์ และใช้<header>เมื่อส่วนนั้นมีมากกว่าชื่อ เช่น ข้อมูลผู้เขียนหรือป้าย เมื่อการ์ดมีปลายทางหลัก ลิงก์จะอยู่ภายในส่วนหัว - เนื้อหา:
<p>,<ul>หรือ<dl>รายการเดียวที่แยกเป็นอิสระจากกัน เมื่อเนื้อหามีหลายองค์ประกอบ เช่น ย่อหน้าหลายย่อหน้า หรือย่อหน้าบวกกับรายการ ให้จัดกลุ่มไว้ใน<div>เดียวเพื่อให้พื้นที่เป็นรายการตารางกริดรายการเดียว - ส่วนท้าย:
<footer>ที่มีการดำเนินการแยกต่างหากเป็นลิงก์และปุ่มแบบเนทีฟ ลิงก์ "อ่านเพิ่มเติม" อาจใช้ URL ของลิงก์ส่วนหัวร่วมกัน แต่ให้ตั้งชื่อที่เข้าถึงได้ซึ่งสื่อความหมายและขึ้นต้นด้วยข้อความที่มองเห็นได้ โดยใช้ข้อความที่ซ่อนไว้ (เช่นRead more<span> about poached eggs</span>) เนื่องจากลิงก์ "อ่านเพิ่มเติม" ที่เหมือนกันจะทำให้เกิดความกำกวมในรายการลิงก์ของโปรแกรมอ่านหน้าจอ อย่าเพิ่มลิงก์ส่วนท้ายอื่นๆ ที่ซ้ำกับ URL ของส่วนหัว
การ์ดที่เรียบง่ายที่สุดคือ <article> ที่มีส่วนหัวและย่อหน้า เลือกลิงก์และรูปแบบการดำเนินการที่ตรงกับลักษณะการทำงานของการ์ด โปรดดูรูปแบบการโต้ตอบ
สำหรับรูปภาพหรือวิดีโอการ์ดที่ควรเติมเต็มพื้นที่อัตราส่วนคงที่ ให้ตั้งค่า aspect-ratio และ object-fit: cover ใน <img> หรือ <video> เอง เพื่อให้เติมเต็มพื้นที่โดยไม่บิดเบี้ยว (อาจมีการครอบตัด) ใช้ aspect-ratio ของคอนเทนเนอร์ .media สำหรับเนื้อหา Hero อื่นๆ เท่านั้น หรือคงสัดส่วนที่แท้จริงของสื่อไว้ ใส่ข้อความแสดงแทนที่เหมาะสมให้กับรูปภาพที่ให้ข้อมูล และใช้ alt="" สำหรับรูปภาพเพื่อการตกแต่ง
ปรับให้เข้ากับพื้นที่ว่าง
จัดเลย์เอาต์ตามพื้นที่ว่างของการ์ด ไม่ใช่วิวพอร์ต หากต้องการปรับองค์ประกอบย่อยของการ์ด (สื่อ ข้อความ การดำเนินการ) ให้กำหนดการ์ดเป็นคอนเทนเนอร์ขนาด (container-type: inline-size) และเขียนกฎ @container สำหรับองค์ประกอบย่อยของการ์ด หลีกเลี่ยงการปรับขนาดจากตารางกริดหรือรายการหลัก เนื่องจากความกว้างจริงของการ์ดอาจขึ้นอยู่กับจำนวนคอลัมน์ ช่องว่าง และอื่นๆ ซึ่งทำให้เบรกพอยต์ที่อิงตามหลักมีสัญญาณรบกวน
ในคอนเทนเนอร์แคบ ให้วางซ้อนภูมิภาคตามลำดับแหล่งที่มา ในคอนเทนเนอร์แบบกว้าง ให้วางสื่อในคอลัมน์ด้านข้างถัดจากส่วนอื่นๆ แต่เฉพาะสำหรับการ์ดที่มีสื่อเท่านั้น โดยกำหนดขอบเขตของกฎเหล่านั้นด้วย :has() ในองค์ประกอบย่อยของสื่อ (เช่น .card:has(> img)) เพื่อไม่ให้คำจำกัดความของคอลัมน์และการวาง grid-column มีผลกับการ์ดที่ไม่มีสื่อ การ์ดที่ไม่มีสื่อจะยังคงเป็นคอลัมน์เดียวในทุกความกว้าง และต้องไม่จองคอลัมน์สื่อที่ว่างเปล่า
จัดตำแหน่งการ์ดในตารางกริด
เมื่อการ์ดในแถวควรใช้ความสูงของภูมิภาคร่วมกัน ให้ใช้ subgrid: ทำให้การ์ดแต่ละใบครอบคลุมแทร็กแถวที่ใช้ร่วมกัน 4 แทร็ก (สื่อ, ส่วนหัว, เนื้อหา, ส่วนท้าย) และวางภูมิภาคตามตัวเลือกองค์ประกอบ โดยถือว่าทุกอย่างที่ไม่ใช่สื่อ ส่วนหัว หรือ <footer> เป็นเนื้อหา การ์ดที่ละเว้นขอบเขตจะปล่อยให้แทร็กว่างเปล่า ดังนั้นขอบเขตที่เหลือจะยังคงเรียงตามการ์ดที่อยู่ติดกัน แต่ละแทร็กจะมีรายการตารางกริด 1 รายการ ดังนั้นให้รวมขอบเขตเนื้อหาไว้ใน <div> เฉพาะเมื่อมีองค์ประกอบมากกว่า 1 รายการและการ์ดใช้แทร็กร่วมกัน การ์ดที่ไม่ได้จัดแนวกับองค์ประกอบข้างเคียงไม่จำเป็นต้องมี Wrapper หรือ Subgrid
รูปแบบการโต้ตอบ
การ์ดเนื้อหา
ใช้ <article> เป็นรูทของการ์ด เก็บลิงก์และปุ่มไว้เป็นตัวควบคุมเนทีฟแยกต่างหาก
การ์ดปลายทางเดียว
เมื่อการ์ดทั้งใบเป็นปลายทางเดียวและไม่มีการดำเนินการแยกต่างหาก ให้ใช้ลิงก์เนทีฟ 1 รายการ ลิงก์สามารถรวม <article> ได้ อย่าฝังลิงก์ ปุ่ม หรือตัวควบคุมแบบฟอร์มอื่นๆ ไว้ในลิงก์ และใช้ข้อความ "อ่านเพิ่มเติม" เป็น <p> หรือ <span> ธรรมดา เนื่องจากชื่อที่เข้าถึงได้ของลิงก์คือข้อความทั้งหมดของการ์ด โปรดทำให้เนื้อหาสั้น หากการ์ดมีข้อความหรือการดำเนินการอื่นๆ จำนวนมาก ให้ใช้รูปแบบลิงก์แบบยืดด้านล่างเพื่อให้เฉพาะส่วนหัวเป็นลิงก์
<a href="/recipes/poached-eggs">
<article class="card">
<h3>Poached eggs</h3>
<p>Two poached eggs served on toasted sourdough.</p>
</article>
</a>
การ์ดที่คลิกได้ซึ่งมีการดำเนินการแยกกัน
หากการคลิกการ์ดทริกเกอร์การดำเนินการแทนการไปยังส่วนต่างๆ ให้ใช้ <button> แทนลิงก์
เมื่อการ์ดเนื้อหาลิงก์ไปยังปลายทางหลัก มีองค์ประกอบแบบอินเทอร์แอกทีฟอื่นๆ และต้องคลิกได้ทั้งหมด ให้ทำดังนี้
- ใช้การเลือกรับแบบครั้งเดียวในลิงก์หลัก โดยใส่
.card-linkในลิงก์เดียวต่อการ์ด (ลิงก์ส่วนหัว) ส่วนท้ายและลิงก์อื่นๆ จะไม่ได้รับคลาสนี้ ไม่เช่นนั้นแต่ละรายการจะขยายการวางซ้อนของตัวเอง และรายการสุดท้ายจะครอบคลุมทั้งการ์ด - ลิงก์ชื่อและขยายพื้นที่การกดตัวชี้ให้ครอบคลุมการ์ดด้วย
::after
.card:has(a.card-link) {
position: relative;
}
.card a.card-link::after {
content: "";
position: absolute;
inset: 0;
}
- ยกระดับองค์ประกอบแบบอินเทอร์แอกทีฟด้วย
position: relative; z-index: 1เพื่อให้ยังคงใช้งานได้ กำหนดเป้าหมายประเภทขององค์ประกอบ (เช่นa, button) แทนที่จะกำหนดให้เลือกใช้ผ่านคลาส - อย่าใช้
z-indexกับคอนเทนเนอร์ทั้งหมด เนื่องจากจะทำให้คอนเทนเนอร์จับเหตุการณ์เคอร์เซอร์ที่ไม่ทำให้เกิดการดำเนินการใดๆ
.card:has(a.card-link) {
/* Keep other interactive elements above the overlay */
a:not(.card-link), button, input, x-button {
position: relative;
z-index: 1;
}
}
- จัดรูปแบบการ์ดเมื่อวางเมาส์เหนือ/โฟกัส แทนที่จะเป็นลิงก์ที่ยืดออก
.card {
a.card-link {
&:focus-visible {
outline: none; /* Draw it on the card instead */
}
}
&:has(a.card-link:focus-visible) {
/* Focus ring */
}
&:has(a.card-link:hover) {
/* Hover styles */
}
}
การ์ดตัวเลือก
สำหรับการ์ดที่แสดงตัวเลือกที่กำหนดไว้ล่วงหน้า ให้ใช้ <label class="card"> โดยมีช่องทำเครื่องหมายหรือปุ่มตัวเลือกเป็นรายการย่อยโดยตรง
จัดรูปแบบการ์ดที่เลือกด้วย :has(:checked) อย่าเปลี่ยนพร็อพเพอร์ตี้ที่ส่งผลต่อเลย์เอาต์ เช่น border-width, padding หรือ font-weight ในการเลือก เนื่องจากจะทำให้การ์ดและองค์ประกอบที่อยู่ติดกันขยับ ให้เน้นด้วย outline, box-shadow หรือเส้นขอบโปร่งใสที่เปลี่ยนเฉพาะสีเท่านั้น
.card {
border: 2px solid transparent;
&:has(> :checked) {
border-color: var(--accent);
}
}
ช่องทำเครื่องหมายหรือปุ่มตัวเลือกที่มองเห็นได้เป็นตัวบ่งชี้การเลือกที่ไม่ใช่สีอยู่แล้ว ดังนั้นการเปลี่ยนสีเพียงอย่างเดียวจึงเพียงพอ หากตัวควบคุมถูกซ่อนไว้ (ให้ตัวควบคุมยังคงโฟกัสได้และอยู่ในแผนผังการช่วยเหลือพิเศษ โดยไม่ใช้ display: none) ให้เพิ่มตัวบ่งชี้ที่ไม่ใช่สีซึ่งไม่ส่งผลต่อเลย์เอาต์ เช่น ไอคอนเครื่องหมายถูกหรือ outline ที่หนาขึ้น
เมื่อตัวเลือกอยู่ในเครื่องมือเลือกแบบเลื่อนลงซึ่งมีตัวเลือกที่จัดวางเป็นการ์ด ให้ใช้ <select> แบบเนทีฟที่มี appearance: base-select และจัดสไตล์องค์ประกอบ ::picker(select) และ <option> แทนที่จะแทนที่การเลือกด้วยการ์ด <div> โปรดดูรายละเอียดเพิ่มเติมและทางเลือกอื่นๆ ที่หัวข้อเลย์เอาต์เครื่องมือเลือกแบบกำหนดเอง