ข้อความ

กล่องโต้ตอบโมดัลคือกล่องป๊อปอัปประเภทพิเศษที่ขัดจังหวะผู้ใช้ในหน้าเว็บ แม้ว่าจะมีกรณีการใช้งานที่เหมาะสมสำหรับการแสดงกล่องโต้ตอบแบบป๊อปอัป แต่คุณควรพิจารณาอย่างรอบคอบก่อนที่จะเพิ่มกล่องโต้ตอบดังกล่าว กล่องโต้ตอบโมดัลจะบังคับให้ผู้ใช้โฟกัสที่เนื้อหาที่เฉพาะเจาะจงและละเว้นส่วนที่เหลือของหน้าชั่วคราว

กล่องโต้ตอบอาจเป็นดังนี้

  • โมดัล: ผู้ใช้จะโต้ตอบได้เฉพาะกับเนื้อหาภายในกล่องโต้ตอบเท่านั้น กล่องโต้ตอบโมดัลจะแสดงที่ด้านบนของเนื้อหาในหน้าเว็บ หน้าเว็บได้รับการตั้งค่าเป็นเฉื่อย และโดยค่าเริ่มต้นจะถูกบดบังด้วยฉากหลังกึ่งโปร่งใส
  • ไม่ใช่โมดัล: ผู้ใช้สามารถโต้ตอบกับเนื้อหาภายนอกกล่องโต้ตอบได้

องค์ประกอบ <dialog> ของ HTML เชิงความหมายเพื่อสร้างกล่องโต้ตอบมาพร้อมกับความหมาย การโต้ตอบกับแป้นพิมพ์ รวมถึงพร็อพเพอร์ตี้และเมธอดทั้งหมดของอินเทอร์เฟซ HTMLDialogElement

ดูตัวอย่างของโมดัล <dialog> คลิกเปิดกล่องโต้ตอบโมดัล เมื่อเปิดแล้ว คุณจะปิดกล่องโต้ตอบได้ 3 วิธี ได้แก่ ปุ่ม Escape, การส่งแบบฟอร์มที่มีปุ่มซึ่งตั้งค่า formmethod="dialog" ไว้ (หรือหากแบบฟอร์มนั้นตั้งค่า method="dialog" ไว้) และเมธอด HTMLDialogElement.close()

HTMLDialogElement มีเมธอดหลัก 3 รายการ พร้อมกับเมธอดทั้งหมดที่รับค่ามาจาก HTMLElement

dialog.show() /* opens the dialog */
dialog.showModal() /* opens the dialog as a modal */
dialog.close() /* closes the dialog */

เนื่องจาก <dialog> นี้เปิดด้วยเมธอด HTMLDialogElement.showModal() จึงเป็นกล่องโต้ตอบโมดัล การเปิดกล่องโต้ตอบโมดัลจะปิดใช้งานและบดบังทุกอย่างที่ไม่ใช่กล่องโต้ตอบนั้น เมื่อคุณวางเมาส์เหนือ UI นอกกล่องโต้ตอบ องค์ประกอบทั้งหมดจะทำงานเหมือนกับว่ามีการตั้งค่า pointer-events: none; ไว้ แม้แต่ปุ่มที่เปิดกล่องโต้ตอบก็จะไม่ตอบสนองต่อการโต้ตอบ

เมื่อกล่องโต้ตอบเปิดขึ้น โฟกัสจะย้ายไปที่กล่องโต้ตอบ ระบบจะตั้งโฟกัสที่องค์ประกอบแรกในลำดับการไปยังส่วนต่างๆ ด้วยแป้นพิมพ์ตามลำดับภายในกล่องโต้ตอบนั้น หากคุณกดปุ่ม tab ซ้ำๆ เฉพาะเนื้อหาภายในกล่องโต้ตอบเท่านั้นที่จะได้รับโฟกัสขณะที่โมดัลเปิดอยู่ ทุกอย่างที่อยู่นอกโมดัลจะยังคงไม่ทำงาน

เมื่อปิดกล่องโต้ตอบ ไม่ว่าจะเป็นโมดัลหรือไม่ก็ตาม โฟกัสจะกลับไปที่องค์ประกอบที่เปิดกล่องโต้ตอบ หลีกเลี่ยงการเปิดกล่องโต้ตอบแบบเป็นโปรแกรมโดยไม่มีการดำเนินการของผู้ใช้ หากจำเป็น โปรดตรวจสอบว่าคุณได้ย้ายโฟกัสกลับไปยังตำแหน่งเดิมก่อนที่กล่องโต้ตอบจะเปิดขึ้น โดยเฉพาะอย่างยิ่งหากผู้ใช้ปิดกล่องโต้ตอบโดยไม่ได้โต้ตอบกับกล่องโต้ตอบ

