สร้าง Tab Interface ที่เปลี่ยนเนื้อหาเมื่อ Hover (ชี้เมาส์) แทนการคลิก - เหมาะสำหรับเมนูดรอปดาวน์หรือ Quick Preview
โค้ดตัวอย่างสมบูรณ์
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tab Change on Hover</title>
<style>
* { box-sizing: border-box; }
body {
font-family: 'Segoe UI', Tahoma, sans-serif;
padding: 24px;
max-width: 900px;
margin: 0 auto;
}
.tabs-container {
display: flex;
border: 1px solid #ccc;
border-radius: 8px;
overflow: hidden;
background: #fafafa;
}
/* Tab Buttons Sidebar */
.tab-sidebar {
width: 25%;
min-width: 180px;
background: #f1f1f1;
border-right: 1px solid #ccc;
}
.tab-btn {
display: block;
width: 100%;
padding: 16px 20px;
background: inherit;
border: none;
border-bottom: 1px solid #ccc;
text-align: left;
cursor: pointer;
font-size: 16px;
font-family: inherit;
color: #333;
transition: background-color 0.2s, color 0.2s;
}
.tab-btn:last-child {
border-bottom: none;
}
.tab-btn:hover {
background-color: #e0e0e0;
color: #000;
}
.tab-btn.active {
background-color: #ddd;
color: #000;
font-weight: 600;
}
/* Tab Content Area */
.tab-content-area {
flex: 1;
padding: 24px;
min-height: 250px;
}
.tab-panel {
display: none;
animation: fadeIn 0.2s ease;
}
.tab-panel.active {
display: block;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(4px); }
to { opacity: 1; transform: translateY(0); }
}
.tab-panel h3 {
margin-top: 0;
color: #333;
}
</style>
</head>
<body>
<h2>แท็บเปลี่ยนเมื่อ Hover</h2>
<p>ชี้เมาส์ที่แท็บด้านซ้ายเพื่อดูข้อมูลแผนกต่างๆ</p>
<div class="tabs-container">
<div class="tab-sidebar" role="tablist">
<button class="tab-btn active" role="tab" aria-selected="true" aria-controls="panel-marketing" onmouseover="showTab('marketing', this)">การตลาด</button>
<button class="tab-btn" role="tab" aria-selected="false" aria-controls="panel-operations" onmouseover="showTab('operations', this)">ปฏิบัติการ</button>
<button class="tab-btn" role="tab" aria-selected="false" aria-controls="panel-finance" onmouseover="showTab('finance', this)">การเงิน</button>
<button class="tab-btn" role="tab" aria-selected="false" aria-controls="panel-it" onmouseover="showTab('it', this)">เทคโนโลยีสารสนเทศ</button>
</div>
<div class="tab-content-area">
<div id="panel-marketing" class="tab-panel active" role="tabpanel">
<h3>แผนกการตลาด</h3>
<p>รับผิดชอบการโปรโมท, บรานด์ดิ้ง, วิจัยตลาด, และการสร้างลูกค้าใหม่</p>
</div>
<div id="panel-operations" class="tab-panel" role="tabpanel">
<h3>แผนกปฏิบัติการ</h3>
<p>จัดการกระบวนการผลิต, logistics, supply chain, และคุณภาพสินค้า</p>
</div>
<div id="panel-finance" class="tab-panel" role="tabpanel">
<h3>แผนกการเงิน</h3>
<p>บัญชี, งบประมาณ, ภาษี, การเงินกองทุน, และรายงานทางการเงิน</p>
</div>
<div id="panel-it" class="tab-panel" role="tabpanel">
<h3>แผนกไอที</h3>
<p>พัฒนาระบบ, โครงสร้างพื้นฐาน, ความปลอดภัยข้อมูล, และนวัตกรรมดิจิทัล</p>
</div>
</div>
</div>
<script>
function showTab(deptId, btnElement) {
// ซ่อนทุก Panel
document.querySelectorAll('.tab-panel').forEach(panel => {
panel.classList.remove('active');
});
// ลบ Active Class จากทุกปุ่ม
document.querySelectorAll('.tab-btn').forEach(btn => {
btn.classList.remove('active');
btn.setAttribute('aria-selected', 'false');
});
// แสดง Panel ที่เลือก
const targetPanel = document.getElementById('panel-' + deptId);
if (targetPanel) {
targetPanel.classList.add('active');
}
// Active ปุ่มที่ Hover
btnElement.classList.add('active');
btnElement.setAttribute('aria-selected', 'true');
}
// Optional: Auto-show first tab on load
document.addEventListener('DOMContentLoaded', () => {
const firstBtn = document.querySelector('.tab-btn');
if (firstBtn) {
// Trigger hover effect หลังโหลดเสร็จ (Optional)
// firstBtn.dispatchEvent(new Event('mouseover'));
}
});
</script>
</body>
</html>
หลักการทำงาน
- HTML: Sidebar มีปุ่มแท็บ (role="tablist"), Content Area มี Panel (role="tabpanel")
- CSS:
.tab-panel { display: none; }+.tab-panel.active { display: block; } - JS: Event
onmouseoverเรียกshowTab(id, btn)สลับ Classactive - Accessibility: ARIA attributes (
role,aria-selected,aria-controls)
⚠️ ข้อควรพิจารณา (UX Considerations)
| ประเด็น | รายละเอียด | แนวทางแก้ |
|---|---|---|
| Accidental Activation | เมาส์ผ่านๆ ก็เปลี่ยนแท็บ | เพิ่ม Debounce 100-200ms |
| Mobile/Touch | ไม่มี Hover บน Touch Screen | Fallback: Click เพื่อเปิด, หรือใช้ Media Query |
| Keyboard Nav | Tab/Enter ไม่ทำงานกับ Hover | เพิ่ม Keyboard Support (Focus = Show) |
| Screen Readers | อาจสับสนจากการเปลี่ยนเร็ว | ใช้ aria-live="polite" บน Panel |
ปรับปรุง: Debounce + Keyboard Support
let hoverTimer = null;
const HOVER_DELAY = 150; // ms
function showTab(deptId, btnElement) {
clearTimeout(hoverTimer);
hoverTimer = setTimeout(() => {
// ... switching logic ...
}, HOVER_DELAY);
}
// Keyboard Support: Focus = Show Tab
document.querySelectorAll('.tab-btn').forEach(btn => {
btn.addEventListener('focus', (e) => {
const deptId = e.target.getAttribute('aria-controls')?.replace('panel-', '');
if (deptId) showTab(deptId, e.target);
});
});
// Touch Support: Click = Show (Mobile)
document.querySelectorAll('.tab-btn').forEach(btn => {
btn.addEventListener('click', (e) => {
if (window.matchMedia('(hover: none)').matches) {
const deptId = e.target.getAttribute('aria-controls')?.replace('panel-', '');
if (deptId) showTab(deptId, e.target);
}
});
});
กรณีใช้งานที่เหมาะสม
- Mega Menu / Dropdown Navigation
- Product Category Preview
- Dashboard Sidebar Navigation
- Documentation Sidebar
- ไม่เหมาะ: Critical Actions, Forms, Mobile-first UI