The CSS Podcast - 034: Overflow
เมื่อเนื้อหาขยายออกไปนอกเหนือจากองค์ประกอบหลัก คุณจะมีตัวเลือกมากมายในการจัดการ คุณสามารถเลื่อนเพื่อเพิ่มพื้นที่ คลิปขอบที่ล้นออกมา ระบุส่วนที่ถูกตัดออกด้วยเครื่องหมายจุดไข่ปลา และอื่นๆ อีกมากมาย การล้นเป็นสิ่งที่ควรพิจารณาเป็นพิเศษเมื่อพัฒนาแอปพลิเคชันสำหรับโทรศัพท์และหน้าจอหลายขนาด
CSS มีตัวเลือกการตัดข้อความ 2 แบบ ได้แก่ text-overflow
ซึ่งจะช่วยจัดการข้อความแต่ละบรรทัด และพร็อพเพอร์ตี้ overflow
ซึ่งจะช่วยควบคุมการล้นในรูปแบบกล่อง
ข้อความบรรทัดเดียวที่ยาวเกินไปพร้อม text-overflow
ใช้พร็อพเพอร์ตี้ text-overflow
ในองค์ประกอบที่มีโหนดข้อความ เช่น ย่อหน้า <p>
โดยจะระบุลักษณะที่ข้อความปรากฏเมื่อไม่พอดีกับพื้นที่ว่างขององค์ประกอบ ข้อความ HTML ทั้งหมดที่ดูได้ในหน้าเว็บจะอยู่ในโหนดข้อความ หากต้องการใช้ text-overflow
คุณต้องมีข้อความบรรทัดเดียวที่ไม่ได้ตัดขึ้นบรรทัดใหม่ ดังนั้นคุณต้องตั้งค่า overflow
เป็น hidden
และมีค่า white-space
ที่ป้องกันการตัดขึ้นบรรทัดใหม่ด้วย
p {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
การใช้พร็อพเพอร์ตี้การล้น
ระบบจะตั้งค่าพร็อพเพอร์ตี้การล้นในองค์ประกอบเพื่อควบคุมสิ่งที่เกิดขึ้นเมื่อองค์ประกอบย่อยต้องการพื้นที่มากกว่าที่องค์ประกอบมี ซึ่งอาจเป็นไปโดยเจตนา เช่น ในแผนที่แบบอินเทอร์แอกทีฟอย่าง Google Maps ที่ผู้ใช้เลื่อนดูรูปภาพขนาดใหญ่ที่ครอบตัดให้มีขนาดเฉพาะ หรืออาจเป็นการกระทำโดยไม่ตั้งใจ เช่น ในแอปพลิเคชันแชทที่ผู้ใช้พิมพ์ข้อความยาวๆ ซึ่งไม่พอดีกับบับเบิ้ลข้อความ
คุณสามารถพิจารณาการล้นได้ 2 ส่วน องค์ประกอบหลักมีพื้นที่ที่จำกัดอย่างแน่นหนาซึ่งจะไม่เปลี่ยนแปลง คุณสามารถคิดว่านี่คือหน้าต่าง องค์ประกอบย่อยคือเนื้อหาที่ต้องการพื้นที่เพิ่มเติมจากองค์ประกอบหลัก คุณสามารถคิดว่าสิ่งนี้คือสิ่งที่คุณมองผ่านหน้าต่าง การจัดการข้อความที่ล้นจะช่วยกำหนดวิธีที่หน้าต่างแสดงเนื้อหานี้
การเลื่อนในแกนแนวตั้งและแนวนอน
พร็อพเพอร์ตี้ overflow-y
จะควบคุมการล้นทางกายภาพตามแกนแนวตั้งของวิวพอร์ตอุปกรณ์ จึงเลื่อนขึ้นและลง
พร็อพเพอร์ตี้ overflow-x
จะควบคุมการล้นตามแกนแนวนอนของ Viewport ของอุปกรณ์ จึงเลื่อนไปทางซ้ายและขวา
พร็อพเพอร์ตี้เชิงตรรกะสำหรับทิศทางการเลื่อน
พร็อพเพอร์ตี้ overflow-inline
และ overflow-block
จะตั้งค่าการล้นตามทิศทางของเอกสารและโหมดการเขียน
overflow
ชวเลข
รูปแบบย่อ overflow
จะตั้งค่าทั้งสไตล์ overflow-x
และ overflow-y
ในบรรทัดเดียว
overflow: hidden scroll;
หากระบุคีย์เวิร์ด 2 รายการ คีย์เวิร์ดแรกจะมีผลกับ overflow-x
และคีย์เวิร์ดที่ 2 จะมีผลกับ overflow-y
ไม่เช่นนั้นทั้ง overflow-x
และ overflow-y
จะใช้ค่าเดียวกัน
ค่า
ดูรายละเอียดค่าและคีย์เวิร์ดที่ใช้ได้สำหรับพร็อพเพอร์ตี้ overflow
overflow: visible
(ค่าเริ่มต้น)- หากไม่ได้ตั้งค่าพร็อพเพอร์ตี้
overflow: visible
จะเป็นค่าเริ่มต้นสำหรับเว็บ วิธีนี้ช่วยให้มั่นใจได้ว่าจะไม่มีการซ่อนเนื้อหาโดยไม่ตั้งใจ และเป็นไปตามหลักการสำคัญของ "ไม่ซ่อนเนื้อหา" หรือ "เลย์เอาต์ที่ปลอดภัยของเลย์เอาต์ที่แม่นยำ" overflow: hidden
overflow: hidden
จะตัดเนื้อหาในทิศทางที่ระบุ และไม่มีแถบเลื่อนให้แสดงoverflow: scroll
overflow: scroll
จะเปิดใช้แถบเลื่อนเพื่อให้ผู้ใช้เลื่อนดูเนื้อหาได้ แม้ว่าเนื้อหาจะไม่ล้นออกมา แต่แถบเลื่อนจะยังคงปรากฏอยู่ วิธีนี้เป็นวิธีที่ดีในการลดการเปลี่ยนเลย์เอาต์ในอนาคตหากคอนเทนเนอร์อาจเลื่อนได้ในอนาคต เช่น ตามการปรับขนาด และเตรียมผู้ใช้ให้พร้อมสำหรับพื้นที่ที่เลื่อนได้overflow: clip
- เช่นเดียวกับ
overflow: hidden
เนื้อหาที่มีoverflow: clip
จะถูกตัดไปยังกล่องระยะเว้นขององค์ประกอบ ความแตกต่างระหว่างclip
กับhidden
คือคีย์เวิร์ดclip
จะห้ามการเลื่อนทั้งหมด รวมถึงการเลื่อนแบบเป็นโปรแกรมด้วย overflow: auto
- สุดท้ายคือค่าที่ใช้กันมากที่สุด
overflow: auto
ซึ่งจะเป็นไปตามค่ากำหนดของผู้ใช้และแสดงแถบเลื่อนหากจำเป็น แต่จะซ่อนแถบเลื่อนโดยค่าเริ่มต้น และให้ผู้ใช้และเบราว์เซอร์เป็นผู้รับผิดชอบในการเลื่อน
การเลื่อนและการล้น
overflow
ลักษณะการทำงานเหล่านี้หลายอย่างจะทำให้เกิดแถบเลื่อน แต่ก็มีลักษณะการทำงานและพร็อพเพอร์ตี้การเลื่อนบางอย่างที่ช่วยให้คุณควบคุมการเลื่อนในคอนเทนเนอร์ที่ล้นได้
การเลื่อนและความสามารถในการเข้าถึง
คุณต้องตรวจสอบว่าพื้นที่ที่เลื่อนได้ยอมรับโฟกัสเพื่อให้ผู้ใช้แป้นพิมพ์สามารถกด Tab ไปยังช่อง แล้วใช้แป้นลูกศรเพื่อเลื่อนได้
หากต้องการอนุญาตให้กล่องเลื่อนยอมรับโฟกัส ให้เพิ่ม tabindex="0"
ชื่อที่มีแอตทริบิวต์ aria-labelledby
และแอตทริบิวต์ role
ที่เหมาะสม เช่น
<div tabindex="0" role="region" aria-labelledby="id-of-descriptive-text">
content
</div>
จากนั้นจะใช้ CSS เพื่อระบุว่าช่องมีโฟกัสได้ โดยใช้พร็อพเพอร์ตี้ outline
เพื่อให้คำใบ้ด้วยภาพว่าตอนนี้ช่องจะเลื่อนได้
ในการใช้ CSS เพื่อบังคับใช้การช่วยเหลือพิเศษ Adrian Roselli แสดงให้เห็นว่า CSS ช่วยป้องกันการถดถอยของการช่วยเหลือพิเศษได้อย่างไร เช่น เปิดการเลื่อนและเพิ่มตัวบ่งชี้โฟกัสเฉพาะในกรณีที่ใช้แอตทริบิวต์ที่ถูกต้อง กฎต่อไปนี้จะทำให้ช่องเลื่อนได้ก็ต่อเมื่อมีแอตทริบิวต์ tabindex
, aria-labelledby
และ role
[role][aria-labelledby][tabindex] {
overflow: auto;
}
[role][aria-labelledby][tabindex]:focus {
outline: .1em solid blue;
}
การวางตำแหน่งแถบเลื่อนภายในรูปแบบกล่อง
แถบเลื่อนจะใช้พื้นที่ภายในกล่องระยะห่างจากขอบ และอาจแย่งพื้นที่หากเป็น inline
แต่ไม่ใช่ overlaid
โมดูลรูปแบบกล่องจะอธิบายแหล่งที่มาที่เป็นไปได้ของการเปลี่ยนแปลงเลย์เอาต์นี้เพิ่มเติม
root-scroller กับ implicit-scroller
คุณอาจสังเกตเห็นว่าแถบเลื่อนบางรายการมีลักษณะการทำงานแบบดึงเพื่อรีเฟรชและลักษณะการทำงานพิเศษอื่นๆ โดยเฉพาะเมื่อพัฒนาแอปพลิเคชันสำหรับอุปกรณ์เคลื่อนที่และแอปพลิเคชันแบบไฮบริด ลักษณะการเลื่อนนี้จะเกิดขึ้นในตัวเลื่อนรูท ในหน้าเว็บจะมีตัวเลื่อนรูทเพียงตัวเดียวเสมอ โดยค่าเริ่มต้น documentElement คือตัวเลื่อนรูทของหน้าเว็บ แต่การเปลี่ยนองค์ประกอบที่เป็นตัวเลื่อนรูทจะทำให้ใช้ลักษณะการทำงานพิเศษกับตัวเลื่อนอื่นๆ นอกเหนือจาก documentElement ได้ ซึ่งเราเรียกตัวเลื่อนใหม่นี้ว่าตัวเลื่อนรูทโดยนัย
หากต้องการสร้าง Scroller ระดับรูท คุณสามารถใช้สิ่งที่เรียกว่าการโปรโมต Scroller โดยวางคอนเทนเนอร์เป็นแบบคงที่ เพื่อให้ครอบคลุมทั้ง Viewport และมี z-index อยู่ด้านบนพร้อม Scroller ดูตัวอย่างการเลื่อนระดับรูทเทียบกับการเลื่อนโดยนัยที่ซ้อนกันที่นี่
เมื่อเทียบกับการเลื่อนตัวเลื่อนโดยนัยที่ไม่มีลักษณะการเลื่อนที่ปรับปรุงแล้ว
การจัดรูปแบบแถบเลื่อน
คุณจัดรูปแบบแถบเลื่อนให้เข้ากับการออกแบบเว็บไซต์ได้ scrollbar-color
กำหนดสีให้กับแถบเลื่อนและรางเลื่อน
หากต้องการเปลี่ยนความกว้างของแถบเลื่อน ให้ใช้ scrollbar-width
คุณไม่สามารถตั้งค่านี้เป็นความยาวที่กำหนดเองได้ แต่สามารถระบุว่าต้องการthin
แถบเลื่อนหรือnone
scroll-behavior
scroll-behavior
ช่วยให้คุณเลือกใช้การเลื่อนที่เบราว์เซอร์ควบคุมไปยังองค์ประกอบได้ ซึ่งช่วยให้คุณระบุวิธีจัดการการนำทางในหน้า เช่น .scrollTo()
หรือลิงก์
ซึ่งจะเป็นประโยชน์อย่างยิ่งเมื่อใช้ร่วมกับ prefers-reduced-motion เพื่อระบุลักษณะการเลื่อนตามค่ากําหนดของผู้ใช้
@media (prefers-reduced-motion: no-preference) {
.scroll-view {
scroll-behavior: auto;
}
}
overscroll-behavior
หากคุณเคยเลื่อนจนสุดการวางซ้อนแบบโมดอล แล้วเลื่อนต่อและทำให้หน้าด้านหลังการวางซ้อนเลื่อนตามไปด้วย นั่นคือการเชื่อมโยงการเลื่อนหรือการส่งต่อการเลื่อนไปยังคอนเทนเนอร์การเลื่อนระดับบนสุด พร็อพเพอร์ตี้ overscroll-behavior
ช่วยให้คุณป้องกันไม่ให้การเลื่อนที่ล้นออกมาไหลไปยังคอนเทนเนอร์ระดับบน (เรียกว่าการเชื่อมโยงการเลื่อน)
การสแนปการเลื่อน
โดยทั่วไปแล้วการเลื่อนจะราบรื่น ทำให้คุณวางตำแหน่งเนื้อหาภายในวิวพอร์ตที่เลื่อนได้ได้ทุกที่ที่ต้องการ สำหรับดีไซน์บางอย่าง เช่น แกลเลอรีรูปภาพหรือเนื้อหาที่จำลองหน้าหรือสไลด์ คุณอาจต้องการให้เนื้อหาติดกับ Scrollport
การตั้งค่าคอนเทนเนอร์การเลื่อน
หากต้องการเปิดใช้การเลื่อนแบบสแนป ให้เพิ่ม scroll-snap-type
ลงในคอนเทนเนอร์การเลื่อน ก่อนอื่นคุณต้องกำหนดแกนที่จะเกิดการเลื่อนแบบสแนป ซึ่งอาจเป็นพร็อพเพอร์ตี้เชิงตรรกะ (block
หรือ inline
) พร็อพเพอร์ตี้ทางกายภาพ (x
หรือ y
) หรือ both
นอกจากนี้ คุณยังกำหนดได้ว่าการสแนปการเลื่อนควรเข้มงวดเพียงใด ความเข้มงวดเริ่มต้นคือ proximity
ซึ่งหมายความว่าคอนเทนเนอร์เลื่อนจะพยายามสแนปหากเป็นไปได้ คุณยังตั้งค่าความเข้มงวดเป็น mandatory
เพื่อให้มั่นใจว่าคอนเทนเนอร์เลื่อนจะสแนปเสมอได้ด้วย
.scroll-container {
scroll-snap-type: block mandatory;
}
การเลื่อนแบบสแนปจะจัดแนวองค์ประกอบภายในขอบเขตทั้งหมดของคอนเทนเนอร์เลื่อน แต่จะเกิดอะไรขึ้นหากมองไม่เห็นคอนเทนเนอร์เลื่อนบางส่วน เช่น คุณอาจมีส่วนหัวแบบคงที่ที่ซ้อนทับส่วนหนึ่งของคอนเทนเนอร์เลื่อน คุณตั้งค่า scroll-padding
เพื่อช่วยจัดแนวองค์ประกอบที่สแนปกับส่วนที่มองเห็นได้ของคอนเทนเนอร์ที่เลื่อนได้
การควบคุมองค์ประกอบที่สแนปได้
หากต้องการทำให้องค์ประกอบสแนปได้ ให้ตั้งค่าพร็อพเพอร์ตี้ scroll-snap-align
เป็น start
, end
หรือ center
หากทิศทางการเลื่อนสแนปเป็น both
คุณจะตั้งค่าได้ 2 ค่า ซึ่งจะกำหนดว่าขอบขององค์ประกอบจะจัดแนวกับขอบของ Scrollport หรือจะอยู่ตรงกลาง
คุณปรับระยะห่างรอบขอบขององค์ประกอบที่สแนปได้โดยใช้ scroll-margin
ดังนี้
scroll-margin
ยังใช้เพื่อตั้งค่าระยะห่างเมื่อเลื่อนไปยังองค์ประกอบด้วย
หากต้องการให้การเลื่อนติดหนึบมากขึ้น คุณสามารถเพิ่ม scroll-snap-stop: always
ลงในรายการในคอนเทนเนอร์เลื่อนได้ แต่ไม่ได้ป้องกันไม่ให้คุณเลื่อนผ่านหลายรายการในการเลื่อนครั้งเดียว หากคุณหยุดการเลื่อนในลักษณะที่การเลื่อนจะดำเนินต่อไปด้วยแรงเฉื่อย การเลื่อนจะสิ้นสุดที่ตำแหน่งสแนปถัดไปแทนที่จะเลื่อนผ่านไป
ทดสอบความเข้าใจ
ข้อความล้นและองค์ประกอบล้นเหมือนกันไหม
overflow
พร็อพเพอร์ตี้ยอมรับคีย์เวิร์ด 2 รายการ คีย์เวิร์ดแรกใช้กับแกนใด
แถบเลื่อนใช้พื้นที่ใดในรูปแบบกล่องเมื่อแสดงและอยู่ในบรรทัด
overlay
จะทับซ้อนกับระยะขอบ และเมื่ออยู่ในโหมด inline
จะเพิ่มระยะขอบหากต้องการดักจับโมเมนตัมเพิ่มเติมจากการเลื่อนในโปรแกรมเลื่อนโดยนัยที่ซ้อนกัน คุณจะใช้พร็อพเพอร์ตี้ใด
scroll-behavior
scroll-hint
overscroll-behavior
contain
จะทำให้การเลื่อนติดอยู่scroll-padding
overscroll-effect
ค่าใดที่ประกาศว่าคอนเทนเนอร์เลื่อนต้องหยุดที่องค์ประกอบที่สแนปได้หากเป็นไปได้
required
mandatory
0px
proximity
ค่าที่ใช้ได้สำหรับ scrollbar-width
คืออะไร
5px
thin
medium
none