Dialog

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

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

องค์ประกอบ HTML เชิงความหมาย <dialog> สำหรับสร้างกล่องโต้ตอบจะมาพร้อมกับอรรถศาสตร์ การโต้ตอบกับแป้นพิมพ์ รวมถึงคุณสมบัติและวิธีการทั้งหมดของอินเทอร์เฟซ 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() ค่าความเฉื่อยหรือการปิดใช้งานจะเกิดขึ้นฟรี และจะไม่มีการตั้งค่าแอตทริบิวต์อย่างชัดเจน

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

กล่องโต้ตอบที่ไม่ใช่แบบโมดัล

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

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