본문으로 건너뛰기

เนื้อหาภาษาไทย / 태국어 콘텐츠

시스템 가이드 검수 완료된 콘텐츠

การสร้าง Modals และ Dialogs ด้วย Tailwind CSS

บทความนี้สอนวิธีการสร้าง Modals และ Dialogs ที่สวยงามและตอบสนองต่อการใช้งานบนอุปกรณ์ต่างๆ โดยใช้ Tailwind CSS Framework พร้อมทั้งเน้นย้ำถึงความสำคัญของการจัดการ...

การสร้าง Modals และ Dialogs ด้วย Tailwind CSS

ในบทความนี้ เราจะมาเรียนรู้วิธีการสร้าง Modals และ Dialogs ที่สวยงามและตอบสนองต่อการใช้งานบนอุปกรณ์ต่างๆ (Responsive) โดยใช้ Tailwind CSS Framework ซึ่งเป็นเครื่องมือที่ช่วยให้เราออกแบบ UI ได้อย่างรวดเร็วและมีประสิทธิภาพ Modals และ Dialogs เป็นส่วนประกอบสำคัญในการสร้างปฏิสัมพันธ์กับผู้ใช้ โดยใช้เพื่อแสดงข้อมูลสำคัญ แจ้งเตือน หรือขอการยืนยันจากผู้ใช้

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

ข้อกำหนดเบื้องต้น

เพื่อให้เข้าใจบทความนี้ได้ดีที่สุด คุณควรมีความรู้พื้นฐานเกี่ยวกับ:

  • Tailwind CSS: การติดตั้งและการใช้งานเบื้องต้น
  • HTML: โครงสร้างพื้นฐานของ HTML
  • CSS: ความเข้าใจเกี่ยวกับ CSS
  • JavaScript: ความรู้พื้นฐานเกี่ยวกับ JavaScript (จำเป็นสำหรับการจัดการการเปิด/ปิด Modal)

ขั้นตอนการสร้าง Modal ด้วย Tailwind CSS

เราจะสร้าง Modal อย่างง่ายที่มีเนื้อหา ข้อความ และปุ่มปิด โดยจะเน้นการใช้ Tailwind CSS เพื่อจัดรูปแบบ Modal ให้สวยงามและ Responsive

1. โครงสร้าง HTML

เริ่มต้นด้วยการสร้างโครงสร้าง HTML สำหรับ Modal ของเรา

<div id="modal" class="fixed z-10 inset-0 overflow-y-auto hidden" aria-labelledby="modal-title" role="dialog" aria-modal="true">
  <div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
    <!-- Background overlay, when the modal open -->
    <div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" aria-hidden="true"></div>

    <!-- This element is to trick the browser into centering the modal contents. -->
    <span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>

    <!-- Modal panel -->
    <div class="inline-block align-bottom bg-white rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full">
      <div class="bg-white px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
        <div class="sm:flex sm:items-start">
          <div class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10">
            <!-- Heroicon name: outline/exclamation -->
            <svg class="h-6 w-6 text-red-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
            </svg>
          </div>
          <div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
            <h3 class="text-lg leading-6 font-medium text-gray-900" id="modal-title">
              Deactivate account
            </h3>
            <div class="mt-2">
              <p class="text-sm text-gray-500">
                Are you sure you want to deactivate your account? All of your data will be permanently removed. This action cannot be undone.
              </p>
            </div>
          </div>
        </div>
      </div>
      <div class="bg-gray-50 px-4 py-3 sm:px-6 sm:flex sm:flex-row-reverse">
        <button type="button" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">
          Deactivate
        </button>
        <button type="button" class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:ml-3 sm:w-auto sm:text-sm" id="closeModalButton">
          Cancel
        </button>
      </div>
    </div>
  </div>
</div>

<button id="openModalButton" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
  Open Modal
</button>

คำอธิบายโค้ด:

  • <div id="modal" ...>: คือ Container หลักของ Modal เรากำหนดให้เป็น fixed เพื่อให้ Modal อยู่เหนือเนื้อหาอื่นๆ และ z-10 เพื่อกำหนด Z-index ให้ Modal แสดงผลอยู่ด้านบนสุด นอกจากนี้เรายังกำหนด hidden เพื่อซ่อน Modal ไว้ก่อน
  • inset-0: กำหนดให้ Modal ครอบคลุมทั้งหน้าจอ
  • overflow-y-auto: เปิดใช้งาน Scrollbar ในกรณีที่เนื้อหา Modal ยาวเกินหน้าจอ
  • aria-labelledby="modal-title", role="dialog", aria-modal="true": คุณสมบัติเหล่านี้มีความสำคัญต่อ Accessibility ช่วยให้ Screen Reader เข้าใจว่าส่วนนี้เป็น Modal และอ่านข้อมูลที่เกี่ยวข้องให้ผู้ใช้
  • <div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" aria-hidden="true"></div>: คือส่วนของ Background Overlay ที่ทำให้ส่วนอื่นๆ ของหน้าจอมืดลงเมื่อ Modal เปิดขึ้น
  • sm: prefixes: คือ Responsive breakpoints ที่ทำให้ Modal ปรับขนาดและตำแหน่งให้เหมาะสมกับหน้าจอขนาดเล็กและใหญ่
  • <button id="openModalButton"...>: คือปุ่มที่ใช้เปิด Modal

2. JavaScript สำหรับการเปิด/ปิด Modal

ตอนนี้เราจะใช้ JavaScript เพื่อควบคุมการแสดงผลของ Modal

const modal = document.getElementById('modal');
const openModalButton = document.getElementById('openModalButton');
const closeModalButton = document.getElementById('closeModalButton');

openModalButton.addEventListener('click', () => {
  modal.classList.remove('hidden');
});

closeModalButton.addEventListener('click', () => {
  modal.classList.add('hidden');
});

// ปิด Modal เมื่อคลิกที่ Background Overlay
modal.addEventListener('click', (event) => {
  if (event.target === modal) {
    modal.classList.add('hidden');
  }
});

// ปิด Modal เมื่อกดปุ่ม ESC
document.addEventListener('keydown', (event) => {
  if (event.key === 'Escape') {
    modal.classList.add('hidden');
  }
});

คำอธิบายโค้ด:

  • เราดึง Element ของ Modal, ปุ่มเปิด และ ปุ่มปิด โดยใช้ document.getElementById()
  • เมื่อคลิกที่ปุ่มเปิด Modal เราจะลบ Class hidden ออกจาก Modal เพื่อให้แสดงผล
  • เมื่อคลิกที่ปุ่มปิด Modal เราจะเพิ่ม Class hidden ให้กับ Modal เพื่อซ่อน
  • เราเพิ่ม Event Listener เพื่อปิด Modal เมื่อคลิกที่ Background Overlay
  • เราเพิ่ม Event Listener เพื่อปิด Modal เมื่อกดปุ่ม ESCAPE

3. การจัดการ Focus

การจัดการ Focus เป็นสิ่งสำคัญเพื่อให้ Modal สามารถใช้งานได้ง่ายสำหรับผู้ใช้ที่ใช้ Keyboard Navigation หรือ Screen Reader

หลักการ:

  • เมื่อ Modal เปิดขึ้น Focus ควรไปอยู่ที่ Element แรกที่สามารถ Focus ได้ภายใน Modal (เช่น ปุ่มปิด หรือ ช่อง Input)
  • เมื่อ Modal เปิดอยู่ Focus จะต้องอยู่ภายใน Modal เท่านั้น ผู้ใช้ไม่ควรสามารถ Focus ไปที่ Element ภายนอก Modal ได้
  • เมื่อ Modal ปิดลง Focus ควรกลับไปยัง Element ที่ทำให้ Modal เปิดขึ้น

ตัวอย่างการ Implement (เพิ่มเติมจากโค้ดเดิม):

// โค้ดเดิม (จากข้อ 2)

// เมื่อ Modal เปิด Focus ไปที่ปุ่มปิด
openModalButton.addEventListener('click', () => {
  modal.classList.remove('hidden');
  closeModalButton.focus();
});

// ปิด Modal (โค้ดเดิม)

// ดักจับ Focus ให้อยู่ภายใน Modal
modal.addEventListener('keydown', (event) => {
  if (event.key === 'Tab') {
    const focusableElements = modal.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
    const firstFocusableElement = focusableElements[0];
    const lastFocusableElement = focusableElements[focusableElements.length - 1];

    if (event.shiftKey) {
      if (document.activeElement === firstFocusableElement) {
        lastFocusableElement.focus();
        event.preventDefault();
      }
    } else {
      if (document.activeElement === lastFocusableElement) {
        firstFocusableElement.focus();
        event.preventDefault();
      }
    }
  }
});

// เมื่อ Modal ปิด Focus กลับไปยังปุ่มเปิด
closeModalButton.addEventListener('click', () => {
  modal.classList.add('hidden');
  openModalButton.focus();
});

modal.addEventListener('click', (event) => {
  if (event.target === modal) {
    modal.classList.add('hidden');
    openModalButton.focus();
  }
});

document.addEventListener('keydown', (event) => {
  if (event.key === 'Escape') {
    modal.classList.add('hidden');
    openModalButton.focus();
  }
});

คำอธิบายโค้ด:

  • เราใช้ querySelectorAll() เพื่อค้นหา Element ทั้งหมดที่สามารถ Focus ได้ภายใน Modal
  • เมื่อกดปุ่ม Tab เราจะตรวจสอบว่า Focus อยู่ที่ Element แรกหรือสุดท้าย หากเป็น Element แรกและกด Shift+Tab เราจะย้าย Focus ไปยัง Element สุดท้าย หากเป็น Element สุดท้ายและกด Tab เราจะย้าย Focus ไปยัง Element แรก
  • เมื่อ Modal ปิดลง เราจะย้าย Focus กลับไปยังปุ่มที่ใช้เปิด Modal

กรณีใช้งานจริงและข้อผิดพลาดที่พบบ่อย

กรณีใช้งานจริง:

  • Form Submission: ใช้ Modal เพื่อแสดง Form ให้ผู้ใช้กรอกข้อมูล
  • Confirmation Dialog: ใช้ Modal เพื่อขอการยืนยันก่อนที่จะดำเนินการที่สำคัญ (เช่น การลบข้อมูล)
  • Alert Message: ใช้ Modal เพื่อแสดงข้อความแจ้งเตือน
  • Image Viewer: ใช้ Modal เพื่อแสดงรูปภาพขนาดใหญ่

ข้อผิดพลาดที่พบบ่อย:

  • ลืมกำหนด aria-modal="true": ทำให้ Screen Reader ไม่เข้าใจว่าส่วนนี้เป็น Modal
  • ไม่ได้จัดการ Focus อย่างถูกต้อง: ทำให้ผู้ใช้ที่ใช้ Keyboard Navigation ใช้งาน Modal ได้ยาก
  • Modal ไม่ Responsive: Modal ไม่ปรับขนาดให้เหมาะสมกับหน้าจอขนาดเล็ก
  • Z-index ไม่ถูกต้อง: Modal ถูกซ่อนอยู่ด้านหลัง Element อื่น

สรุป

ในบทความนี้ เราได้เรียนรู้วิธีการสร้าง Modals และ Dialogs ที่สวยงาม Responsive และ Accessible โดยใช้ Tailwind CSS Framework เราได้เรียนรู้เกี่ยวกับโครงสร้าง HTML, JavaScript สำหรับการเปิด/ปิด Modal และการจัดการ Focus ที่ถูกต้อง การสร้าง Modals ที่ดีจะช่วยปรับปรุงประสบการณ์การใช้งานของผู้ใช้และทำให้เว็บไซต์ของคุณดูเป็นมืออาชีพมากขึ้น

Office.in.th Custom Service

이 구조를 바탕으로 시스템을 개발하거나 맞춤 변경하고 싶으신가요?

Office.in.th는 엔터프라이즈 웹 애플리케이션, API 연동, 공공/민간 업무 관리 시스템을 설계·개발하며 장기 지원을 제공합니다.

소프트웨어 개발 서비스 보기