Category: reference
HTML Semantic Elements — เขียน HTML ให้มีความหมาย
รวม HTML5 semantic elements ที่ควรรู้ทั้งหมด ว่าควรใช้ element ไหนในสถานการณ์ใด ทำไมถึงสำคัญต่อ accessibility และ SEO และความสัมพันธ์กับ ARIA
สารบัญ
ทำไม Semantic HTML สำคัญ
<!-- ❌ div soup — ไม่มีความหมาย -->
<div class="header">
<div class="nav">
<div class="nav-item">Home</div>
</div>
</div>
<!-- ✅ semantic — screen reader, bot, dev อ่านเข้าใจ -->
<header>
<nav aria-label="Main navigation">
<a href="/">Home</a>
</nav>
</header>
Semantic HTML ช่วย:
- Screen reader นำทางได้ถูกต้องโดยไม่ต้อง ARIA เพิ่ม
- Search engine เข้าใจโครงสร้างหน้าได้ดีขึ้น
- Developer อ่านโค้ดเข้าใจเร็วขึ้น
- Browser render default style ที่เหมาะสม
Document Structure
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8">
<title>ชื่อหน้า</title>
</head>
<body>
<header>...</header> <!-- header ของ site หรือ section -->
<nav>...</nav> <!-- navigation links -->
<main> <!-- เนื้อหาหลัก — มีแค่ 1 ต่อหน้า -->
<article>...</article> <!-- เนื้อหาที่เป็น self-contained -->
<aside>...</aside> <!-- เนื้อหาที่เกี่ยวข้องแต่ไม่ใช่ main content -->
</main>
<footer>...</footer> <!-- footer ของ site หรือ section -->
</body>
</html>
Content Elements
<!-- ระดับ heading — ห้ามข้าม (h1 → h3 โดยไม่มี h2) -->
<h1>ชื่อหน้า</h1> <!-- มีแค่ 1 ต่อหน้า -->
<h2>หัวข้อหลัก</h2>
<h3>หัวข้อรอง</h3>
<!-- paragraph -->
<p>ข้อความ paragraph</p>
<!-- figure — รูปภาพ, diagram, code ที่มี caption -->
<figure>
<img src="chart.png" alt="กราฟแสดงการเติบโต" />
<figcaption>รูปที่ 1: อัตราการเติบโต Q1 2026</figcaption>
</figure>
<!-- blockquote -->
<blockquote cite="https://source.com">
<p>ข้อความที่อ้างถึง</p>
</blockquote>
<!-- code -->
<pre><code class="language-js">const x = 1;</code></pre>
<p>ใช้ <code>npm install</code> เพื่อติดตั้ง</p>
Interactive Elements
<!-- button vs anchor -->
<!-- ใช้ <a> เมื่อ navigate ไปยัง URL -->
<a href="/about">About</a>
<!-- ใช้ <button> เมื่อทำ action ที่ไม่ navigate -->
<button type="button" onclick="toggleMenu()">Menu</button>
<button type="submit">Send</button>
<!-- details + summary — accordion โดยไม่ต้องการ JavaScript -->
<details>
<summary>คลิกเพื่อดูเพิ่มเติม</summary>
<p>เนื้อหาที่ซ่อนอยู่</p>
</details>
<!-- dialog — modal โดยไม่ต้องการ JS library -->
<dialog id="modal">
<form method="dialog">
<p>ยืนยันการลบ?</p>
<button type="submit">ยืนยัน</button>
</form>
</dialog>
<button onclick="document.getElementById('modal').showModal()">ลบ</button>
Lists
<!-- ordered list — ลำดับมีความหมาย -->
<ol>
<li>เปิด terminal</li>
<li>รัน npm install</li>
<li>รัน npm run dev</li>
</ol>
<!-- unordered list — ลำดับไม่มีความหมาย -->
<ul>
<li>Astro</li>
<li>TypeScript</li>
</ul>
<!-- description list — คำศัพท์และนิยาม, key-value -->
<dl>
<dt>Astro</dt>
<dd>Web framework สำหรับ content-driven websites</dd>
<dt>TypeScript</dt>
<dd>JavaScript ที่มี static type system</dd>
</dl>
Time และ Date
<!-- ใช้ <time> เสมอสำหรับวันเวลา -->
<time datetime="2026-06-14">14 มิถุนายน 2026</time>
<time datetime="2026-06-14T09:00">9 โมงเช้า วันที่ 14 มิ.ย. 2026</time>
<time datetime="PT2H30M">2 ชั่วโมง 30 นาที</time>
ใช้กับ Astro
---
// Layout.astro
const { title } = Astro.props;
---
<html lang="th">
<head>
<title>{title}</title>
</head>
<body>
<header>
<nav>...</nav>
</header>
<main>
<slot />
</main>
<footer>...</footer>
</body>
</html>
---
// [slug].astro — blog post
const { Content } = await render(entry);
---
<article>
<header>
<h1>{entry.data.title}</h1>
<time datetime={entry.data.date.toISOString()}>
{entry.data.date.toLocaleDateString('th-TH')}
</time>
</header>
<Content />
</article>
เมื่อไรต้องเพิ่ม ARIA
Semantic HTML ที่ถูกต้องแทบไม่ต้องการ ARIA แต่มีบางกรณีที่ต้องเพิ่ม:
<!-- เมื่อ semantic element ไม่เพียงพอ -->
<nav aria-label="Main navigation">...</nav>
<nav aria-label="Breadcrumb">...</nav>
<!-- เมื่อ state เปลี่ยน dynamically -->
<button aria-pressed="false" id="theme-toggle">Dark Mode</button>
<button aria-expanded="false" aria-controls="menu">Menu</button>
<!-- เมื่อ error message อยู่แยกจาก input -->
<input id="email" aria-describedby="email-error" />
<p id="email-error" role="alert">กรุณากรอกอีเมลที่ถูกต้อง</p>
กฎง่ายๆ: ถ้า HTML semantic element ทำให้ browser/screen reader เข้าใจได้แล้ว → ไม่ต้องเพิ่ม ARIA