HTML (HyperText Markup Language), web sayfalarının iskeletini oluşturan işaretleme dilidir. Bir web sayfasındaki başlıklar, paragraflar, bağlantılar, görseller, formlar ve daha fazlası HTML etiketleriyle tanımlanır. İster basit bir kişisel sayfa, ister React veya Next.js ile yazılmış büyük bir uygulama geliştirin; tarayıcıya ulaşan her şey sonunda HTML'dir.
Bu rehberde HTML'i sıfırdan ele alacağız: doküman yapısından <head> içindeki meta etiketlere, metin ve medya etiketlerinden formlara, semantic HTML'den erişilebilirlik ve SEO'ya kadar ihtiyacınız olan her konuyu örneklerle inceleyeceğiz. Yazının sonunda tüm parçaları birleştiren eksiksiz bir sayfa örneği ve hızlı başvuru listesi de bulacaksınız.
HTML Nedir?
HTML, tarayıcıların anlayabileceği şekilde içerik yapısını tanımlayan bir işaretleme dilidir (markup language) — bir programlama dili değildir. Değişkenler, döngüler ya da koşullar yoktur; HTML yalnızca "bu bir başlık", "bu bir paragraf", "bu bir bağlantı" der. Etiketler (tags) kullanılarak içerik; başlık, paragraf, liste, bağlantı gibi anlamlı parçalara bölünür.
Adındaki her kelimenin bir karşılığı vardır:
- HyperText: Belgeleri birbirine bağlayan bağlantılar. Web'i bir "ağ" yapan şey budur.
- Markup: İçeriği etiketlerle işaretleyerek ona anlam ve yapı kazandırmak.
- Language: Tüm tarayıcıların ortak olarak anladığı, standartları belirlenmiş bir dil.
HTML, CSS ve JavaScript
Modern bir web sayfası üç temel teknolojinin birleşiminden oluşur. Bunu bir ev üzerinden düşünebilirsiniz:
- HTML — İskelet: Duvarlar, odalar, kapılar. Sayfada ne olduğunu tanımlar.
- CSS — Görünüm: Boya, mobilya, dekorasyon. Sayfanın nasıl göründüğünü belirler.
- JavaScript — Davranış: Elektrik ve tesisat. Sayfanın nasıl davrandığını kontrol eder.
Bu üçlünün temelinde HTML vardır: CSS ve JavaScript olmadan da bir sayfa çalışır, ancak HTML olmadan ikisinin de uygulanacağı bir şey kalmaz.
Kısa Bir Tarihçe
- 1991: Tim Berners-Lee, CERN'de çalışırken HTML'i tanımlayan ilk belgeyi yayınladı. İlk sürümde yalnızca 18 civarında etiket vardı.
- 1995 – 1999: HTML 2.0, 3.2 ve 4.01 sürümleriyle tablolar, formlar ve stil desteği geldi.
- 2000: XML kurallarına dayanan, daha katı bir sözdizimi sunan XHTML 1.0 yayınlandı.
- 2014: HTML5 resmi standart oldu; semantic etiketler, yerleşik video/ses desteği, yeni form elemanları ve canvas gibi özellikler eklendi.
- Bugün: HTML artık sürüm numarasıyla değil, WHATWG tarafından sürekli güncellenen HTML Living Standard olarak gelişiyor. Yani "HTML5" dediğimiz şey aslında bugünkü HTML'in ta kendisi.
Tarayıcı HTML'i Nasıl İşler?
Bir web adresine girdiğinizde tarayıcı sunucudan bir HTML dosyası indirir ve bu metni yukarıdan aşağıya okuyarak DOM (Document Object Model) adı verilen bir ağaç yapısına dönüştürür. Her etiket bu ağaçta bir düğüm (node) olur; iç içe geçmiş etiketler ise ebeveyn-çocuk ilişkisi kurar.
document
└── html
├── head
│ └── title
└── body
├── h1
└── p
Süreç kabaca şu adımlardan oluşur:
- Tarayıcı HTML'i indirir, ayrıştırır (parse) ve DOM ağacını oluşturur.
- CSS dosyalarını okuyarak stil ağacını (CSSOM) oluşturur.
- DOM ve CSSOM birleştirilerek ekranda görünecek elemanlar belirlenir (render tree).
- Her elemanın konumu ve boyutu hesaplanır (layout), ardından ekrana çizilir (paint).
JavaScript, DOM'a erişerek sayfayı sonradan değiştirebilir. Tarayıcılar ayrıca oldukça hoşgörülüdür: kapanmamış bir etiket veya yanlış iç içe yazım gördüklerinde hata vermek yerine bunu kendi tahminlerine göre düzeltmeye çalışırlar. Bu kullanışlı görünse de beklenmedik sonuçlara yol açabilir; bu yüzden her zaman doğru ve geçerli HTML yazmak gerekir.
Geliştirme Ortamını Hazırlamak
HTML yazmak için özel bir programa ihtiyacınız yok; teorik olarak Not Defteri bile yeterlidir. Ancak işinizi ciddi şekilde kolaylaştıracak birkaç araç önerilir:
- Kod editörü: Visual Studio Code; otomatik tamamlama, renklendirme ve Emmet desteğiyle en popüler seçenektir.
- Tarayıcı: Chrome, Firefox veya Edge. Hepsinde bulunan geliştirici araçları (DevTools) sayfayı canlı olarak incelemenizi sağlar.
- Live Server eklentisi: Dosyayı kaydettiğiniz anda tarayıcıyı otomatik olarak yeniler.
Yeni bir klasör açın, içine index.html adında bir dosya oluşturun ve tarayıcıyla açın — ilk web sayfanız hazır. Ana sayfa dosyasının index.html olarak adlandırılması bir gelenektir; sunucular bir klasör istendiğinde varsayılan olarak bu dosyayı gösterir.
İpucu: VS Code'da boş bir HTML dosyasına ! yazıp Tab tuşuna bastığınızda Emmet temel doküman iskeletini sizin için otomatik oluşturur. Herhangi bir elemanı incelemek için ise sayfada sağ tıklayıp İncele (Inspect) seçeneğini kullanabilirsiniz.
Etiket ve Element Anatomisi
HTML'in yapı taşı element'tir. Bir element genellikle bir açılış etiketi, içerik ve bir kapanış etiketinden oluşur:
<a href="https://ertucuk.com" class="link">Portfolyom</a>
- Açılış etiketi:
<a ...>— Elementin başladığı yer. - Nitelikler (attributes):
href="...",class="..."— Açılış etiketine yazılan ek bilgiler;isim="değer"biçimindedir. - İçerik:
Portfolyom— Etiketlerin arasındaki metin veya başka elementler. - Kapanış etiketi:
</a>— Etiket adının önünde eğik çizgi (/) bulunur.
Etiket isimleri büyük/küçük harfe duyarlı değildir (<P> ile <p> aynıdır), ancak her zaman küçük harf kullanmak evrensel bir alışkanlıktır.
Boş (Void) Elementler
Bazı elementler içerik almaz ve kapanış etiketine ihtiyaç duymaz. Bunlara void element denir:
<br />
<hr />
<img src="/ertu.png" alt="Ertuğrul Mert" />
<input type="text" />
<meta charset="UTF-8" />
<link rel="stylesheet" href="/style.css" />
HTML5'te <br> ve <br /> yazımları aynı anlama gelir. Sondaki eğik çizgi HTML'de isteğe bağlıdır, ancak React/JSX gibi ortamlarda zorunludur. Projenizde tek bir yazım stili seçip ona sadık kalmanız yeterlidir.
İç İçe Elementler
Elementler birbirinin içine yerleştirilebilir. Buradaki kural basittir: en son açılan etiket ilk kapanır.
<!-- Doğru -->
<p>Bu metin <strong><em>hem kalın hem italik</em></strong>.</p>
<!-- Yanlış: etiketler çapraz kapanıyor -->
<p>Bu metin <strong><em>hem kalın hem italik</strong></em>.</p>
Kodunuzu okunabilir tutmak için iç içe geçen her seviyeyi bir girinti (genellikle 2 boşluk) ile yazın.
Yorum Satırları
Yorumlar tarayıcıda görüntülenmez; kodunuza not düşmek veya bir bölümü geçici olarak devre dışı bırakmak için kullanılır:
<!-- Bu bir yorum satırıdır -->
<!--
Birden fazla satıra
yayılan bir yorum
-->
Dikkat: Yorumlar sayfa kaynağında herkes tarafından görülebilir. Şifre, API anahtarı gibi hassas bilgileri asla yorum satırına yazmayın.
Temel Doküman Yapısı
Her HTML dokümanı belirli bir iskelete sahiptir:
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Ertuğrul Mert</title>
</head>
<body>
<h1>Merhaba, Ben Ertuğrul Mert</h1>
<p>Self-taught bir geliştiriciyim.</p>
</body>
</html>
- <!DOCTYPE html>: Tarayıcıya belgenin HTML5 olduğunu bildirir. Yazılmazsa tarayıcı "quirks mode" adı verilen eski uyumluluk moduna geçer ve sayfanız beklenmedik şekilde görünebilir.
- <html lang="tr">: Tüm sayfa içeriğini saran kök etikettir.
langniteliği ekran okuyuculara doğru telaffuzu, arama motorlarına sayfanın dilini, tarayıcılara ise çeviri önerisini ve doğru heceleme kurallarını bildirir. - <head>: Sayfa hakkında meta bilgileri, başlığı ve bağlantılı dosyaları içerir. Buradaki içerik sayfada görünmez.
- <meta charset="UTF-8">: Türkçe karakterlerin (ç, ğ, ı, ö, ş, ü) ve emojilerin doğru görüntülenmesini sağlar.
<head>içindeki ilk elemanlardan biri olmalıdır. - <meta name="viewport">: Sayfanın mobil cihazlarda ekran genişliğine göre ölçeklenmesini sağlar. Bu satır olmadan telefonlarda sayfanın küçültülmüş masaüstü versiyonu görünür.
- <title>: Tarayıcı sekmesinde, yer imlerinde ve arama motoru sonuçlarında görünen başlıktır.
- <body>: Kullanıcının tarayıcıda gördüğü tüm görünür içeriği barındırır.
Head Bölümü ve Meta Etiketler
<head> kullanıcıya görünmez, ancak tarayıcılar, arama motorları ve sosyal medya platformları için kritik bilgileri barındırır. Gerçek bir projede head bölümü genellikle şöyle görünür:
<head>
<!-- Karakter seti ve mobil uyum -->
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- Başlık ve açıklama (SEO) -->
<title>Ertuğrul Mert | Yazılım Geliştirici</title>
<meta name="description" content="Node.js, MongoDB ve Next.js ile projeler geliştiren self-taught bir yazılımcı." />
<meta name="author" content="Ertuğrul Mert" />
<link rel="canonical" href="https://ertucuk.com/" />
<!-- Favicon -->
<link rel="icon" href="/favicon.ico" sizes="any" />
<link rel="icon" href="/icon.svg" type="image/svg+xml" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
<!-- Open Graph: bağlantı paylaşıldığında görünen önizleme kartı -->
<meta property="og:title" content="Ertuğrul Mert" />
<meta property="og:description" content="Self-taught yazılım geliştirici" />
<meta property="og:image" content="https://ertucuk.com/og-image.png" />
<meta property="og:url" content="https://ertucuk.com/" />
<meta property="og:type" content="website" />
<!-- Twitter / X kartı -->
<meta name="twitter:card" content="summary_large_image" />
<!-- Mobil tarayıcı arayüz rengi -->
<meta name="theme-color" content="#0f172a" />
<!-- Stil ve script dosyaları -->
<link rel="stylesheet" href="/css/style.css" />
<script src="/js/main.js" defer></script>
</head>
- description: Arama sonuçlarında başlığın altında görünen kısa açıklamadır. 150–160 karakter civarında, sayfayı özetleyen ve tıklamaya teşvik eden bir metin yazın.
- canonical: Aynı içerik birden fazla URL'den erişilebiliyorsa, arama motorlarına asıl adresi bildirir ve kopya içerik sorununu önler.
- icon: Tarayıcı sekmesinde görünen küçük simgedir (favicon). SVG favicon modern tarayıcılarda her boyutta keskin görünür.
- og:*: Open Graph etiketleri; bağlantınız WhatsApp, LinkedIn, Discord veya Facebook'ta paylaşıldığında görünen başlık, açıklama ve görseli belirler.
og:imageiçin 1200×630 piksel önerilir. - theme-color: Bazı mobil tarayıcılarda adres çubuğunun rengini belirler.
- robots:
<meta name="robots" content="noindex, nofollow" />ile bir sayfanın arama motorlarında listelenmesini engelleyebilirsiniz (ör. yönetim paneli veya teşekkür sayfaları).
Başlık ve Metin Etiketleri
Başlıklar (h1 – h6)
<h1>En büyük başlık</h1>
<h2>Alt başlık</h2>
<h3>Daha küçük alt başlık</h3>
<h4>...</h4>
<h5>...</h5>
<h6>En küçük başlık</h6>
<h1> ile <h6> arasında altı farklı başlık seviyesi bulunur; sayı büyüdükçe başlık önemi azalır. Başlıkları kullanırken dikkat edilmesi gerekenler:
- Her sayfada, sayfanın ana konusunu anlatan tek bir
<h1>kullanmak en iyi uygulamadır. - Seviye atlamayın:
<h2>'den sonra doğrudan<h4>'e geçmek yerine<h3>kullanın. Başlıklar bir kitabın içindekiler tablosu gibi hiyerarşik olmalıdır. - Başlıkları yazıyı büyütmek için değil, yapıyı belirtmek için kullanın. Görsel boyutu CSS ile ayarlanır.
- Ekran okuyucu kullanıcıları sayfada başlıklar arasında atlayarak gezinir; düzgün bir başlık yapısı onlar için bir harita görevi görür.
<h1>Web Geliştirme Rehberi</h1>
<h2>Frontend</h2>
<h3>HTML</h3>
<h3>CSS</h3>
<h2>Backend</h2>
<h3>Node.js</h3>
<h3>MongoDB</h3>
Paragraf, Satır Sonu ve Yatay Çizgi
<p>Bu bir paragraftır. Tarayıcı paragrafların arasına otomatik boşluk bırakır.</p>
<p>
Atatürk Caddesi No: 1<br />
Kadıköy / İstanbul
</p>
<hr />
<p>Yeni bir konuya geçiş.</p>
<br> yalnızca adres veya şiir gibi satır sonunun içeriğin bir parçası olduğu durumlarda kullanılmalıdır; paragraflar arasına boşluk eklemek için değil — boşluk CSS'in işidir. <hr> ise yalnızca bir çizgi değil, konu değişimini temsil eden tematik bir ayırıcıdır.
Metin Biçimlendirme Etiketleri
<strong>Önemli metin</strong>
<b>Dikkat çekmek için kalın metin</b>
<em>Vurgulanan metin</em>
<i>Teknik terim veya yabancı kelime</i>
<mark>İşaretlenmiş (fosforlu) metin</mark>
<small>Dipnot veya telif hakkı metni</small>
<del>Eski fiyat: 500 TL</del>
<ins>Yeni fiyat: 400 TL</ins>
<s>Artık geçerli olmayan bilgi</s>
<u>Altı çizili metin (ör. yazım hatası işareti)</u>
H<sub>2</sub>O
x<sup>2</sup> + y<sup>2</sup>
- strong ve b farkı: İkisi de varsayılan olarak kalın görünür. Ancak
<strong>içeriğin önemli olduğunu belirtir;<b>ise ek bir anlam taşımadan yalnızca görsel olarak öne çıkarır. - em ve i farkı:
<em>cümlenin anlamını değiştirebilecek bir vurgu bildirir ("Ben yapmadım" ile "Ben yapmadım" farklıdır).<i>ise teknik terimler, yabancı kelimeler veya iç ses gibi farklı tonda okunan metinler içindir. - del, ins ve s:
<del>ve<ins>içerikte yapılan değişiklikleri (silinen/eklenen),<s>ise artık doğru ya da geçerli olmayan bilgiyi gösterir. - sub ve sup: Alt simge (kimyasal formüller) ve üst simge (üsler, dipnot numaraları) içindir.
Alıntı, Kısaltma ve Kaynak Etiketleri
<figure>
<blockquote cite="https://www.w3.org/WAI/">
<p>Web'in gücü evrenselliğindedir.</p>
</blockquote>
<figcaption>— Tim Berners-Lee</figcaption>
</figure>
<p>Hocam her zaman <q>Önce yapıyı kur, sonra süsle</q> derdi.</p>
<p><abbr title="HyperText Markup Language">HTML</abbr> öğrenmesi kolay bir dildir.</p>
<p><cite>Clean Code</cite> her yazılımcının okuması gereken bir kitaptır.</p>
- blockquote: Başka bir kaynaktan alınan uzun, blok halindeki alıntılar içindir. Alıntının sahibi blockquote'un dışında, örneğin bir
<figcaption>içinde belirtilmelidir. - q: Satır içi kısa alıntılardır; tarayıcı tırnak işaretlerini otomatik ekler.
- abbr: Kısaltmalar içindir;
titleniteliğindeki açılım fareyle üzerine gelindiğinde görünür. - cite: Bir eserin (kitap, film, makale) adını belirtir.
Kod ve Teknik Metin Etiketleri
<p>Diziye eleman eklemek için <code>array.push()</code> metodunu kullanın.</p>
<p>Kaydetmek için <kbd>Ctrl</kbd> + <kbd>S</kbd> tuşlarına basın.</p>
<p>Terminal çıktısı: <samp>Server running on port 3000</samp></p>
<p>Dairenin alanı: <var>π</var> × <var>r</var><sup>2</sup></p>
<pre>
Bu metindeki boşluklar
ve satır sonları
aynen korunur.
</pre>
- code: Satır içi kod parçaları.
- kbd: Klavye girdisi ve tuş kombinasyonları.
- samp: Bir programın ürettiği örnek çıktı.
- var: Matematiksel veya programlama değişkenleri.
- pre: Boşlukları ve satır sonlarını olduğu gibi koruyan, genellikle sabit genişlikli yazı tipiyle gösterilen önceden biçimlendirilmiş metin. Çok satırlı kod blokları için
<pre><code>...</code></pre>birlikte kullanılır.
Tarih ve Adres Bilgisi
<p>Bu yazı <time datetime="2026-02-18">18 Şubat 2026</time> tarihinde yayınlandı.</p>
<p>Etkinlik <time datetime="2026-03-01T19:30">1 Mart akşamı 19.30'da</time> başlıyor.</p>
<address>
İletişim: <a href="mailto:merhaba@example.com">merhaba@example.com</a>
</address>
<time> elementinin datetime niteliği, insanlar için yazılmış tarihi makinelerin (arama motorları, takvim uygulamaları) anlayabileceği standart biçimde sunar. <address> ise sayfanın veya makalenin sahibine ait iletişim bilgileri içindir.
Boşluklar ve Özel Karakterler
HTML'de art arda yazılan birden fazla boşluk veya satır sonu, tarayıcıda tek bir boşluğa indirgenir:
<p>Merhaba Dünya</p>
<!-- Tarayıcıda: "Merhaba Dünya" -->
Ayrıca < ve > gibi karakterler HTML sözdiziminin parçası olduğundan metin içinde doğrudan yazılamaz. Bunun yerine karakter varlıkları (HTML entities) kullanılır:
<→ < (küçüktür)>→ > (büyüktür)&→ & (ve işareti)"→ " (çift tırnak) → bölünemez boşluk©→ © (telif hakkı)®ve™→ ® ve ™€→ €
<p>5 < 10 ve 10 > 5</p>
<p>© 2026 Ertuğrul Mert. Tüm hakları saklıdır.</p>
<p>Fiyat: 100 TL</p>
iki kelimenin satır sonunda birbirinden ayrılmasını engeller ("100 TL" gibi). Boşluk oluşturmak için arka arkaya yazmak ise kötü bir alışkanlıktır; bunun yerine CSS'teki margin ve padding özelliklerini kullanın. UTF-8 kullandığınız sürece ©, € gibi karakterleri doğrudan yazabilirsiniz; varlık kullanmak yalnızca <, > ve & için gerçekten gereklidir.
Bağlantılar (Linkler)
Bağlantılar web'i "web" yapan şeydir. <a> (anchor) etiketi ve href niteliğiyle oluşturulur. href bağlantının hedefini belirtir.
Mutlak ve Göreli Yollar
<!-- Mutlak (absolute) URL: başka bir siteye -->
<a href="https://github.com/ertucuk">GitHub Profilim</a>
<!-- Kök dizine göre (root-relative) yol -->
<a href="/blog">Blog</a>
<!-- Bulunulan dosyaya göre (relative) yollar -->
<a href="hakkimda.html">Hakkımda</a>
<a href="projeler/index.html">Projeler</a>
<a href="../index.html">Bir üst klasördeki ana sayfa</a>
- Mutlak URL: Protokol ve alan adını içerir (
https://...). Başka sitelere bağlantı verirken kullanılır. - Kök dizine göre yol:
/ile başlar ve sitenin ana dizininden itibaren hesaplanır. Sayfa nerede olursa olsun aynı yere gider. - Göreli yol: Mevcut dosyanın konumuna göre hesaplanır.
../bir üst klasöre çıkmak anlamına gelir.
Özel Bağlantı Türleri
<!-- Yeni sekmede aç -->
<a href="https://ertucuk.com" target="_blank" rel="noopener noreferrer">Portfolyom</a>
<!-- E-posta ve telefon -->
<a href="mailto:merhaba@example.com?subject=Proje%20Teklifi">E-posta gönder</a>
<a href="tel:+905551234567">Beni arayın</a>
<!-- Dosya indirme -->
<a href="/cv.pdf" download="Ertugrul-Mert-CV.pdf">CV'mi indir</a>
<!-- Sayfa içi bağlantı (id'ye göre) -->
<a href="#iletisim">İletişim bölümüne git</a>
<section id="iletisim">...</section>
<!-- Başka bir sayfanın belirli bir bölümüne -->
<a href="/blog/html#formlar">HTML yazısındaki Formlar bölümü</a>
- target="_blank": Bağlantıyı yeni sekmede açar.
rel="noopener"yeni sayfanın sizin sayfanızawindow.openerüzerinden erişmesini engeller;noreferrerise hangi sayfadan gelindiği bilgisini göndermez. Modern tarayıcılar bunu büyük ölçüde varsayılan olarak uygulasa da açıkça yazmak iyi bir alışkanlıktır. - mailto: ve tel: Tıklandığında e-posta uygulamasını veya telefon aramasını başlatır. Mobil kullanıcılar için özellikle kullanışlıdır.
- download: Dosyanın tarayıcıda açılmak yerine indirilmesini sağlar; verdiğiniz değer indirilen dosyanın adı olur. Yalnızca aynı kaynaktaki (same-origin) dosyalarda çalışır.
- #id: Sayfa içinde, belirtilen
id'ye sahip elemana kaydırır. Bu yazının içindekiler tablosu da bu şekilde çalışır.
İpucu: Bağlantı metni, bağlamından bağımsız olarak anlamlı olmalıdır. "Buraya tıklayın" yerine "CV'mi indir" veya "GitHub profilim" gibi açıklayıcı metinler kullanın. Ekran okuyucu kullanıcıları sayfadaki bağlantıları tek bir liste halinde gezebilir ve on tane "buraya tıklayın" hiçbir şey ifade etmez.
Görseller
<img src="/ertu.png" alt="Ertuğrul Mert" width="200" height="200" />
- src: Görsel dosyasının yolu.
- alt: Görsel yüklenemediğinde gösterilen, ekran okuyucuların sesli okuduğu ve arama motorlarının görseli anlamak için kullandığı alternatif metin. Zorunludur.
- width ve height: Tarayıcının görsel yüklenmeden önce yer ayırmasını sağlar. Bu sayede görsel yüklendiğinde sayfa içeriği aşağı kaymaz (Layout Shift). Boyutları CSS ile değiştirseniz bile en-boy oranı için bu değerleri yazmanız önerilir.
İyi Bir alt Metni Yazmak
<!-- İyi: görseli anlatıyor -->
<img src="/ekip.jpg" alt="Ofiste bilgisayar başında birlikte çalışan üç geliştirici" />
<!-- Kötü: hiçbir bilgi vermiyor -->
<img src="/ekip.jpg" alt="resim" />
<!-- Dekoratif görsel: boş alt ile ekran okuyucu atlar -->
<img src="/ayirici-desen.svg" alt="" />
- Görselin içeriğini ve sayfadaki amacını kısaca anlatın.
- "Resim", "görsel", "fotoğraf" gibi ifadelerle başlamayın; ekran okuyucu zaten bunun bir görsel olduğunu söyler.
- Görsel bir bağlantının içindeyse, alt metni bağlantının nereye gittiğini anlatmalıdır.
- Yalnızca süs amaçlı görsellerde
alt=""(boş) kullanın.altniteliğini tamamen silmek ise farklıdır: bazı ekran okuyucular bu durumda dosya adını ("ayirici-desen-svg") okur.
Görsel Formatları
- JPEG: Fotoğraflar için; şeffaflık desteklemez.
- PNG: Şeffaflık gereken ve keskin kenarlı görseller (ekran görüntüleri) için; dosya boyutu büyük olabilir.
- WebP: JPEG ve PNG'ye göre genellikle çok daha küçük dosya boyutu sunar, şeffaflık ve animasyon destekler.
- AVIF: Bugün yaygın olarak desteklenen en verimli sıkıştırmaya sahip formatlardan biridir.
- SVG: Vektör tabanlıdır; logo ve ikonlar için idealdir, her boyutta keskin görünür.
- GIF: Basit animasyonlar için; ancak aynı animasyon video formatında çok daha küçük olur.
Performans ve Duyarlı (Responsive) Görseller
<!-- Ekranın altındaki görseller ancak yaklaşıldığında yüklenir -->
<img src="/proje.webp" alt="Proje ekran görüntüsü" width="800" height="450" loading="lazy" decoding="async" />
<!-- Tarayıcı ekran genişliğine göre en uygun dosyayı seçer -->
<img
src="/kapak-800.jpg"
srcset="/kapak-400.jpg 400w, /kapak-800.jpg 800w, /kapak-1600.jpg 1600w"
sizes="(max-width: 600px) 100vw, 800px"
alt="Blog kapak görseli"
width="800"
height="450"
/>
<!-- Tarayıcı desteklediği ilk formatı kullanır -->
<picture>
<source srcset="/kapak.avif" type="image/avif" />
<source srcset="/kapak.webp" type="image/webp" />
<img src="/kapak.jpg" alt="Blog kapak görseli" width="800" height="450" />
</picture>
<!-- Ekran boyutuna göre tamamen farklı bir görsel (art direction) -->
<picture>
<source media="(max-width: 600px)" srcset="/banner-dikey.jpg" />
<img src="/banner-yatay.jpg" alt="Kampanya afişi" />
</picture>
- loading="lazy": Görselin ekrana yaklaşıldığında yüklenmesini sağlar. Sayfa açıldığında hemen görünen ana görselde (hero) kullanmayın; aksi halde en önemli görsel geç yüklenir.
- srcset ve sizes: Tarayıcıya farklı boyutlarda görseller sunar; tarayıcı ekran genişliğine ve piksel yoğunluğuna göre en uygununu indirir. Mobil kullanıcılar gereksiz yere dev görseller indirmez.
- picture: Modern formatlar için yedekli (fallback) yapı kurmanızı veya ekran boyutuna göre tamamen farklı görseller göstermenizi sağlar. İçindeki
<img>zorunludur.
figure ve figcaption
<figure>
<img src="/dashboard.png" alt="Satış grafikleri ve kullanıcı istatistiklerini gösteren yönetim paneli" />
<figcaption>Şekil 1: Projenin yönetim paneli arayüzü.</figcaption>
</figure>
<figure>, ana metne referans verilen ancak kendi başına anlamlı olan içerikleri (görsel, diyagram, kod parçası, alıntı) sarar. <figcaption> ise bu içeriğin görünür açıklamasıdır.
Ses ve Video
<video controls width="640" poster="/video-kapak.jpg" preload="metadata">
<source src="/tanitim.webm" type="video/webm" />
<source src="/tanitim.mp4" type="video/mp4" />
<track src="/altyazi-tr.vtt" kind="subtitles" srclang="tr" label="Türkçe" default />
Tarayıcınız video etiketini desteklemiyor.
</video>
<!-- Arka plan videosu: otomatik oynatma için muted gereklidir -->
<video src="/arka-plan.mp4" autoplay muted loop playsinline></video>
<audio controls>
<source src="/podcast.mp3" type="audio/mpeg" />
<source src="/podcast.ogg" type="audio/ogg" />
Tarayıcınız audio etiketini desteklemiyor.
</audio>
- controls: Oynat, duraklat, ses ve tam ekran düğmelerini gösterir.
- autoplay: Medyayı otomatik başlatır. Tarayıcılar sesli otomatik oynatmayı engellediği için genellikle
mutedile birlikte kullanılması gerekir. - muted, loop: Sesi kapatır / medyayı sürekli tekrarlar.
- playsinline: iOS'ta videonun tam ekrana geçmeden sayfa içinde oynatılmasını sağlar.
- poster: Video oynatılmadan önce gösterilecek kapak görseli.
- preload:
none(hiçbir şey yükleme),metadata(yalnızca süre gibi bilgileri yükle) veyaauto(tarayıcı karar versin). - source: Birden fazla format sunar; tarayıcı desteklediği ilkini oynatır.
- track: WebVTT formatında altyazı ekler. Altyazılar işitme engelli kullanıcılar ve sessiz ortamda izleyenler için önemlidir.
iframe ile İçerik Gömme
<iframe>, sayfanızın içine başka bir web sayfasını gömmenizi sağlar. YouTube videoları, Google Haritalar ve CodePen örnekleri genellikle bu şekilde eklenir:
<iframe
width="560"
height="315"
src="https://www.youtube.com/embed/VIDEO_ID"
title="HTML eğitim videosu"
loading="lazy"
allow="autoplay; encrypted-media; picture-in-picture"
allowfullscreen
></iframe>
<!-- Güvenilmeyen içeriği kısıtlı izinlerle göm -->
<iframe src="https://example.com/widget" title="Harici widget" sandbox="allow-scripts"></iframe>
- title: Ekran okuyucuların iframe içeriğini tanımlaması için gereklidir.
- loading="lazy": iframe'ler ağırdır; ekran dışındaysa ertelemek performansı artırır.
- sandbox: Gömülen sayfanın yeteneklerini kısıtlar. Boş bırakıldığında script çalıştırma, form gönderme gibi her şey engellenir; izinler tek tek eklenir.
- Birçok site (bankalar, sosyal medya) güvenlik nedeniyle kendisinin iframe içine gömülmesini engeller.
Listeler
Sırasız ve Sıralı Listeler
<ul>
<li>Node.js</li>
<li>MongoDB</li>
<li>Next.js</li>
</ul>
<ol>
<li>Kurulum</li>
<li>Geliştirme</li>
<li>Yayınlama</li>
</ol>
<ul> (unordered list) sıranın önemli olmadığı listeler, <ol> (ordered list) ise adımlar veya sıralamalar gibi sıranın önemli olduğu listeler içindir. Sıralı listelerin davranışı niteliklerle değiştirilebilir:
<!-- 5'ten başlayan liste -->
<ol start="5">
<li>Beşinci adım</li>
<li>Altıncı adım</li>
</ol>
<!-- Geriye sayan liste (3, 2, 1) -->
<ol reversed>
<li>Bronz</li>
<li>Gümüş</li>
<li>Altın</li>
</ol>
<!-- Numaralandırma türü: 1, A, a, I, i -->
<ol type="I">
<li>Giriş</li>
<li>Gelişme</li>
<li>Sonuç</li>
</ol>
İç İçe Listeler
<ul>
<li>Frontend
<ul>
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
</ul>
</li>
<li>Backend
<ul>
<li>Node.js</li>
<li>MongoDB</li>
</ul>
</li>
</ul>
Dikkat: <ul> ve <ol> elementlerinin doğrudan çocuğu yalnızca <li> olabilir. Alt liste, doğrudan <ul> içine değil, bir <li>'nin içine yazılmalıdır. Sitelerdeki navigasyon menüleri de çoğunlukla bu yapıyla oluşturulur.
Tanım Listeleri
<dl>
<dt>HTML</dt>
<dd>Web sayfalarının yapısını tanımlayan işaretleme dili.</dd>
<dt>CSS</dt>
<dd>Web sayfalarının görünümünü belirleyen stil dili.</dd>
<dt>JavaScript</dt>
<dd>Web sayfalarına etkileşim kazandıran programlama dili.</dd>
</dl>
<dl> (description list), terim–açıklama veya anahtar–değer çiftleri içindir: sözlükler, SSS bölümleri, ürün özellikleri veya profil bilgileri (ör. "Konum: İstanbul") için idealdir. <dt> terimi, <dd> açıklamayı içerir.
Tablolar
Tablolar, satır ve sütunlardan oluşan veriler için kullanılır. En basit hali şöyledir:
<table>
<tr>
<th>İsim</th>
<th>Rol</th>
</tr>
<tr>
<td>Ertuğrul Mert</td>
<td>Developer</td>
</tr>
</table>
Eksiksiz Tablo Yapısı
Gerçek projelerde tabloları başlık, gövde ve alt bilgi bölümlerine ayırmak hem okunabilirliği hem de erişilebilirliği artırır:
<table>
<caption>2026 Proje Listesi</caption>
<thead>
<tr>
<th scope="col">Proje</th>
<th scope="col">Teknoloji</th>
<th scope="col">Durum</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Portfolyo</th>
<td>Next.js</td>
<td>Yayında</td>
</tr>
<tr>
<th scope="row">E-Ticaret API</th>
<td>Node.js, MongoDB</td>
<td>Geliştiriliyor</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="3">Toplam: 2 proje</td>
</tr>
</tfoot>
</table>
- caption: Tablonun başlığı;
<table>'ın ilk çocuğu olmalıdır. - thead, tbody, tfoot: Tablonun başlık, gövde ve alt bilgi bölümleri.
- tr: Bir satır (table row).
- th: Başlık hücresi.
scope="col"sütun başlığı,scope="row"satır başlığı olduğunu belirtir; ekran okuyucular her hücreyi okurken ilgili başlığı da söyler. - td: Veri hücresi (table data).
Hücre Birleştirme: colspan ve rowspan
<table>
<tr>
<th>Gün</th>
<th colspan="2">Program</th>
</tr>
<tr>
<td rowspan="2">Pazartesi</td>
<td>09:00</td>
<td>HTML</td>
</tr>
<tr>
<td>13:00</td>
<td>CSS</td>
</tr>
</table>
colspan bir hücrenin yatayda kaç sütunu kaplayacağını, rowspan ise dikeyde kaç satırı kaplayacağını belirler.
Önemli: Tablolar yalnızca tablo verisi içindir. 2000'lerin başında yaygın olan, sayfa düzenini tablolarla kurma alışkanlığından kaçının; sayfa düzeni için CSS Flexbox ve Grid kullanılır.
Formlar
Kullanıcıdan veri almak için <form> etiketi ve giriş elemanları kullanılır:
<form action="/submit" method="POST">
<label for="name">İsim:</label>
<input type="text" id="name" name="name" placeholder="Ertuğrul Mert" />
<label for="email">E-posta:</label>
<input type="email" id="email" name="email" required />
<button type="submit">Gönder</button>
</form>
action, method ve name
- action: Form verilerinin gönderileceği adres. Yazılmazsa form, bulunduğu sayfanın adresine gönderilir.
- method="GET": Veriler URL'e eklenir (
/arama?q=html). Arama ve filtreleme gibi veriyi değiştirmeyen işlemler için uygundur; sonuç sayfası yer imlerine eklenebilir. Şifre gibi hassas veriler için asla kullanılmamalıdır. - method="POST": Veriler isteğin gövdesinde (body) gönderilir. Giriş, kayıt, sipariş gibi veri oluşturan veya değiştiren işlemler için kullanılır.
- enctype="multipart/form-data": Form dosya yüklemesi içeriyorsa zorunludur.
- name: Sunucuya gönderilen verinin anahtarıdır.
nameniteliği olmayan alanlar gönderilmez!
<!-- GET: /arama?q=html şeklinde gönderilir -->
<form action="/arama" method="GET" role="search">
<label for="arama">Blogda ara</label>
<input type="search" id="arama" name="q" placeholder="ör. semantic html" />
<button type="submit">Ara</button>
</form>
label Kullanımı
Her form alanının bir <label>'ı olmalıdır. İki şekilde bağlanabilir:
<!-- 1. for ve id eşleştirmesi -->
<label for="email">E-posta</label>
<input type="email" id="email" name="email" />
<!-- 2. input'u label'ın içine almak -->
<label>
<input type="checkbox" name="bulten" />
Bültene abone ol
</label>
- Label'a tıklandığında ilgili alana odaklanılır; küçük checkbox'lara tıklamak çok kolaylaşır.
- Ekran okuyucular alana gelindiğinde label metnini okur; label olmadan kullanıcı alanın ne için olduğunu bilemez.
placeholderbir label yerine geçmez: yazmaya başlandığında kaybolur ve genellikle düşük kontrastlıdır.
Input Türleri
<input> elementi, type niteliğine göre bambaşka davranışlar sergiler:
<!-- Metin tabanlı -->
<input type="text" name="ad" />
<input type="email" name="email" />
<input type="password" name="sifre" />
<input type="number" name="yas" min="18" max="99" />
<input type="tel" name="telefon" />
<input type="url" name="website" />
<input type="search" name="arama" />
<!-- Tarih ve saat -->
<input type="date" name="dogum-tarihi" />
<input type="time" name="saat" />
<input type="datetime-local" name="randevu" />
<input type="month" name="ay" />
<input type="week" name="hafta" />
<!-- Diğer -->
<input type="color" name="renk" value="#3b82f6" />
<input type="range" name="ses" min="0" max="100" step="10" />
<input type="file" name="avatar" accept="image/png, image/jpeg" />
<input type="file" name="belgeler" multiple />
<input type="checkbox" name="kosullar" />
<input type="radio" name="plan" value="ucretsiz" />
<input type="hidden" name="kaynak" value="blog" />
Doğru type seçmek yalnızca doğrulama sağlamaz; mobil cihazlarda uygun klavyeyi de açar. email türünde @ işareti klavyede hazır gelir, tel türünde sayı tuş takımı açılır, date türünde ise yerleşik bir tarih seçici görünür. hidden türü kullanıcıya görünmeyen ancak formla birlikte gönderilen değerler içindir.
Checkbox ve Radio Butonları
<fieldset>
<legend>Hangi teknolojileri biliyorsunuz?</legend>
<label><input type="checkbox" name="teknoloji" value="html" checked /> HTML</label>
<label><input type="checkbox" name="teknoloji" value="css" /> CSS</label>
<label><input type="checkbox" name="teknoloji" value="js" /> JavaScript</label>
</fieldset>
<fieldset>
<legend>Deneyim seviyeniz</legend>
<label><input type="radio" name="seviye" value="baslangic" checked /> Başlangıç</label>
<label><input type="radio" name="seviye" value="orta" /> Orta</label>
<label><input type="radio" name="seviye" value="ileri" /> İleri</label>
</fieldset>
- Checkbox: Birden fazla seçenek işaretlenebilir.
- Radio: Aynı
namedeğerine sahip radio butonları bir grup oluşturur ve gruptan yalnızca biri seçilebilir. - value: Seçenek işaretlendiğinde sunucuya gönderilecek değerdir.
- fieldset ve legend: İlişkili alanları gruplar ve gruba bir başlık verir. Ekran okuyucular her seçenekte grup başlığını da bildirir.
Textarea, Select ve Datalist
<label for="mesaj">Mesajınız</label>
<textarea id="mesaj" name="mesaj" rows="5" maxlength="500"></textarea>
<label for="sehir">Şehir</label>
<select id="sehir" name="sehir">
<option value="">Seçiniz</option>
<optgroup label="Marmara">
<option value="istanbul">İstanbul</option>
<option value="bursa">Bursa</option>
</optgroup>
<optgroup label="İç Anadolu">
<option value="ankara" selected>Ankara</option>
<option value="konya">Konya</option>
</optgroup>
</select>
<label for="dil">Favori programlama diliniz</label>
<input list="diller" id="dil" name="dil" />
<datalist id="diller">
<option value="JavaScript"></option>
<option value="TypeScript"></option>
<option value="Python"></option>
<option value="Go"></option>
</datalist>
- textarea: Çok satırlı metin girişi. Varsayılan içerik
valueniteliğine değil, açılış ve kapanış etiketlerinin arasına yazılır. - select: Açılır liste.
optgroupseçenekleri gruplar,selectedvarsayılan seçimi belirler,multipleniteliği birden fazla seçime izin verir. - datalist: Bir input'a otomatik tamamlama önerileri ekler; select'ten farkı, kullanıcının listede olmayan bir değer de yazabilmesidir.
Butonlar
<button type="submit">Gönder</button>
<button type="reset">Formu Temizle</button>
<button type="button" id="tema-butonu">Temayı Değiştir</button>
- submit: Formu gönderir. Form içindeki bir butonun varsayılan türü budur.
- reset: Tüm alanları başlangıç değerlerine döndürür. Kullanıcıların yanlışlıkla tıklayıp tüm verilerini kaybetmesine yol açabileceği için nadiren kullanılır.
- button: Varsayılan hiçbir davranışı yoktur; JavaScript ile işlem yapmak için kullanılır.
Sık yapılan hata: Form içinde JavaScript ile bir iş yapan butona type="button" yazmayı unutmak. Bu durumda buton formu gönderir ve sayfa yenilenir. Ayrıca kural basittir: başka bir sayfaya gidiliyorsa <a>, sayfada bir işlem yapılıyorsa <button> kullanın.
Yerleşik Form Doğrulama
HTML, JavaScript yazmadan temel doğrulama yapabilir. Tarayıcı, kurallara uymayan bir formu göndermez ve kullanıcıya bir uyarı gösterir (örneği kısa tutmak için label'lar çıkarılmıştır):
<form action="/kaydet" method="POST">
<input type="text" name="kullanici" required minlength="3" maxlength="20" />
<input type="number" name="adet" min="1" max="10" step="1" />
<!-- 5 haneli posta kodu -->
<input type="text" name="posta-kodu" pattern="[0-9]{5}" title="5 haneli posta kodu girin" />
<input type="email" name="email" required autocomplete="email" />
<input type="text" name="uye-no" value="TR-1024" readonly />
<input type="text" name="eski-alan" disabled />
<button type="submit">Kaydet</button>
</form>
- required: Alanın doldurulması zorunludur.
- minlength / maxlength: Minimum ve maksimum karakter sayısı.
- min / max / step: Sayı ve tarih alanları için alt sınır, üst sınır ve artış miktarı.
- pattern: Değerin uyması gereken düzenli ifade (regex).
titleniteliği hata mesajında ipucu olarak gösterilir. - autocomplete: Tarayıcının kayıtlı bilgileri otomatik doldurmasına yardımcı olur.
name,email,tel,street-address,current-password,new-passwordveone-time-codesık kullanılan değerlerdir. - autofocus: Sayfa yüklendiğinde alana otomatik odaklanır.
- readonly ve disabled farkı: İkisi de düzenlemeyi engeller; ancak
readonlyalanlar formla birlikte gönderilir,disabledalanlar gönderilmez ve odaklanılamaz. - novalidate:
<form>etiketine eklendiğinde tarayıcı doğrulamasını kapatır (doğrulamayı tamamen JavaScript ile yapacaksanız).
Önemli: Tarayıcı doğrulaması kullanıcı deneyimi içindir, güvenlik için değil. Kötü niyetli biri bu kontrolleri DevTools ile saniyeler içinde atlatabilir. Gelen verileri her zaman sunucu tarafında da doğrulayın.
progress ve meter
<label for="yukleme">Dosya yükleniyor:</label>
<progress id="yukleme" value="70" max="100">%70</progress>
<label for="disk">Disk kullanımı:</label>
<meter id="disk" value="0.8" min="0" max="1" low="0.3" high="0.7" optimum="0.2">%80</meter>
<progress> bir görevin ilerleyişini (dosya yükleme, adım adım form), <meter> ise bilinen bir aralıktaki ölçümü (disk doluluğu, şifre gücü, puan) gösterir. value verilmeyen bir progress, süresi belirsiz bir yükleme animasyonu olarak görünür.
Eksiksiz Bir Kayıt Formu
Öğrendiklerimizi birleştirerek gerçek hayatta kullanılabilecek bir form oluşturalım:
<form action="/kayit" method="POST" enctype="multipart/form-data">
<fieldset>
<legend>Hesap Bilgileri</legend>
<label for="kayit-ad">Ad Soyad</label>
<input type="text" id="kayit-ad" name="ad" autocomplete="name" required />
<label for="kayit-email">E-posta</label>
<input type="email" id="kayit-email" name="email" autocomplete="email" required />
<label for="kayit-sifre">Şifre (en az 8 karakter)</label>
<input type="password" id="kayit-sifre" name="sifre" autocomplete="new-password" minlength="8" required />
</fieldset>
<fieldset>
<legend>Profil</legend>
<label for="kayit-avatar">Profil fotoğrafı</label>
<input type="file" id="kayit-avatar" name="avatar" accept="image/*" />
<label for="kayit-hakkinda">Hakkınızda</label>
<textarea id="kayit-hakkinda" name="hakkinda" rows="4" maxlength="300"></textarea>
</fieldset>
<label>
<input type="checkbox" name="sozlesme" required />
Kullanım koşullarını okudum ve kabul ediyorum.
</label>
<button type="submit">Hesap Oluştur</button>
</form>
Block ve Inline Elementler
HTML elementleri varsayılan olarak iki temel yerleşim davranışından birini gösterir:
- Block elementler: Her zaman yeni bir satırda başlar ve bulundukları alanın tüm genişliğini kaplar. Örnekler:
div,p,h1–h6,ul,ol,li,section,article,header,footer,form,table,blockquote,pre. - Inline elementler: Metnin akışı içinde yer alır ve yalnızca içerikleri kadar yer kaplar. Örnekler:
span,a,strong,em,img,code,label,button,input.
<div>Bu bir block element — tüm satırı kaplar.</div>
<div>Bu da yeni bir satırda başlar.</div>
<span>Inline elementler</span> <strong>yan yana</strong> <a href="#">dizilir</a>.
Bu varsayılan davranış CSS'teki display özelliğiyle değiştirilebilir; ancak elementin anlamı değişmez. Bu yüzden elementi görünüşüne göre değil, anlamına göre seçin.
div ve span
<div> (block) ve <span> (inline) hiçbir anlam taşımayan genel amaçlı kapsayıcılardır. Uygun bir semantic element olmadığında, genellikle CSS ile stillendirmek veya JavaScript ile seçmek amacıyla kullanılırlar:
<div class="kart">
<h3>Proje Adı</h3>
<p>Proje açıklaması burada yer alır. <span class="rozet">Yeni</span></p>
</div>
Semantic HTML
Semantic (anlamsal) etiketler, içeriğin ne anlama geldiğini hem tarayıcıya hem de geliştiricilere açıkça belirtir; bu da erişilebilirlik ve SEO açısından önemlidir.
<header>Site başlığı ve navigasyon</header>
<nav>Menü bağlantıları</nav>
<main>
<article>Ana içerik</article>
<aside>Yan bilgi</aside>
</main>
<footer>Alt bilgi</footer>
Bunun yerine her şeyi <div> ile yazmak da mümkündür, ancak semantic etiketler kodu daha okunabilir kılar ve ekran okuyucuların sayfa yapısını doğru yorumlamasına yardımcı olur.
Semantic Etiketler ve Görevleri
- header: Sayfanın veya bir bölümün giriş kısmı: logo, başlık, navigasyon. Bir sayfada birden fazla olabilir; örneğin her
<article>'ın kendi header'ı olabilir. - nav: Ana navigasyon bağlantıları. Her bağlantı grubu nav değildir; yalnızca site içi önemli gezinti blokları için kullanılır.
- main: Sayfanın benzersiz ana içeriği. Sayfada yalnızca bir tane (görünür) main bulunmalı ve header, footer, nav gibi tekrarlanan bölümleri içermemelidir.
- article: Kendi başına anlamlı ve bağımsız olarak paylaşılabilecek içerik: blog yazısı, haber, ürün kartı, kullanıcı yorumu.
- section: Bir dokümanın tematik bölümü; genellikle bir başlıkla başlar.
- aside: Ana içerikle dolaylı olarak ilişkili içerik: kenar çubuğu, ilgili yazılar, yazar bilgisi, reklam.
- footer: Sayfanın veya bir bölümün alt bilgisi: telif hakkı, iletişim, sosyal medya bağlantıları.
- search: Arama formunu veya filtreleme alanını saran, nispeten yeni bir elementtir.
- figure, time, address: Önceki bölümlerde gördüğümüz, içeriğe anlam katan diğer semantic elementler.
article mı, section mı, div mi?
Bu üçü sık karıştırılır. Karar vermek için şu soruları sorabilirsiniz:
- İçerik tek başına başka bir sitede veya RSS akışında yayınlansa anlamlı olur mu? → article
- İçerik, bir başlığı olan tematik bir bölüm mü? → section
- Sadece stil veya düzen için bir sarmalayıcıya mı ihtiyacım var? → div
Div Çorbası ve Semantic Yapı
<!-- Kötü: "div çorbası" -->
<div class="header">
<div class="nav">...</div>
</div>
<div class="content">
<div class="post">...</div>
</div>
<div class="footer">...</div>
<!-- İyi: semantic yapı -->
<header>
<nav>...</nav>
</header>
<main>
<article>...</article>
</main>
<footer>...</footer>
İki yapı tarayıcıda aynı görünebilir, ancak ikincisinde ekran okuyucular "ana içeriğe atla", "navigasyona git" gibi kısayollar sunabilir; arama motorları da asıl içeriğin nerede olduğunu çok daha net anlar. Gerçek bir blog sayfasının iskeleti şöyle görünebilir:
<body>
<header>
<a href="/" class="logo">ertucuk</a>
<nav aria-label="Ana menü">
<ul>
<li><a href="/">Ana Sayfa</a></li>
<li><a href="/projeler">Projeler</a></li>
<li><a href="/blog" aria-current="page">Blog</a></li>
</ul>
</nav>
</header>
<main>
<article>
<header>
<h1>HTML'e Giriş</h1>
<p>Yayın tarihi: <time datetime="2026-02-18">18 Şubat 2026</time></p>
</header>
<section>
<h2>HTML Nedir?</h2>
<p>...</p>
</section>
<section>
<h2>Temel Doküman Yapısı</h2>
<p>...</p>
</section>
<footer>
<p>Etiketler: HTML, Web, Frontend</p>
</footer>
</article>
<aside>
<h2>İlgili Yazılar</h2>
<ul>
<li><a href="/blog/css">CSS'e Giriş</a></li>
<li><a href="/blog/javascript">JavaScript'e Giriş</a></li>
</ul>
</aside>
</main>
<footer>
<p>© 2026 Ertuğrul Mert</p>
</footer>
</body>
Etkileşimli Yerleşik Elementler
Eskiden JavaScript kütüphaneleri gerektiren birçok bileşen artık HTML'in kendisinde yerleşik olarak bulunuyor.
details ve summary: Açılır Kapanır İçerik
<details>
<summary>HTML bir programlama dili midir?</summary>
<p>Hayır. HTML bir işaretleme dilidir; mantık veya hesaplama içermez.</p>
</details>
<details open>
<summary>Bu bölüm varsayılan olarak açık gelir</summary>
<p>open niteliği sayesinde içerik ilk yüklemede görünür.</p>
</details>
<!-- Aynı name değerine sahip olanlar akordeon gibi davranır -->
<details name="sss">
<summary>Soru 1</summary>
<p>Cevap 1</p>
</details>
<details name="sss">
<summary>Soru 2</summary>
<p>Cevap 2</p>
</details>
SSS bölümleri ve akordeon menüler için idealdir. Klavyeyle kullanılabilir ve ekran okuyucular açık/kapalı durumunu otomatik olarak bildirir. Aynı name değerine sahip details elementlerinden biri açıldığında diğerleri otomatik olarak kapanır.
dialog: Yerleşik Modal Pencere
<button type="button" id="modal-ac">Modalı Aç</button>
<dialog id="modal">
<h2>Merhaba!</h2>
<p>Bu pencere yerleşik dialog elementiyle oluşturuldu.</p>
<form method="dialog">
<button>Kapat</button>
</form>
</dialog>
<script>
const modal = document.getElementById("modal");
document.getElementById("modal-ac").addEventListener("click", () => {
modal.showModal();
});
</script>
showModal() ile açılan bir dialog; arka planı etkileşime kapatır, odağı pencerenin içinde tutar ve Esc tuşuyla kapanır. method="dialog" olan bir form gönderildiğinde dialog otomatik olarak kapanır. Arka plan karartması ise CSS'te ::backdrop ile stillendirilir.
popover: JavaScript'siz Açılır Pencere
<button popovertarget="profil-menu">Profil</button>
<div id="profil-menu" popover>
<ul>
<li><a href="/ayarlar">Ayarlar</a></li>
<li><a href="/cikis">Çıkış Yap</a></li>
</ul>
</div>
popover niteliği, tek satır JavaScript yazmadan açılır menüler, ipuçları ve bildirimler oluşturmanızı sağlar. Dışarı tıklandığında veya Esc tuşuna basıldığında otomatik olarak kapanır ve her zaman sayfadaki diğer içeriklerin üstünde görünür.
Nitelikler (Attributes)
Etiketlere ek bilgi vermek için nitelikler kullanılır:
<a href="https://ertucuk.com" target="_blank" rel="noopener">
Portfolyom
</a>
<input type="checkbox" checked disabled />
- id: Elemente benzersiz bir kimlik verir.
- class: CSS ile stillendirme için grup tanımlar.
- href / src: Bağlantı veya kaynak adresini belirtir.
Nitelik değerlerini her zaman çift tırnak içinde yazın. Tırnaksız yazılan class=kart vurgulu gibi bir değerde tarayıcı yalnızca kart'ı sınıf olarak algılar.
Global Nitelikler
Aşağıdaki nitelikler tüm HTML elementlerinde kullanılabilir:
- id: Sayfada benzersiz olmalıdır; aynı id iki kez kullanılmamalıdır. Sayfa içi bağlantılar,
label foreşleştirmesi ve JavaScript seçimleri için kullanılır. - class: Birden fazla değer boşlukla ayrılarak verilebilir:
class="kart kart-aktif". - style: Satır içi CSS. Bakımı zor olduğundan mümkün olduğunca kaçınılmalıdır.
- title: Fareyle üzerine gelindiğinde ipucu gösterir. Dokunmatik ekranlarda görünmediği için önemli bilgileri yalnızca buraya yazmayın.
- lang: Farklı dildeki içeriği belirtir:
<span lang="en">Hello</span>. - dir: Yazı yönü; Arapça gibi sağdan sola yazılan diller için
dir="rtl". - hidden: Elementi gizler.
- tabindex:
0elementi klavye odak sırasına ekler,-1yalnızca JavaScript ile odaklanılabilir yapar. Pozitif değerler odak sırasını bozduğu için kullanılmamalıdır. - contenteditable: Elementin içeriğini kullanıcı tarafından düzenlenebilir yapar.
- draggable: Elementin sürüklenebilir olup olmadığını belirtir.
- spellcheck: Yazım denetimini açar veya kapatır.
- translate="no": Marka ve ürün isimlerinin otomatik çeviri araçları tarafından çevrilmesini engeller.
- inert: Elementi ve içindeki her şeyi tıklama, odaklanma ve ekran okuyuculara kapatır.
<p id="giris" class="metin vurgulu" title="Kısa açıklama">...</p>
<div contenteditable="true">Bu metni doğrudan düzenleyebilirsiniz.</div>
<p>Markamın adı <span translate="no">ertucuk</span>.</p>
<p hidden>Bu paragraf sayfada görünmez.</p>
Boolean Nitelikler
Bazı niteliklerin bir değere ihtiyacı yoktur; yalnızca varlıkları yeterlidir: checked, disabled, required, readonly, hidden, autoplay, muted, loop, controls, open, multiple, defer, async.
<input type="checkbox" checked />
<input type="checkbox" checked="checked" /> <!-- Aynı anlam -->
<!-- Dikkat: bu buton HÂLÂ devre dışı! -->
<button disabled="false">Tıklanamaz</button>
Boolean niteliklerde değerin ne olduğu önemli değildir; disabled="false" yazmak bile elementi devre dışı bırakır. Niteliği kaldırmak için onu tamamen silmeniz gerekir.
data-* Nitelikleri
Elementlere kendi özel verilerinizi eklemek için data- ön ekiyle başlayan nitelikler kullanılır. Bu veriler JavaScript'te dataset üzerinden okunabilir:
<button class="sepete-ekle" data-urun-id="42" data-fiyat="199.90">
Sepete Ekle
</button>
<script>
const buton = document.querySelector(".sepete-ekle");
console.log(buton.dataset.urunId); // "42"
console.log(buton.dataset.fiyat); // "199.90"
</script>
Tire ile yazılan isimler JavaScript'te otomatik olarak camelCase'e dönüşür: data-urun-id → dataset.urunId.
CSS ve JavaScript'i HTML'e Bağlamak
CSS Ekleme Yöntemleri
<!-- 1. Harici dosya (önerilen) -->
<link rel="stylesheet" href="/css/style.css" />
<!-- 2. Sayfa içi (internal) -->
<style>
body {
font-family: system-ui, sans-serif;
line-height: 1.6;
}
</style>
<!-- 3. Satır içi (inline) -->
<p style="color: tomato; font-weight: bold;">Kırmızı ve kalın metin</p>
Harici CSS dosyası tarayıcı tarafından önbelleğe alınır, birden fazla sayfada tekrar kullanılabilir ve HTML ile stilin birbirinden ayrı tutulmasını sağlar. Satır içi stiller ise en yüksek önceliğe sahip olduğundan üzerine yazılması zordur ve bakımı karmaşıklaştırır.
JavaScript Ekleme: defer, async ve module
<!-- Varsayılan: HTML ayrıştırmasını durdurur -->
<script src="/js/app.js"></script>
<!-- defer: arka planda indirilir, HTML tamamen ayrıştırıldıktan sonra sırayla çalışır -->
<script src="/js/app.js" defer></script>
<!-- async: arka planda indirilir, hazır olduğu an çalışır (sıra garantisi yok) -->
<script src="/js/analytics.js" async></script>
<!-- module: import/export kullanılabilir, varsayılan olarak defer gibi davranır -->
<script type="module" src="/js/main.js"></script>
<noscript>Bu sitenin tüm özelliklerini kullanmak için JavaScript'i etkinleştirin.</noscript>
- Varsayılan: Tarayıcı script'e geldiğinde sayfayı işlemeyi durdurur, script'i indirip çalıştırır, sonra devam eder. Bu yüzden eskiden script'ler
</body>'den hemen önce yazılırdı. - defer: DOM'a erişen kodlar için en iyi seçenektir.
<head>içine yazılabilir ve sayfa hazır olduğunda çalışır. - async: Sayfadan bağımsız çalışan script'ler (analitik, reklam) içindir.
- noscript: JavaScript kapalıysa gösterilecek içerik.
Erişilebilirlik (Accessibility)
Erişilebilirlik (kısaca a11y), web sitenizin görme, işitme, motor veya bilişsel engeli olan kişiler dahil herkes tarafından kullanılabilmesidir. Ekran okuyucu kullananlar, yalnızca klavyeyle gezinenler, ekranı büyüterek okuyanlar veya kolu kırık olduğu için geçici olarak tek eliyle bilgisayar kullananlar... İyi haber şu: doğru yazılmış HTML, erişilebilirliğin büyük kısmını kendiliğinden sağlar.
Temel kontrol listesi:
<html>etiketindelangniteliği var mı?- Tüm anlamlı görsellerin açıklayıcı bir
altmetni var mı? - Her form alanının bir
<label>'ı var mı? - Başlık hiyerarşisi (
h1→h2→h3) mantıklı mı? - Semantic yapı (
header,nav,main,footer) kullanılmış mı? - Tıklanabilir her şey
<button>veya<a>mı? - Sayfadaki her şeye yalnızca klavyeyle (Tab, Enter, Space) ulaşılabiliyor mu? Odak göstergesi (outline) görünüyor mu?
- Bilgi yalnızca renkle mi aktarılıyor? (Örneğin hatalı alanları sadece kırmızıyla değil, bir mesajla da belirtin.)
- Metin ve arka plan arasında yeterli kontrast var mı?
- Videolarda altyazı var mı?
Neden div Yerine button?
<!-- Kötü: klavyeyle odaklanılamaz, Enter/Space çalışmaz,
ekran okuyucu bunun bir buton olduğunu söylemez -->
<div class="buton" onclick="kaydet()">Kaydet</div>
<!-- İyi: tüm bu davranışlar yerleşik olarak gelir -->
<button type="button" onclick="kaydet()">Kaydet</button>
Tıklanabilir bir <div>'i gerçek bir butonla aynı seviyeye getirmek için role, tabindex ve klavye olay dinleyicileri eklemeniz gerekir. <button> ise tüm bunları ücretsiz olarak sunar.
ARIA Temelleri
ARIA (Accessible Rich Internet Applications), yerleşik HTML'in yetersiz kaldığı durumlarda yardımcı teknolojilere ek bilgi veren niteliklerdir. ARIA'nın ilk kuralı şudur: İşinizi gören yerleşik bir HTML elementi varsa ARIA kullanmayın. Yanlış kullanılan ARIA, hiç kullanılmamasından daha kötüdür.
<!-- Görünür metni olmayan ikon buton -->
<button type="button" aria-label="Menüyü kapat">
<svg aria-hidden="true" width="24" height="24">...</svg>
</button>
<!-- Açılıp kapanan menünün durumu -->
<button type="button" aria-expanded="false" aria-controls="mobil-menu">Menü</button>
<ul id="mobil-menu" hidden>...</ul>
<!-- Dinamik olarak değişen bildirimleri ekran okuyucuya duyur -->
<div aria-live="polite">Form başarıyla gönderildi.</div>
<!-- Navigasyonda aktif sayfa -->
<a href="/blog" aria-current="page">Blog</a>
- aria-label: Görünür metni olmayan elementlere erişilebilir bir isim verir.
- aria-hidden="true": Dekoratif elementleri ekran okuyuculardan gizler.
- aria-expanded: Açılır bir içeriğin açık mı kapalı mı olduğunu bildirir (JavaScript ile güncellenmelidir).
- aria-live: İçeriği değiştiğinde ekran okuyucunun bunu duyurmasını sağlar.
- aria-current: Bir grup içindeki aktif öğeyi (ör. bulunulan sayfa) belirtir.
"İçeriğe Atla" Bağlantısı
<body>
<a href="#ana-icerik" class="skip-link">İçeriğe atla</a>
<header>...uzun bir navigasyon menüsü...</header>
<main id="ana-icerik">...</main>
</body>
Klavye kullanıcılarının her sayfada onlarca menü bağlantısından Tab ile geçmek zorunda kalmaması için sayfanın en başına konur. Genellikle CSS ile gizlenir ve yalnızca klavyeyle odaklanıldığında görünür hale gelir.
SEO İçin HTML
Arama motorları sayfanızı HTML üzerinden anlar. İyi yapılandırılmış HTML, SEO'nun en sağlam temelidir:
- Benzersiz bir title: Her sayfa için açıklayıcı, 50–60 karakter civarında bir başlık.
- Meta description: Arama sonuçlarındaki tıklanma oranını doğrudan etkiler.
- Tek bir h1 ve mantıklı başlık hiyerarşisi: Sayfanın konusunu ve yapısını netleştirir.
- Semantic etiketler: Ana içeriğin, navigasyonun ve yan içeriklerin ayırt edilmesini sağlar.
- Açıklayıcı alt metinleri: Görsel aramalarda bulunmanızı sağlar.
- Anlamlı bağlantı metinleri ve iç bağlantılar: Sayfalar arası ilişkiyi kurar.
- Canonical URL: Kopya içerik sorunlarını önler.
- Hız ve mobil uyum: Google, sayfa deneyimini (Core Web Vitals) sıralamada dikkate alır.
Yapılandırılmış Veri (JSON-LD)
Yapılandırılmış veri, arama motorlarına içeriğinizi standart bir dille anlatır ve arama sonuçlarında yıldız puanı, yazar, tarih gibi zengin sonuçlar görünmesine yardımcı olabilir:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": "HTML'e Giriş: Web'in Temel Yapı Taşı",
"datePublished": "2026-02-18",
"image": "https://ertucuk.com/html-cover.svg",
"author": {
"@type": "Person",
"name": "Ertuğrul Mert",
"url": "https://ertucuk.com"
}
}
</script>
Performans İpuçları
<head>
<!-- Harici bir sunucuya önceden bağlantı kur -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<!-- Kritik bir kaynağı erkenden yükle -->
<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin />
<!-- Script'ler sayfanın işlenmesini engellemesin -->
<script src="/js/main.js" defer></script>
</head>
<!-- En önemli (ilk görünen) görsele öncelik ver -->
<img src="/hero.webp" alt="..." width="1200" height="600" fetchpriority="high" />
<!-- Ekran dışındaki görselleri ertele -->
<img src="/galeri-1.webp" alt="..." width="400" height="300" loading="lazy" />
- Görsellere her zaman
widthveheightverin; sayfa yüklenirken içerik kaymasını önler. - Ekran dışındaki görsel ve iframe'lerde
loading="lazy"kullanın, ilk görünen ana görselde ise kullanmayın. - WebP ve AVIF gibi modern görsel formatlarını tercih edin.
- Script'leri
deferveyaasyncile yükleyin. - Kullanılmayan CSS ve JavaScript dosyalarını sayfaya eklemeyin.
- DOM'u gereksiz yere derinleştirmeyin; binlerce iç içe
divsayfayı yavaşlatır.
Diğer Faydalı Elementler
template
<template id="kart-sablonu">
<article class="kart">
<h3 class="kart-baslik"></h3>
<p class="kart-aciklama"></p>
</article>
</template>
<template> içindeki içerik sayfada görüntülenmez. JavaScript ile kopyalanıp verilerle doldurularak sayfaya eklenmek üzere bekleyen bir şablon görevi görür.
svg ve canvas
<!-- SVG: vektörel, ölçeklenebilir grafik -->
<svg width="100" height="100" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill="#3b82f6" />
</svg>
<!-- Canvas: JavaScript ile piksel tabanlı çizim alanı -->
<canvas id="grafik" width="400" height="200">
Tarayıcınız canvas elementini desteklemiyor.
</canvas>
SVG; logo, ikon ve basit illüstrasyonlar için idealdir, her boyutta keskin kalır ve CSS ile stillendirilebilir. Canvas ise oyunlar, grafikler ve görüntü işleme gibi JavaScript ile piksel piksel çizim gerektiren durumlar içindir.
Kullanımdan Kalkan Etiketler
Eski eğitimlerde veya projelerde karşınıza çıkabilecek, ancak artık kullanılmaması gereken bazı etiketler ve modern karşılıkları:
<font>→ CSS'tekifont-family,font-sizevecolor<center>→ CSS'tekitext-align: centerveya Flexbox/Grid<marquee>ve<blink>→ CSS animasyonları<big>,<tt>,<strike>→ CSS veya<s><frame>ve<frameset>→<iframe>veya modern sayfa düzenlerialign,bgcolor,bordergibi görünüm nitelikleri → CSS
Genel kural: HTML yapıyı, CSS görünümü tanımlar. Görünümle ilgili her şey CSS'e aittir.
Sık Yapılan Hatalar
- DOCTYPE'ı unutmak: Tarayıcı eski uyumluluk moduna geçer.
- Etiketleri kapatmamak veya çapraz kapatmak.
- Paragraf içine block element koymak:
<p>içine<div>yazılamaz; tarayıcı paragrafı div'den önce otomatik olarak kapatır ve beklenmedik bir yapı ortaya çıkar. - Aynı id'yi birden fazla kez kullanmak.
- Görsellerde alt niteliğini unutmak.
- Boşluk vermek için br veya kullanmak: Boşluk CSS'in işidir.
- Her şeyi div ile yazmak: Uygun semantic element varsa onu kullanın.
- Başlık etiketlerini yazı boyutu için seçmek: Küçük bir başlık istiyorsanız h5 değil, doğru seviyedeki başlığı kullanıp CSS ile küçültün.
- Tıklanabilir div'ler oluşturmak: Bunun yerine button veya a kullanın.
- label yerine yalnızca placeholder kullanmak.
- Tablolarla sayfa düzeni kurmak.
- Nitelik değerlerini tırnaksız yazmak.
<!-- Yanlış -->
<p>Merhaba <div>Dünya</div></p>
<img src="logo.png">
<div id="kart"></div>
<div id="kart"></div>
<div onclick="gonder()">Gönder</div>
<!-- Doğru -->
<p>Merhaba <span>Dünya</span></p>
<img src="logo.png" alt="ertucuk logosu">
<div id="kart-1"></div>
<div id="kart-2"></div>
<button type="button" onclick="gonder()">Gönder</button>
Doğrulama ve Hata Ayıklama Araçları
- W3C Markup Validation Service: HTML'inizi standartlara göre kontrol eder; kapanmamış etiketleri, geçersiz iç içe yazımları ve eksik nitelikleri listeler.
- DevTools Elements paneli: Tarayıcının oluşturduğu gerçek DOM'u gösterir. Ctrl + U ile açılan "Sayfa Kaynağını Görüntüle" ise sunucudan gelen ham HTML'dir; ikisi arasındaki fark, tarayıcının veya JavaScript'in yaptığı değişiklikleri ortaya koyar.
- Lighthouse: Chrome DevTools içinde yer alır; sayfanızı erişilebilirlik, SEO, performans ve en iyi uygulamalar açısından puanlar ve iyileştirme önerileri sunar.
- Editör eklentileri: Prettier kodunuzu otomatik biçimlendirir, HTMLHint gibi araçlar ise hataları siz yazarken gösterir.
Hepsi Bir Arada: Eksiksiz Bir Portfolyo Sayfası
Bu yazıda öğrendiğimiz neredeyse her şeyi bir araya getiren, gerçek bir projede doğrudan kullanılabilecek bir sayfa:
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Ertuğrul Mert | Yazılım Geliştirici</title>
<meta name="description" content="Self-taught yazılım geliştirici Ertuğrul Mert'in kişisel portfolyosu." />
<link rel="icon" href="/favicon.ico" />
<link rel="stylesheet" href="/css/style.css" />
<script src="/js/main.js" defer></script>
</head>
<body>
<a href="#ana-icerik" class="skip-link">İçeriğe atla</a>
<header>
<a href="/" class="logo">ertucuk</a>
<nav aria-label="Ana menü">
<ul>
<li><a href="#hakkimda">Hakkımda</a></li>
<li><a href="#projeler">Projeler</a></li>
<li><a href="#iletisim">İletişim</a></li>
</ul>
</nav>
</header>
<main id="ana-icerik">
<section id="hakkimda">
<img src="/ertu.png" alt="Ertuğrul Mert'in profil fotoğrafı" width="200" height="200" />
<h1>Merhaba, Ben Ertuğrul Mert</h1>
<p>
<strong>Self-taught</strong> bir geliştiriciyim. Node.js, MongoDB
ve Next.js ile modern web uygulamaları geliştiriyorum.
</p>
<a href="/cv.pdf" download>CV'mi indir</a>
</section>
<section id="projeler">
<h2>Projeler</h2>
<article class="proje-karti">
<figure>
<img src="/projeler/portfolyo.webp" alt="Portfolyo sitesinin ana sayfası" width="600" height="340" loading="lazy" />
<figcaption>Portfolyo sitesinin ana sayfası</figcaption>
</figure>
<h3>Portfolyo Sitesi</h3>
<p>Next.js ile geliştirilmiş kişisel portfolyo ve blog sitesi.</p>
<ul>
<li>Next.js</li>
<li>Tailwind CSS</li>
</ul>
<a href="https://github.com/ertucuk" target="_blank" rel="noopener noreferrer">Kaynak kodu</a>
</article>
</section>
<section id="sss">
<h2>Sıkça Sorulan Sorular</h2>
<details name="sss">
<summary>Hangi teknolojileri kullanıyorsun?</summary>
<p>Ağırlıklı olarak Node.js, MongoDB ve Next.js.</p>
</details>
</section>
<section id="iletisim">
<h2>İletişim</h2>
<form action="/iletisim" method="POST">
<label for="ad">İsim</label>
<input type="text" id="ad" name="ad" autocomplete="name" required />
<label for="eposta">E-posta</label>
<input type="email" id="eposta" name="eposta" autocomplete="email" required />
<label for="mesaj">Mesajınız</label>
<textarea id="mesaj" name="mesaj" rows="5" required></textarea>
<button type="submit">Gönder</button>
</form>
</section>
</main>
<footer>
<p>© 2026 Ertuğrul Mert</p>
<a href="https://github.com/ertucuk" target="_blank" rel="noopener noreferrer">GitHub</a>
</footer>
</body>
</html>
Hızlı Başvuru Listesi
- Doküman yapısı:
!DOCTYPE,html,head,body,title,meta,link,style,script,noscript - Bölümleme:
header,nav,main,article,section,aside,footer,search,address - Metin blokları:
h1–h6,p,br,hr,blockquote,pre,div - Satır içi anlam:
strong,em,b,i,u,s,mark,small,sub,sup,del,ins,q,cite,abbr,time,code,kbd,samp,var,span - Bağlantı ve medya:
a,img,picture,source,figure,figcaption,video,audio,track,iframe,svg,canvas - Listeler:
ul,ol,li,dl,dt,dd - Tablolar:
table,caption,thead,tbody,tfoot,tr,th,td - Formlar:
form,label,input,textarea,select,option,optgroup,datalist,button,fieldset,legend,progress,meter - Etkileşim ve diğer:
details,summary,dialog,template,popoverniteliği
Sıkça Sorulan Sorular
HTML bir programlama dili mi?
Hayır. HTML bir işaretleme dilidir; içeriğin yapısını tanımlar ancak mantık, koşul veya döngü içermez. Programlama tarafı JavaScript ile başlar. Yine de HTML, her web geliştiricisinin bilmesi gereken ilk ve en temel teknolojidir.
Tüm etiketleri ezberlemem gerekiyor mu?
Hayır. Günlük işlerin büyük kısmı 30–40 etiketle yapılır ve bunlar pratik yaptıkça kendiliğinden akılda kalır. Geri kalanı için MDN gibi kaynaklara bakmak profesyonel geliştiricilerin de her gün yaptığı bir şeydir.
React veya Next.js kullanıyorsam HTML öğrenmeli miyim?
Kesinlikle. JSX, HTML'e çok benzeyen bir sözdizimidir ve sonunda tarayıcıya HTML olarak ulaşır. Semantic yapı, form davranışları, erişilebilirlik ve SEO bilgisi hangi framework'ü kullanırsanız kullanın doğrudan işinize yarar. Framework'ler değişir, HTML kalır.
HTML öğrenmek ne kadar sürer?
Temelleri birkaç gün içinde öğrenip basit sayfalar yazmaya başlayabilirsiniz. Semantic HTML, erişilebilirlik ve form detaylarında gerçekten ustalaşmak ise gerçek projelerde geçen zamanla gelir. En hızlı yol: okuduklarınızı hemen kendi projelerinizde uygulamak.
Sonraki Adımlar ve Kaynaklar
HTML temellerini öğrendikten sonra izleyebileceğiniz yol:
- CSS: Seçiciler, kutu modeli (box model), Flexbox, Grid ve duyarlı (responsive) tasarım.
- JavaScript: DOM manipülasyonu, olaylar (events) ve form işlemleri.
- Pratik: Kendi portfolyo sayfanızı sıfırdan, hiçbir framework kullanmadan yazın. Beğendiğiniz siteleri DevTools ile inceleyip nasıl yapılandırıldıklarına bakın.
- Erişilebilirlik testi: Bir sayfanızı yalnızca klavyeyle gezmeyi deneyin ve Lighthouse raporunu inceleyin.
Faydalı kaynaklar:
- MDN Web Docs — HTML: Her element ve nitelik için en kapsamlı başvuru kaynağı.
- HTML Living Standard: HTML'in resmi spesifikasyonu.
- web.dev Learn HTML: Google'ın modern HTML eğitimi.
- W3C Markup Validator: HTML doğrulama aracı.
- Can I Use: Bir özelliğin hangi tarayıcılarda desteklendiğini kontrol etmek için.
Sonuç
HTML, her web sayfasının temelini oluşturur. Bu yazıda doküman yapısından meta etiketlere, metin ve medya elementlerinden formlara, tablolardan semantic yapıya, erişilebilirlikten SEO ve performansa kadar HTML'in neredeyse tüm temel konularını ele aldık.
Akılda tutulması gereken en önemli fikir şu: HTML'i görünüşe göre değil, anlama göre yazın. Doğru etiketleri ve semantic yapıyı kullanmak; hem tarayıcı uyumluluğunu hem erişilebilirliği hem de arama motoru görünürlüğünü artırır, üstelik kodunuzu sizden sonra okuyacak geliştiriciler için çok daha anlaşılır hale getirir.
Bu temel bilgilerle artık kendi HTML sayfalarınızı yapılandırmaya başlayabilirsiniz. Bir sonraki adım, bu iskeleti CSS ile giydirmek ve JavaScript ile hayat vermek olacak.