
Bu yazı, tek bir “responsive başlangıç sayfası” mantığını 5 küçük parçaya bölerek öğretir. Her parça bağımsız kullanılabilir; isterseniz hepsini birleştirip küçük bir landing page iskeleti çıkarabilirsiniz. Odak noktamız kopyalayıp düzenleyebileceğiniz kadar minimal örnekler.
Teknik dayanaklar:
Referans olarak MDN dokümantasyonunu baz alıyoruz: MDN Responsive Design, MDN Meta Viewport, MDN Flexbox, MDN CSS Grid, MDN Responsive Images.
Not: Kod örneklerinde geçen https://your-domain.example ve benzeri adresler yer tutucudur; kendi URL’nizle değiştirin.
Mobil cihazların sayfayı cihaz genişliğine göre ölçeklemesi için, meta viewport etiketi pratikte temel bir adımdır (detay: MDN Meta viewport).
index.html (head içine)
<meta name="viewport" content="width=device-width, initial-scale=1">
Mobil-öncelikli yaklaşımda önce küçük ekranlar için temel stilleri yazarsınız; daha geniş ekranlar için @media (min-width: ...) ile eklemeler yaparsınız (genel yaklaşım için: MDN Responsive Design).
styles.css (başlangıç)
:root {
--max: 1100px;
--gap: 16px;
--radius: 14px;
--text: #111;
--muted: #555;
--bg: #fff;
--surface: #f5f5f7;
--accent: #2f6fed;
}
* { box-sizing: border-box; }
body {
margin: 0;
font-family: system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif;
line-height: 1.5;
color: var(--text);
background: var(--bg);
}
img { max-width: 100%; height: auto; display: block; }
.container {
max-width: var(--max);
margin: 0 auto;
padding: 0 16px;
}
| Kullanım | Önerilen | Neden |
|---|---|---|
| Tek sıra/tek kolon hizalama (dikey ya da yatay) | Flexbox | Tek boyutlu düzenlerde hizalama ve boşluk yönetimi pratiktir. (MDN Flexbox) |
| Kart ızgarası gibi hem satır hem sütun kontrolü | CSS Grid | İki boyutlu yerleşimlerde daha öngörülebilir kontrol sağlar. (MDN Grid) |
Landing page’lerin en üst bölümü genelde bir “hero” alanıdır: değer önerisi, kısa açıklama ve bir çağrı linki. Burada Flexbox ile küçük ekranda tek kolon, geniş ekranda iki sütuna doğru bir düzen kuracağız (MDN Flexbox).
HTML
<div class="hero">
<div class="container hero__inner">
<div class="hero__copy">
<h1>Ürününüz için sade ve responsive bir başlangıç sayfası</h1>
<p>Bu şablon, mobil-öncelikli CSS ile hızlıca düzen kurmanıza yardımcı olur.</p>
<a class="btn" href="https://your-domain.example">Daha fazla bilgi</a>
</div>
<img class="hero__img" src="hero.jpg" alt="Ürün ekran görüntüsü">
</div>
</div>
CSS
.hero { padding: 40px 0; background: var(--surface); }
.hero__inner { display: flex; flex-direction: column; gap: 20px; }
.hero__copy h1 { margin: 0; font-size: clamp(28px, 5vw, 44px); line-height: 1.1; }
.hero__copy p { margin: 10px 0 0; color: var(--muted); }
.btn {
display: inline-block;
margin-top: 16px;
padding: 10px 14px;
background: var(--accent);
color: #fff;
text-decoration: none;
border-radius: 999px;
}
.hero__img { border-radius: var(--radius); }
@media (min-width: 900px) {
.hero__inner { flex-direction: row; align-items: center; }
.hero__copy { flex: 1; }
.hero__img { flex: 1; }
}
Özellikleri, kullanım senaryolarını veya içerikleri göstermek için kart ızgarası çok kullanılır. Burada CSS Grid ile “ekran genişledikçe kendini düzenleyen” bir ızgara kuracağız (MDN CSS Grid).
HTML
<div class="container">
<h2>Öne çıkanlar</h2>
<div class="grid">
<div class="card"><h3>Hızlı kurulum</h3><p>Minimum HTML/CSS ile başlayın.</p></div>
<div class="card"><h3>Responsive düzen</h3><p>Mobil-öncelikli medya sorguları.</p></div>
<div class="card"><h3>Temiz tipografi</h3><p>Okunabilir aralıklar ve boyutlar.</p></div>
</div>
</div>
CSS
.grid {
display: grid;
grid-template-columns: 1fr;
gap: var(--gap);
margin: 16px 0 40px;
}
.card {
background: var(--surface);
border-radius: var(--radius);
padding: 16px;
}
.card h3 { margin: 0; }
.card p { margin: 10px 0 0; color: var(--muted); }
@media (min-width: 700px) {
.grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1000px) {
.grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
Bu mini örnekte hedefimiz “tam açılır-kapanır hamburger menü” değil; JavaScript olmadan, küçük ekranda satıra sığmadığında kendini düzgünce saran, büyük ekranda tek satırda hizalanan bir menü kurmak. Böylece bakım basit kalır.
Bu örnekte temel yapı taşı olarak Flexbox kullanıyoruz (MDN Flexbox).
HTML
<div class="topbar">
<div class="container topbar__inner">
<a class="brand" href="#">Marka</a>
<div class="menu">
<a href="#ozellikler">Özellikler</a>
<a href="#fiyat">Fiyat</a>
<a href="#sss">SSS</a>
</div>
</div>
</div>
CSS
.topbar { border-bottom: 1px solid #e6e6ea; background: #fff; }
.topbar__inner {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 12px 16px;
}
.brand { color: var(--text); text-decoration: none; font-weight: 700; }
.menu { display: flex; flex-wrap: wrap; gap: 12px; justify-content: flex-end; }
.menu a { color: var(--muted); text-decoration: none; }
.menu a:hover { text-decoration: underline; }
@media (min-width: 900px) {
.menu { gap: 16px; }
}
İletişim veya kayıt gibi formlar, küçük ekranda tek sütun; geniş ekranda iki sütun olduğunda daha rahat kullanılabilir. Bu örnekte Grid ile “label + input” düzenini geniş ekranda iki kolona çeviriyoruz (MDN CSS Grid).
Not: Gerçek bir formu yayına almadan önce doğrulama, hata mesajları ve gizlilik gereksinimlerini proje kapsamınıza göre ayrıca ele alın.
HTML
<div class="container">
<h2>İletişim</h2>
<form class="form" action="/contact" method="post">
<div class="field">
<label for="name">Ad Soyad</label>
<input id="name" name="name" autocomplete="name" required>
</div>
<div class="field">
<label for="email">E-posta</label>
<input id="email" name="email" type="email" autocomplete="email" required>
</div>
<div class="field field--full">
<label for="msg">Mesaj</label>
<textarea id="msg" name="message" rows="5" required></textarea>
</div>
<button class="btn" type="submit">Gönder</button>
</form>
</div>
CSS
.form { display: grid; grid-template-columns: 1fr; gap: var(--gap); margin: 16px 0 40px; }
.field { display: grid; gap: 6px; }
label { font-weight: 600; }
input, textarea {
font: inherit;
padding: 10px 12px;
border-radius: 10px;
border: 1px solid #d9d9e0;
}
@media (min-width: 900px) {
.form { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.field--full { grid-column: 1 / -1; }
}
En temel responsive görsel yaklaşımı, görselin taşmasını engellemek için CSS’te max-width: 100% ve height: auto kullanmaktır. Daha uygun dosya seçimi için HTML’de srcset/sizes eklemek çoğu senaryoda faydalıdır (MDN Responsive images).
HTML (srcset/sizes örneği)
<img
src="hero-800.jpg"
srcset="hero-480.jpg 480w, hero-800.jpg 800w, hero-1200.jpg 1200w"
sizes="(min-width: 900px) 50vw, 100vw"
alt="Uygulama ekranı örneği"
loading="lazy"
>
CSS (kırpma gereken kaplar için)
.media { border-radius: var(--radius); overflow: hidden; }
.media img { width: 100%; height: 100%; object-fit: cover; }
Bu 5 parçayı bir sayfada birleştirdiğinizde tipik akış şöyle olur: üstte menü, altında hero, sonra kart ızgarası, ardından form ve uygun yerlerde görseller. Mobil-öncelikli yazdığınızda, sayfa küçük ekranda “doğal bir tek kolon akış” gibi çalışır; geniş ekranda medya sorguları ile düzeni açarsınız (yaklaşım için: MDN Responsive Design).
Pratik notlar:
Aşağıdaki iki dosya, bu yazıdaki 5 parçayı “tek sayfada” birleştiren minimal bir başlangıç verir. Görselleri ve metinleri projenize göre değiştirin.
<!doctype html>
<html lang="tr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Responsive Başlangıç Sayfası</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="topbar">
<div class="container topbar__inner">
<a class="brand" href="#">Marka</a>
<div class="menu">
<a href="#ozellikler">Özellikler</a>
<a href="#iletisim">İletişim</a>
</div>
</div>
</div>
<div class="hero">
<div class="container hero__inner">
<div class="hero__copy">
<h1>Sade ve responsive landing page</h1>
<p>Mobile-first CSS ile hızlı bir başlangıç.</p>
<a class="btn" href="https://your-domain.example">Daha fazla bilgi</a>
</div>
<div class="media">
<img src="hero-800.jpg"
srcset="hero-480.jpg 480w, hero-800.jpg 800w, hero-1200.jpg 1200w"
sizes="(min-width: 900px) 50vw, 100vw"
alt="Ürün görseli" loading="lazy">
</div>
</div>
</div>
<div class="container" id="ozellikler">
<h2>Öne çıkanlar</h2>
<div class="grid">
<div class="card"><h3>Hızlı kurulum</h3><p>Minimal HTML/CSS.</p></div>
<div class="card"><h3>Grid düzen</h3><p>Kart ızgarası.</p></div>
<div class="card"><h3>Görseller</h3><p>srcset ile esnek.</p></div>
</div>
</div>
<div class="container" id="iletisim">
<h2>İletişim</h2>
<form class="form" action="/contact" method="post">
<div class="field">
<label for="name">Ad Soyad</label>
<input id="name" name="name" autocomplete="name" required>
</div>
<div class="field">
<label for="email">E-posta</label>
<input id="email" name="email" type="email" autocomplete="email" required>
</div>
<div class="field field--full">
<label for="msg">Mesaj</label>
<textarea id="msg" name="message" rows="5" required></textarea>
</div>
<button class="btn" type="submit">Gönder</button>
</form>
</div>
</body>
</html>
:root {
--max: 1100px;
--gap: 16px;
--radius: 14px;
--text: #111;
--muted: #555;
--bg: #fff;
--surface: #f5f5f7;
--accent: #2f6fed;
}
* { box-sizing: border-box; }
body { margin: 0; font-family: system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif; line-height: 1.5; color: var(--text); background: var(--bg); }
img { max-width: 100%; height: auto; display: block; }
.container { max-width: var(--max); margin: 0 auto; padding: 0 16px; }
.topbar { border-bottom: 1px solid #e6e6ea; background: #fff; }
.topbar__inner { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 16px; }
.brand { color: var(--text); text-decoration: none; font-weight: 700; }
.menu { display: flex; flex-wrap: wrap; gap: 12px; justify-content: flex-end; }
.menu a { color: var(--muted); text-decoration: none; }
.menu a:hover { text-decoration: underline; }
.hero { padding: 40px 0; background: var(--surface); }
.hero__inner { display: flex; flex-direction: column; gap: 20px; }
.hero__copy h1 { margin: 0; font-size: clamp(28px, 5vw, 44px); line-height: 1.1; }
.hero__copy p { margin: 10px 0 0; color: var(--muted); }
.btn { display: inline-block; margin-top: 16px; padding: 10px 14px; background: var(--accent); color: #fff; text-decoration: none; border-radius: 999px; border: 0; font: inherit; }
.media { border-radius: var(--radius); overflow: hidden; }
.media img { width: 100%; height: 100%; object-fit: cover; }
.grid { display: grid; grid-template-columns: 1fr; gap: var(--gap); margin: 16px 0 40px; }
.card { background: var(--surface); border-radius: var(--radius); padding: 16px; }
.card h3 { margin: 0; }
.card p { margin: 10px 0 0; color: var(--muted); }
.form { display: grid; grid-template-columns: 1fr; gap: var(--gap); margin: 16px 0 40px; }
.field { display: grid; gap: 6px; }
label { font-weight: 600; }
input, textarea { font: inherit; padding: 10px 12px; border-radius: 10px; border: 1px solid #d9d9e0; }
@media (min-width: 700px) {
.grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 900px) {
.hero__inner { flex-direction: row; align-items: center; }
.menu { gap: 16px; }
.form { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.field--full { grid-column: 1 / -1; }
}
@media (min-width: 1000px) {
.grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
Bu şablonu temel alıp içeriklerinizi, renklerinizi ve kırılma noktalarınızı ihtiyacınıza göre güncelleyebilirsiniz.
Yorumlar