รายการเพิ่มเติม

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 ของอุปกรณ์ จึงเลื่อนไปทางซ้ายและขวา

พร็อพเพอร์ตี้เชิงตรรกะสำหรับทิศทางการเลื่อน

Browser Support

  • Chrome: 135.
  • Edge: 135.
  • Firefox: 69.
  • Safari: not supported.

Source

พร็อพเพอร์ตี้ 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

Browser Support

  • Chrome: 61.
  • Edge: 79.
  • Firefox: 36.
  • Safari: 15.4.

Source

scroll-behavior ช่วยให้คุณเลือกใช้การเลื่อนที่เบราว์เซอร์ควบคุมไปยังองค์ประกอบได้ ซึ่งช่วยให้คุณระบุวิธีจัดการการนำทางในหน้า เช่น .scrollTo() หรือลิงก์

ซึ่งจะเป็นประโยชน์อย่างยิ่งเมื่อใช้ร่วมกับ prefers-reduced-motion เพื่อระบุลักษณะการเลื่อนตามค่ากําหนดของผู้ใช้

@media (prefers-reduced-motion: no-preference) {
  .scroll-view {
    scroll-behavior: auto;
  }
}

overscroll-behavior

Browser Support

  • Chrome: 63.
  • Edge: 18.
  • Firefox: 59.
  • Safari: 16.

Source

หากคุณเคยเลื่อนจนสุดการวางซ้อนแบบโมดอล แล้วเลื่อนต่อและทำให้หน้าด้านหลังการวางซ้อนเลื่อนตามไปด้วย นั่นคือการเชื่อมโยงการเลื่อนหรือการส่งต่อการเลื่อนไปยังคอนเทนเนอร์การเลื่อนระดับบนสุด พร็อพเพอร์ตี้ 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 รายการ คีย์เวิร์ดแรกใช้กับแกนใด

แนวนอน
🎉
แนวตั้ง
แทบทุกครั้งเมื่อส่งค่าแบบย่อ 2 ค่า ค่าแรกจะเป็นแนวนอน

แถบเลื่อนใช้พื้นที่ใดในรูปแบบกล่องเมื่อแสดงและอยู่ในบรรทัด

กล่องเนื้อหา
ลองอีกครั้งนะ
กล่องระยะห่างจากขอบ
แถบเลื่อนในโหมด overlay จะทับซ้อนกับระยะขอบ และเมื่ออยู่ในโหมด inline จะเพิ่มระยะขอบ
กล่องเส้นขอบ
ลองอีกครั้งนะ
กล่องขอบ
ลองอีกครั้งนะ

หากต้องการดักจับโมเมนตัมเพิ่มเติมจากการเลื่อนในโปรแกรมเลื่อนโดยนัยที่ซ้อนกัน คุณจะใช้พร็อพเพอร์ตี้ใด

scroll-behavior
ลองอีกครั้งนะ
scroll-hint
ลองอีกครั้งนะ
overscroll-behavior
การตั้งค่าพร็อพเพอร์ตี้นี้เป็น contain จะทำให้การเลื่อนติดอยู่
scroll-padding
ลองอีกครั้งนะ
overscroll-effect
ลองอีกครั้งนะ

ค่าใดที่ประกาศว่าคอนเทนเนอร์เลื่อนต้องหยุดที่องค์ประกอบที่สแนปได้หากเป็นไปได้

required
ผิด
mandatory
ถูกต้อง
0px
ผิด
proximity
ผิด

ค่าที่ใช้ได้สำหรับ scrollbar-width คืออะไร

5px
ผิด
thin
ถูกต้อง
medium
ผิด
none
ถูกต้อง

แหล่งข้อมูล

Overflow And Data Loss In CSS from Smashing Magazine