มีแอตทริบิวต์ inert ส่วนกลางที่ใช้เพื่อปิดใช้องค์ประกอบและองค์ประกอบสืบทอดทั้งหมดได้ นอกเหนือจากกล่องโต้ตอบที่ใช้งานอยู่ เมื่อเปิดกล่องโต้ตอบโมดัลโดยใช้ showModal() ความเฉื่อยหรือการปิดใช้งานจะเกิดขึ้นโดยค่าเริ่มต้น ไม่ได้ตั้งค่าแอตทริบิวต์ไว้อย่างชัดแจ้ง

ฉากหลังที่บดบังทุกอย่างนอกเหนือจากกล่องโต้ตอบสามารถจัดรูปแบบได้โดยใช้ Pseudo-Element ::backdrop ฉากหลังจะแสดงเมื่อ <dialog> แสดงด้วยเมธอด .showModal() เท่านั้น องค์ประกอบจำลองนี้จะจับคู่ฉากหลังทั้งหมด รวมถึงฉากหลังที่แสดงเมื่อใช้ FullScreen API เช่น เมื่อดูวิดีโอในโหมดเต็มหน้าจอซึ่งมีสัดส่วนภาพไม่เหมือนกับหน้าจอหรือจอภาพ

กล่องโต้ตอบแบบไม่บังคับ (Non-modal Dialog)

HTMLDialogElement.show() จะเปิดกล่องโต้ตอบในลักษณะเดียวกัน แต่จะไม่เพิ่มฉากหลังหรือทำให้สิ่งใดๆ ไม่ทำงาน แป้น Escape จะปิดเฉพาะกล่องโต้ตอบโมดัลเท่านั้น ไม่ใช่กล่องโต้ตอบที่ไม่ใช่โมดัล ด้วยเหตุนี้ การใส่เมธอดในการปิดกล่องโต้ตอบแบบไม่บังคับจึงมีความสำคัญมากยิ่งขึ้น หากตัวเลือกปิดอยู่นอกกล่องโต้ตอบ โฟกัสจะกลับไปที่องค์ประกอบที่เปิดกล่องโต้ตอบ ซึ่งเป็นประสบการณ์ของผู้ใช้ที่ไม่เหมาะสม

แม้ว่าข้อกำหนดจะไม่ได้กำหนดให้ต้องมีปุ่มปิดกล่องโต้ตอบอย่างเป็นทางการ แต่ก็ควรพิจารณาว่าจำเป็นต้องมี ปุ่มที่มองเห็นได้ซึ่งสามารถรับโฟกัสจะช่วยปรับปรุงการช่วยเหลือพิเศษและประสบการณ์ของผู้ใช้

การปิดกล่องโต้ตอบ

คุณไม่จำเป็นต้องใช้เมธอด HTMLDialogElement.close() เพื่อปิดกล่องโต้ตอบ คุณไม่จำเป็นต้องใช้ JavaScript เลย หากต้องการปิด <dialog> โดยไม่มี JavaScript ให้ใส่แบบฟอร์มที่มีเมธอดกล่องโต้ตอบโดยตั้งค่า method="dialog" ใน <form> หรือ formmethod="dialog" ในปุ่ม

เมื่อผู้ใช้ส่งด้วยเมธอด dialog ระบบจะคงสถานะของข้อมูลที่ผู้ใช้ป้อนไว้ แม้ว่าจะมีเหตุการณ์การส่ง แต่แบบฟอร์มจะผ่านการตรวจสอบข้อจำกัด (เว้นแต่จะมีการตั้งค่า novalidate) ระบบไม่ได้ล้างหรือส่งข้อมูลผู้ใช้ คุณสร้างปุ่มปิดโดยไม่ใช้ JavaScript ได้ดังนี้

<dialog open>
  <form method="dialog">
    <button type="submit" autofocus>close</button>
  </form>
</dialog>

คุณอาจสังเกตเห็นว่ามีการตั้งค่าแอตทริบิวต์ autofocus ในแท็กปิด <button> ในตัวอย่างนี้ องค์ประกอบที่มีแอตทริบิวต์ autofocus ที่ตั้งค่าไว้ภายใน <dialog> จะได้รับโฟกัสเมื่อการโหลดหน้าเว็บก็ต่อเมื่อหน้าเว็บโหลดโดยที่กล่องโต้ตอบปรากฏอยู่แล้วเท่านั้น หากหน้าเว็บไม่ได้โหลด องค์ประกอบเหล่านี้จะได้รับโฟกัสเมื่อกล่องโต้ตอบเปิดขึ้น

