İçeriğe geç
academia.sh

Ders 14 / 26

Konumlandırma

Statik, göreli, mutlak, sabit ve yapışkan konumlandırmanın kutuyu nereye koyduğu; kapsayan blok kavramı ve ofset özelliklerinin neye göre ölçüldüğü.

İçindekiler

Kaydırma bir kutuyu akıştan çıkardı ama nereye gideceğini seçtirmedi; kutu yalnızca bir kenara itildi. İstasyon sayfasında bunun yetmediği yerler var: bir durum rozetinin kartın köşesinde durması, ölçüm çizelgesinin sütun başlıklarının kaydırma sırasında görünür kalması.

Bu ders position özelliğinin beş değerini tanımlar. Her değerin iki sorusu vardır: kutu akışta kalıyor mu, ve ofset değerleri hangi kutuya göre ölçülüyor?

Beş Değer, İki Soru

// konum.mjs — bes konumlandirma degerinin kutuyu nereye koydugunu hesaplar
const KAPSAYAN = { ad: "main",  x: 40,  y: 100, en: 640, boy: 800 };
const KART     = { ad: "kart",  x: 80,  y: 200, en: 400, boy: 240 }; // akistaki yeri
const GORUNTU  = { ad: "goruntu alani", x: 0, y: 0, en: 1024, boy: 768 };

function yerlestir({ konum, akistakiYer, kapsayanBlok, ofset, kaydirmaY = 0 }) {
  const { ust = null, sol = null, en = 120, boy = 40 } = ofset;
  switch (konum) {
    case "static":
      return { x: akistakiYer.x, y: akistakiYer.y, en: akistakiYer.en, boy: akistakiYer.boy, akista: true };
    case "relative":
      return { x: akistakiYer.x + (sol ?? 0), y: akistakiYer.y + (ust ?? 0),
               en: akistakiYer.en, boy: akistakiYer.boy, akista: true };
    case "absolute":
      return { x: kapsayanBlok.x + (sol ?? 0), y: kapsayanBlok.y + (ust ?? 0), en, boy, akista: false };
    case "fixed":
      return { x: GORUNTU.x + (sol ?? 0), y: GORUNTU.y + (ust ?? 0), en, boy, akista: false };
    case "sticky": {
      const esik = ust ?? 0;
      const akmisY = akistakiYer.y - kaydirmaY;
      return { x: akistakiYer.x, y: Math.max(esik, akmisY),
               en: akistakiYer.en, boy: akistakiYer.boy, akista: true, yapisti: akmisY < esik };
    }
  }
}

const rozet = { x: 0, y: 0, en: 120, boy: 40 };
console.log("kapsayan blok: main  x=40 y=100 640x800");
console.log("akistaki yer : rozet x=0  y=0   120x40\n");

for (const konum of ["static", "relative", "absolute", "fixed"]) {
  const r = yerlestir({ konum, akistakiYer: rozet, kapsayanBlok: KART, ofset: { ust: 16, sol: 12 } });
  console.log(`${konum.padEnd(9)} -> x=${String(r.x).padStart(4)} y=${String(r.y).padStart(4)}  ${r.en}x${r.boy}  akista=${r.akista}`);
}
console.log("  (absolute icin kapsayan blok = kart: x=80 y=200)");

console.log("\n--- sticky: baslik, esik ust=0, kaydirma ilerledikce ---");
const baslik = { x: 40, y: 300, en: 640, boy: 48 };
for (const kaydirmaY of [0, 200, 300, 400, 520]) {
  const r = yerlestir({ konum: "sticky", akistakiYer: baslik, kapsayanBlok: KAPSAYAN, ofset: { ust: 0 }, kaydirmaY });
  console.log(`kaydirma=${String(kaydirmaY).padStart(3)} -> ekranda y=${String(r.y).padStart(3)}  yapisti=${r.yapisti}`);
}
kapsayan blok: main  x=40 y=100 640x800
akistaki yer : rozet x=0  y=0   120x40

