Mobil cihazlarda ekran genişliği sınırlı olduğu için yatay bir menü çubuğu nadiren işe yarar. İşte tam bu noktada hamburger menü devreye girer: üç çizgiden oluşan küçük bir düğme, dokunulduğunda gezinme bağlantılarını açar. Bu yazıda hiçbir kütüphaneye ihtiyaç duymadan, sade HTML, CSS ve JavaScript ile erişilebilir ve akıcı bir mobil navigasyon menüsünü adım adım kuracağız.
İskelet: anlamlı HTML
İyi bir menü, JavaScript kapalıyken bile mantıklı kalan anlamlı bir işaretleme ile başlar. Düğmeyi gerçek bir <button> olarak yazın; bir <div> değil. Ekran okuyucuların durumu anlaması için aria-expanded ve aria-controls niteliklerini ekleyin.
<header class="site-header">
<a href="/" class="logo">aslain</a>
<button id="navToggle" class="nav-toggle"
aria-expanded="false"
aria-controls="primaryNav"
aria-label="Menüyü aç">
<span class="bar"></span>
<span class="bar"></span>
<span class="bar"></span>
</button>
<nav id="primaryNav" class="nav">
<ul>
<li><a href="/#about">Hakkımda</a></li>
<li><a href="/#projects">Projeler</a></li>
<li><a href="/#contact">İletişim</a></li>
</ul>
</nav>
</header>
Üç <span class="bar"> ikonun çizgileridir. Bunları CSS ile çizmek, görsel dosyası kullanmaktan daha hafiftir ve renk ile animasyonu kolayca kontrol etmenizi sağlar.
İkonu CSS ile çizmek
Düğmeyi yalnızca dar ekranlarda göstermek için bir medya sorgusu kullanırız. Geniş ekranlarda menü zaten yatay olarak görünür, hamburger düğmesi gizlenir.
.nav-toggle {
display: none; /* masaüstünde gizli */
width: 44px;
height: 44px; /* en az 44px dokunma alanı */
background: none;
border: 0;
cursor: pointer;
}
.nav-toggle .bar {
display: block;
width: 24px;
height: 2px;
margin: 5px auto;
background: currentColor;
transition: transform .25s ease, opacity .25s ease;
}
@media (max-width: 760px) {
.nav-toggle { display: block; }
}
Dokunma alanı için en az 44×44 piksel hedefleyin; bu, parmakla rahatça basılabilen güvenli bir boyuttur ve erişilebilirlik kılavuzlarının önerdiği ölçüdür.
Menüyü açıp kapatma katmanı
Dar ekranda menü panelini varsayılan olarak gizleriz ve .is-open sınıfı eklenince görünür yaparız. Burada display: none yerine transform ve visibility kullanmak, kaydırma geçişini akıcı tutar.
@media (max-width: 760px) {
.nav {
position: fixed;
inset: 64px 0 0 0; /* başlığın altından başlar */
background: #0f0f12;
transform: translateX(100%);
visibility: hidden;
transition: transform .3s ease, visibility .3s;
}
.nav.is-open {
transform: translateX(0);
visibility: visible;
}
.nav ul {
display: flex;
flex-direction: column;
gap: 1.5rem;
padding: 2rem;
}
}
Üç çizgiyi bir "X" şekline dönüştürmek menünün açık olduğunu net biçimde anlatır. Bunu yalnızca CSS ile yaparız; üst ve alt çubuklar döner, ortadaki kaybolur.
.nav-toggle.is-active .bar:nth-child(1) {
transform: translateY(7px) rotate(45deg);
}
.nav-toggle.is-active .bar:nth-child(2) {
opacity: 0;
}
.nav-toggle.is-active .bar:nth-child(3) {
transform: translateY(-7px) rotate(-45deg);
}
JavaScript: durum ve erişilebilirlik
JavaScript'in tek işi sınıfları değiştirmek ve aria-expanded değerini güncellemektir. Durumu HTML'in tek kaynağı olarak aria-expanded'da tutmak, kodun temiz kalmasını sağlar.
const toggle = document.getElementById('navToggle');
const nav = document.getElementById('primaryNav');
function setOpen(open) {
toggle.setAttribute('aria-expanded', String(open));
toggle.classList.toggle('is-active', open);
nav.classList.toggle('is-open', open);
toggle.setAttribute('aria-label', open ? 'Menüyü kapat' : 'Menüyü aç');
}
toggle.addEventListener('click', () => {
const open = toggle.getAttribute('aria-expanded') === 'true';
setOpen(!open);
});
// Bir bağlantıya dokununca menüyü kapat
nav.addEventListener('click', (e) => {
if (e.target.closest('a')) setOpen(false);
});
// Escape tuşu menüyü kapatır
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape') setOpen(false);
});
Dikkat edilmesi gereken üç küçük ama önemli ayrıntı:
- Bağlantıya tıklayınca kapatma: Tek sayfalık bir sitede kullanıcı bir bölüme atladığında menünün açık kalması can sıkıcıdır.
- Escape desteği: Klavye kullanıcıları menüyü kapatmak için
Esctuşunu bekler. - aria-label güncellemesi: Etiket "aç" ve "kapat" arasında değişerek ekran okuyucuya doğru bilgi verir.
Odak yönetimi ve gövde kaydırması
Menü açıkken arka plandaki sayfanın kaymasını engellemek, mobilde önemli bir ayrıntıdır. <body> üzerine bir sınıf ekleyip overflow: hidden uygulayabilirsiniz. Ayrıca menü açıldığında odağı ilk bağlantıya taşımak, klavye ve ekran okuyucu kullanıcıları için akışı doğal kılar.
function setOpen(open) {
/* ...önceki satırlar... */
document.body.classList.toggle('nav-locked', open);
if (open) nav.querySelector('a')?.focus();
else toggle.focus();
}
body.nav-locked { overflow: hidden; }
Menü kapandığında odağı tekrar hamburger düğmesine döndürmek, kullanıcının kaldığı yerden devam etmesini sağlar. Bu küçük geri-odaklama davranışı, erişilebilir bileşenlerin imzasıdır.
Hareketi azaltma tercihine saygı
Bazı kullanıcılar işletim sistemi ayarlarından hareketi azaltmayı seçer. Animasyonları bu tercihe göre kapatmak hem kibar hem de erişilebilir bir davranıştır.
@media (prefers-reduced-motion: reduce) {
.nav, .nav-toggle .bar { transition: none; }
}
Bu birkaç satır, hareket duyarlılığı olan kullanıcıların menüyü ani geçişler olmadan kullanmasını sağlar; işlevsellikten ödün vermeden.
Sık Sorulan Sorular
Neden <div> yerine <button> kullanmalıyım?
Gerçek bir <button> klavye ile odaklanabilir, Enter ve Space tuşlarıyla çalışır ve ekran okuyuculara "düğme" olarak tanıtılır. Bir <div> ile bu davranışları elle taklit etmeniz gerekir ki bu hem fazladan kod hem de hata kaynağıdır.
Hamburger ikonu için görsel mi yoksa CSS mi daha iyi?
Çoğu durumda CSS ile üç <span> çizmek daha iyidir: ek istek yoktur, rengi currentColor ile temaya uyar ve X'e dönüşüm animasyonunu doğrudan yapabilirsiniz. SVG de geçerli bir seçenektir.
Menü hangi genişlikte gizlenmeli?
Sabit bir kural yoktur; içeriğinize bakın. Yatay menü sığmamaya başladığı noktada (sıklıkla 700–800px civarı) kırılma noktası koymak iyi sonuç verir. Tasarımınızı tarayıcıyı daraltarak test edin.
Mobil menünüzün hem şık hem erişilebilir olmasını mı istiyorsunuz? Sitenizin navigasyonunu birlikte gözden geçirelim. Benimle iletişime geçin ve projenizi konuşalım.