เมื่อเปิดกล่องโต้ตอบ องค์ประกอบแรกที่โฟกัสได้ภายในกล่องโต้ตอบจะได้รับโฟกัส เว้นแต่องค์ประกอบอื่นจะตั้งค่าแอตทริบิวต์ autofocus ไว้ การตั้งค่าแอตทริบิวต์ autofocus ในปุ่มปิดช่วยให้มั่นใจว่าปุ่มจะได้รับโฟกัสเมื่อเปิดกล่องโต้ตอบ แต่การรวม autofocus ไว้ใน <dialog> ควรทำด้วยความรอบคอบอย่างยิ่ง ระบบจะข้ามองค์ประกอบทั้งหมดในลำดับที่อยู่ก่อนองค์ประกอบที่โฟกัสอัตโนมัติ เราจะพูดถึงแอตทริบิวต์นี้เพิ่มเติมในโมดูลโฟกัส

อินเทอร์เฟซ HTMLDialogElement มีพร็อพเพอร์ตี้ returnValue การส่งแบบฟอร์มที่มี method="dialog" จะตั้งค่า returnValue เป็น name (หากมี) ของปุ่มส่งที่ใช้ส่งแบบฟอร์ม หากเราเขียน <button type="submit" name="toasty">close</button> returnValue จะเป็น toasty

เมื่อเปิดกล่องโต้ตอบ แอตทริบิวต์บูลีน open จะปรากฏขึ้น ซึ่งหมายความว่ากล่องโต้ตอบทำงานอยู่และโต้ตอบได้ เมื่อเปิดกล่องโต้ตอบโดยการเพิ่มแอตทริบิวต์ open แทนที่จะใช้ .show() หรือ .showModal() กล่องโต้ตอบจะเป็นแบบไม่มีโมดัล พร็อพเพอร์ตี้ HTMLDialogElement.open จะแสดงผลเป็น true หรือ false โดยขึ้นอยู่กับว่ากล่องโต้ตอบพร้อมให้โต้ตอบหรือไม่ ไม่ใช่ว่ากล่องโต้ตอบเป็นโมดัลหรือไม่

แม้ว่า JavaScript จะเป็นวิธีที่แนะนำในการเปิดกล่องโต้ตอบ แต่การใส่แอตทริบิวต์ open ในการโหลดหน้าเว็บ แล้วนำออกด้วย .close() จะช่วยให้มั่นใจได้ว่ากล่องโต้ตอบจะพร้อมใช้งานแม้ว่า JavaScript จะไม่พร้อมใช้งานก็ตาม

รายละเอียดเพิ่มเติม

ไม่ใช้ tabindex

องค์ประกอบที่เปิดใช้งานเพื่อเปิดกล่องโต้ตอบและปุ่มปิดที่อยู่ในกล่องโต้ตอบ (และอาจรวมถึงเนื้อหาอื่นๆ) จะรับโฟกัสได้และเป็นแบบอินเทอร์แอกทีฟ องค์ประกอบ <dialog> ไม่ใช่แบบอินเทอร์แอกทีฟและไม่ได้รับโฟกัส อย่าเพิ่มพร็อพเพอร์ตี้ tabindex ลงในกล่องโต้ตอบเอง

บทบาท ARIA

บทบาทโดยนัยคือ dialog หากกล่องโต้ตอบเป็นหน้าต่างยืนยันที่สื่อสารข้อความที่ต้องการการตอบกลับหรือการยืนยันจากผู้ใช้ ให้ตั้งค่า role="alertdialog" ใส่ชื่อที่เข้าถึงได้สำหรับกล่องโต้ตอบ หากข้อความที่มองเห็นได้สามารถระบุชื่อที่เข้าถึงได้ ให้เพิ่ม aria-labelledby="idOfLabelingText"

ค่าเริ่มต้นของ CSS

เบราว์เซอร์มีรูปแบบเริ่มต้นสำหรับ dialog Firefox, Chrome และ Edge จะตั้งค่า color: CanvasText; และ background-color: Canvas; Safari ตั้งค่า color: black; background-color: white; ในสไตล์ชีต User Agent color รับค่ามาจาก dialog แทนที่จะเป็น body หรือ :root ซึ่งอาจไม่เป็นไปตามที่คาดไว้ พร็อพเพอร์ตี้ background-color ไม่ได้รับการรับค่า

ทดสอบความเข้าใจ

ทดสอบความรู้เกี่ยวกับองค์ประกอบกล่องโต้ตอบ

คุณจะจัดสไตล์พื้นที่ด้านหลังกล่องโต้ตอบอย่างไร

ด้วยองค์ประกอบเทียม ::background
โปรดลองอีกครั้ง
ด้วยองค์ประกอบเทียม ::backdrop
ถูกต้อง
ด้วยพร็อพเพอร์ตี้ background
โปรดลองอีกครั้ง