static    -> x=   0 y=   0  120x40  akista=true
relative  -> x=  12 y=  16  120x40  akista=true
absolute  -> x=  92 y= 216  120x40  akista=false
fixed     -> x=  12 y=  16  120x40  akista=false
  (absolute icin kapsayan blok = kart: x=80 y=200)

--- sticky: baslik, esik ust=0, kaydirma ilerledikce ---
kaydirma=  0 -> ekranda y=300  yapisti=false
kaydirma=200 -> ekranda y=100  yapisti=false
kaydirma=300 -> ekranda y=  0  yapisti=false
kaydirma=400 -> ekranda y=  0  yapisti=true
kaydirma=520 -> ekranda y=  0  yapisti=true

Değerlerin Okunması

static — başlangıç değeridir. Kutu normal akıştaki yerinde durur ve ofset özellikleri (top, right, bottom, left; mantıksal karşılıkları inset-block-start ve akrabaları) yok sayılır. Çıktıda ofset verildiği hâlde konum değişmedi.

relative — kutu akıştaki yerinden ofset kadar kaydırılır ama akıştaki yerini korur. Çıktıda kutu 12 ve 16 birim kaydı; komşuları bu kaymadan etkilenmez, kutunun eski yeri boş kalır. Bu, göreli konumlandırmanın hem gücü hem sınırıdır: görsel bir düzeltme yapar, yerleşimi yeniden düzenlemez.

absolute — kutu akıştan çıkarılır ve ofsetler kapsayan bloğa göre ölçülür. Çıktıda kart x=80x=80, y=200y=200 noktasındaydı; rozet 92,21692, 216 noktasına yerleşti. Kutu akıştan çıktığı için genişliği de artık kapsayanı doldurmaz — içeriğine göre daralır.

fixed — kutu akıştan çıkarılır ve ofsetler görüntü alanına göre ölçülür. Çıktıda kart nerede olursa olsun kutu 12,1612, 16 noktasına yerleşti. Sayfa kaydırıldığında kutu ekranda sabit kalır.

sticky — ikisi arasındadır ve çıktının ikinci bloğunda görülüyor.

Kapsayan Blok Nasıl Belirlenir

Mutlak konumlandırmanın en çok yanlış anlaşılan yanı, “kapsayan blok”un ne olduğudur. Kural şudur: kutu, en yakın konumlandırılmış atasına göre yerleşir. Konumlandırılmış demek, position değeri static dışında bir şey olan demektir.

Hiçbir atası konumlandırılmamışsa kapsayan blok, belgenin ilk kutusudur; kutu sayfanın tamamına göre yerleşir — çoğu zaman istenmeyen sonuç budur.

Bu, standart bir eşleşmeyi doğurur:

.kart          { position: relative; }
.kart .rozet   { position: absolute; inset-block-start: 8px; inset-inline-end: 8px; }

Karta position: relative verilir ama hiçbir ofset yazılmaz. Amaç kartı kaydırmak değil, onu bir kapsayan blok hâline getirmektir. Rozet artık kartın köşesine yerleşir.

Ofsetlerin kısayolu inset’tir: inset: 0 dört ofseti de sıfırlar ve mutlak konumlandırılmış bir kutuyu kapsayan bloğuna tam olarak yayar.

Karşıt iki ofset birlikte verildiğinde — inset-inline-start: 0 ve inset-inline-end: 0 — kutunun genişliği ikisi arasındaki mesafeye zorlanır. Bu, width yazmadan genişlik vermenin yoludur.

Yapışkan Konum Bir Eşik Davranışıdır

position: sticky kutuyu akışta bırakır. Kutu normal yerinde durur; ta ki kaydırma sırasında bildirilen eşiğe ulaşana kadar. O noktadan sonra kutu eşikte yapışır.

Çıktının ikinci bloğu bunu adım adım gösteriyor. Başlık akışta y=300y = 300 noktasındaydı ve eşik inset-block-start: 0 olarak verildi. Kaydırma 200 birim ilerlediğinde başlık ekranda 100 noktasına çıktı — hâlâ akışla birlikte hareket ediyor. Kaydırma 300’e ulaştığında başlık eşiğe değdi; 400 ve 520’de ekranda 0 noktasında kaldı, yani yapıştı.

İki koşul gerekir ve ikisi de sıkça atlanır.

Bir eşik bildirilmelidir. position: sticky tek başına hiçbir şey yapmaz; en az bir ofset özelliği yazılmalıdır.

Yapışma kapsayan kutunun sınırları içindedir. Kutu, kapsayanının dışına çıkmaz; kapsayan kaydırılıp geçildiğinde kutu da onunla birlikte gider. Bu, bir bölüm başlığının yalnızca kendi bölümü ekrandayken yapışmasını sağlar — istenen davranış genellikle budur.

Bir de engel vardır: yapışkan kutu, kaydırılabilir bir atası varsa ona göre yapışır. Aradaki atalardan birinde overflow: hidden bulunması yapışmayı sessizce durdurur. Yapışmayan bir kutuda ilk bakılacak yer budur.

Akıştan Çıkmanın Bedeli

Mutlak ve sabit konumlandırma kutuyu akıştan çıkarır. Bunun bedeli, kutunun kapsayanının yüksekliğine katılmamasıdır — kaydırmada gördüğümüz sorunun aynısı.

Sonuç, mutlak konumlandırılmış içeriğin altındaki içerikle çakışabilmesidir. Bu yüzden mutlak konumlandırma, ölçüsü içerikle birlikte değişen bir şey için değil, ölçüsü sabit ya da çakışması sorun olmayan bir şey için kullanılır: rozet, kapatma düğmesi, dekoratif işaret.

Sayfanın ana düzenini konumlandırmayla kurmak, akışın verdiği bütün otomatik davranışları elle yeniden yazmak demektir. Genel kural şudur: düzen akışla kurulur, konumlandırma akışın veremediği tek tek istisnalar içindir.

/* istasyon.css — 13. adım: konumlandırma */
.kart { position: relative; }

.kart .durum-rozeti {
  position: absolute;
  inset-block-start: 8px;
  inset-inline-end: 8px;
}

.olcum-cizelgesi thead th {
  position: sticky;
  inset-block-start: 0;
  background-color: #f5f7f8;
}

.atlama-baglantisi {
  position: absolute;
  inset-block-start: -100px;
}

.atlama-baglantisi:focus {
  position: fixed;
  inset-block-start: 8px;
  inset-inline-start: 8px;
}

Çizelge başlığındaki arka plan rengi zorunludur: yapışan başlık, altından geçen satırların üstünde çizilir ve saydam kalırsa iki metin üst üste okunur.

Son iki kural bir erişilebilirlik kalıbıdır. İçeriğe atlama bağlantısı görüş alanının dışında durur, klavye odağı ona geldiğinde sabit konuma geçip görünür olur. Kural display: none ile yazılamazdı — kutu üretmeyen bir öge odaklanamaz.

Özet

  • static kutuyu akıştaki yerinde bırakır ve ofsetleri yok sayar; relative kutuyu ofset kadar kaydırır ama akıştaki yerini korur.
  • absolute ve fixed kutuyu akıştan çıkarır; birincisi en yakın konumlandırılmış ataya, ikincisi görüntü alanına göre ölçer.
  • Mutlak konumlandırma için kapsayan blok, position değeri static dışında olan en yakın atadır; ofsetsiz position: relative yazmanın işi budur.
  • sticky kutuyu akışta bırakır ve bildirilen eşiğe ulaşınca orada tutar; en az bir ofset bildirilmelidir ve yapışma kapsayan kutunun sınırlarıyla çevrilidir.
  • Akıştan çıkmış kutu kapsayanının yüksekliğine katılmaz; bu yüzden konumlandırma ana düzen için değil, akışın veremediği istisnalar için kullanılır.

Sonraki Adım

Konumlandırma kutuları üst üste bindirebiliyor: rozet kartın üzerinde, yapışan başlık satırların üzerinde duruyor. Peki iki kutu aynı noktada çakışırsa hangisi üstte çizilir? z-index yazmak her zaman işe yaramaz — bazen daha yüksek bir değer daha altta kalır. Sonraki ders çizim sırasını ve bu davranışın sebebi olan yığılma bağlamını tanımlar.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat