Ders 26 / 26
CSS Fonksiyonları
calc ile birim karışımı, min ve max ile sınır koyma, clamp ile aralık kelepçeleme ve bu fonksiyonların ölçek üretiminde birleştirilmesi.
İçindekiler
Birimler tanımlandı ama hâlâ tek tek sabit değerler yazılıyor. Biçem dosyasında ölçüler
elle hesaplanıp yazılmış durumda: max-width: 70ch, padding-inline: 1rem,
font-size: 2.4414rem. Bu değerlerden bazıları bir başkasına bağlıdır ve bağ dosyada
görünmez.
Bu ders hesabı biçem dosyasının içine taşıyan fonksiyonları tanımlar. Kursun son dersidir; sonunda kurs boyunca kurulan biçem dosyası toparlanır.
Dört Fonksiyon
calc() — dört işlemle bir uzunluk hesaplar. Farklı birimler karıştırılabilir; çözüm,
değerlerin bilindiği aşamada yapılır.
min() ve max() — virgülle ayrılmış değerlerden en küçüğünü ya da en büyüğünü seçer.
İkiden çok değer alabilirler.
clamp() — üç değer alır: en küçük, tercih edilen, en büyük. Tercih edilen değeri iki sınır
arasına kelepçeler.
// fonksiyon.mjs — calc, min, max ve clamp degerlerinin cozulmesi const px = (v) => +v.toFixed(2); // clamp(en_kucuk, tercih, en_buyuk) = max(en_kucuk, min(tercih, en_buyuk)) const clamp = (k, t, b) => Math.max(k, Math.min(t, b)); console.log("--- clamp: gorus alani genisligine gore yazi boyutu ---"); console.log("font-size: clamp(1rem, 0.75rem + 1.2vw, 1.5rem) (kok 16px)"); for (const vw of [320, 480, 640, 800, 1024, 1440]) { const tercih = 0.75 * 16 + 1.2 * vw / 100; const sonuc = clamp(1 * 16, tercih, 1.5 * 16); const hangisi = sonuc === 16 ? "alt sinir" : sonuc === 24 ? "ust sinir" : "tercih"; console.log(`gorus alani ${String(vw).padStart(4)}px -> tercih ${px(tercih)}px, uygulanan ${px(sonuc)}px (${hangisi})`); } console.log("\n--- calc: farkli birimlerin karisimi ---"); const KAPSAYAN = 640, KOK = 16; const ifadeler = [ ["100% - 2rem", KAPSAYAN - 2 * KOK], ["100% / 3", KAPSAYAN / 3], ["100% / 3 - 16px", KAPSAYAN / 3 - 16], ["50% + 20px", KAPSAYAN * 0.5 + 20], ["2rem * 1.5", 2 * KOK * 1.5], ]; for (const [ifade, sonuc] of ifadeler) { console.log(`calc(${ifade})`.padEnd(24) + `-> ${px(sonuc)}px (kapsayan ${KAPSAYAN}px, kok ${KOK}px)`); } console.log("\n--- min ve max: hangisi sinir koyar ---"); for (const kapsayan of [320, 640, 1200]) { const minSonuc = Math.min(kapsayan * 0.9, 600); const maxSonuc = Math.max(kapsayan * 0.9, 600); console.log(`kapsayan ${String(kapsayan).padStart(4)}px -> min(90%, 600px)=${px(minSonuc)} max(90%, 600px)=${px(maxSonuc)}`); } console.log("\n--- clamp'in min/max ile esdegerligi ---"); for (const t of [10, 16, 20, 24, 30]) { const a = clamp(16, t, 24); const b = Math.max(16, Math.min(t, 24)); console.log(`tercih=${String(t).padStart(2)} -> clamp=${a} max(16,min(t,24))=${b} esit=${a === b}`); } console.log("\n--- ic ice: aralik olcegi ---"); const TABAN = 16; for (const n of [0, 1, 2, 3, 4]) { const deger = TABAN * Math.pow(1.5, n); console.log(`--aralik-${n}: ${px(deger / KOK)}rem = ${px(deger)}px`); }
--- clamp: gorus alani genisligine gore yazi boyutu --- font-size: clamp(1rem, 0.75rem + 1.2vw, 1.5rem) (kok 16px) gorus alani 320px -> tercih 15.84px, uygulanan 16px (alt sinir) gorus alani 480px -> tercih 17.76px, uygulanan 17.76px (tercih) gorus alani 640px -> tercih 19.68px, uygulanan 19.68px (tercih) gorus alani 800px -> tercih 21.6px, uygulanan 21.6px (tercih) gorus alani 1024px -> tercih 24.29px, uygulanan 24px (ust sinir) gorus alani 1440px -> tercih 29.28px, uygulanan 24px (ust sinir) --- calc: farkli birimlerin karisimi --- calc(100% - 2rem) -> 608px (kapsayan 640px, kok 16px) calc(100% / 3) -> 213.33px (kapsayan 640px, kok 16px) calc(100% / 3 - 16px) -> 197.33px (kapsayan 640px, kok 16px) calc(50% + 20px) -> 340px (kapsayan 640px, kok 16px) calc(2rem * 1.5) -> 48px (kapsayan 640px, kok 16px) --- min ve max: hangisi sinir koyar --- kapsayan 320px -> min(90%, 600px)=288 max(90%, 600px)=600 kapsayan 640px -> min(90%, 600px)=576 max(90%, 600px)=600 kapsayan 1200px -> min(90%, 600px)=600 max(90%, 600px)=1080 --- clamp'in min/max ile esdegerligi --- tercih=10 -> clamp=16 max(16,min(t,24))=16 esit=true tercih=16 -> clamp=16 max(16,min(t,24))=16 esit=true tercih=20 -> clamp=20 max(16,min(t,24))=20 esit=true tercih=24 -> clamp=24 max(16,min(t,24))=24 esit=true tercih=30 -> clamp=24 max(16,min(t,24))=24 esit=true --- ic ice: aralik olcegi --- --aralik-0: 1rem = 16px --aralik-1: 1.5rem = 24px --aralik-2: 2.25rem = 36px --aralik-3: 3.38rem = 54px --aralik-4: 5.06rem = 81px
clamp Üç Bölgeli Bir Fonksiyondur
İlk blok, clamp() fonksiyonunun üç bölgesini gösteriyor. 320 birimlik bir görüntü alanında
tercih edilen değer 15,84 piksel hesaplandı ama alt sınırın altında kaldığı için 16 piksel
uygulandı. 480’den 800’e kadar tercih edilen değer aralıkta kaldı ve doğrudan kullanıldı.
1024’ten sonra üst sınıra dayandı.
Dördüncü blok eşdeğerliği doğruluyor: clamp(a, t, b) her zaman max(a, min(t, b))
sonucunu verir. clamp() ayrı bir mekanizma değil, bu bileşimin adıdır.
Tercih edilen değerdeki 0.75rem + 1.2vw yazımı bir kalıptır: sabit bir taban ile görüntü
alanına oranlı bir bileşenin toplamı. Sabit bileşen olmadan yalnızca vw yazılsaydı,
kullanıcı yakınlaştırma yaptığında metin büyümezdi — bir önceki derste anılan sorun. Sabit
bileşen bu bağı korur.
calc Birim Karıştırır
İkinci blok calc() fonksiyonunun asıl işini gösteriyor: aynı ifadede yüzde, rem ve px
karıştırılabiliyor. Bu, başka türlü yazılamayacak ilişkileri kurar.
calc(100% - 2rem) — kapsayanı doldur ama iki taban birim boşluk bırak.
calc(100% / 3 - 16px) — üçte bir genişlik al ve aradaki boşluğu düş.
Yazım kurallarında bir ayrıntı vardır: + ve - işleçlerinin iki yanında da boşluk
zorunludur. calc(100%-2rem) yazımı geçersizdir, çünkü -2rem negatif bir sayı olarak
okunur. * ve / için boşluk zorunlu değildir, ama tutarlılık için yazılır.
İkinci kısıt: çarpmada işlenenlerden en az biri, bölmede bölen birimsiz bir sayı olmalıdır. İki uzunluk çarpılamaz.
calc() iç içe yazılabilir ve var() çağrılarını da kapsayabilir. Özel özelliklerle
birlikte kullanıldığında bir ölçeğin tek bir tabandan türetilmesini sağlar — dördüncü blok
bunun sonucunu veriyor.
min ve max Sınır Koyar
Üçüncü blok bir okuma alışkanlığını düzeltiyor. min() bir üst sınır koyar: verilen
değerlerin en küçüğü seçilir, dolayısıyla sonuç hiçbirini aşamaz. max() bir alt sınır
koyar.
Adlarla işlevlerin ters gibi görünmesi sık karıştırılan bir noktadır. Çıktıda
min(90%, 600px) yazımı, kapsayan 1200 birim olduğunda 600’de durdu — yani bir üst sınır
işlevi gördü.
Bu iki fonksiyonun bir üstünlüğü vardır: min-width ve max-width gibi ayrı özellikler
yazmadan, aynı bildirimin içinde sınır koyarlar. Ayrıca kısayol değerlerinin içinde de
kullanılabilirler — padding: min(5%, 2rem) yazılabilir, oysa padding için bir max-
özelliği yoktur.
Kursun Biçem Dosyası
Kurs boyunca istasyon sayfasının biçem dosyası adım adım büyüdü. Toparlanmış hâli, bu kursta kurulan bütün kararları taşır:
/* istasyon.css — toparlanmış hâl */ /* 1. Taban */ *, *::before, *::after { box-sizing: border-box; } :root { font-size: 100%; } /* 2. Ölçekler */ :root { --ton: 203; --marka-koyu: hsl(var(--ton) 61% 20%); --zemin: hsl(var(--ton) 18% 97%); --cizgi: hsl(207 15% 86%); --metin: hsl(211 29% 16%); --metin-soluk: hsl(211 12% 45%); --uyari: hsl(0 66% 33%); --aralik-0: 1rem; --aralik-1: calc(var(--aralik-0) * 1.5); --aralik-2: calc(var(--aralik-1) * 1.5); --aralik-3: calc(var(--aralik-2) * 1.5); --yazi-govde: clamp(1rem, 0.9rem + 0.35vw, 1.125rem); --yazi-h1: clamp(1.75rem, 1.3rem + 2.2vw, 2.5rem); } /* 3. Belge */ body { color: var(--metin); font-family: "Istasyon Sans", system-ui, sans-serif; font-size: var(--yazi-govde); line-height: 1.5; } main { max-width: min(70ch, 100% - var(--aralik-1)); margin-inline: auto; padding-block: var(--aralik-2); } main > * + * { margin-block-start: var(--aralik-0); } main > section { margin-block-start: var(--aralik-3); } /* 4. Künye */ .kunye { padding: var(--aralik-1); margin-block-end: var(--aralik-2); background-color: var(--zemin); border-block-end: 4px solid var(--marka-koyu); } .kunye > :first-child { margin-block-start: 0; } h1 { font-size: var(--yazi-h1); line-height: 1.15; } /* 5. Ölçüm çizelgesi */ .cizelge-sarmalayici { overflow-x: auto; } .olcum-cizelgesi { width: 100%; min-width: 40rem; border-collapse: collapse; } .olcum-cizelgesi th, .olcum-cizelgesi td { padding-block: 0.5rem; padding-inline: 0.75rem; border-block-end: 1px solid var(--cizgi); } .olcum-cizelgesi thead th { position: sticky; z-index: 10; inset-block-start: 0; background-color: var(--zemin); text-transform: uppercase; letter-spacing: 0.04em; } :where(.olcum-cizelgesi) .deger { text-align: end; font-variant-numeric: tabular-nums; } :where(.olcum-cizelgesi) .eksik { color: var(--uyari); } .olcum-cizelgesi tbody tr:nth-child(odd) { background-color: var(--zemin); } /* 6. Konum bölümü */ .konum-bolumu { display: flow-root; } .konum-gorseli { float: inline-start; inline-size: min(200px, 40%); margin-inline-end: var(--aralik-0); margin-block-end: 0.5rem; } .konum-gorseli img { max-width: 100%; height: auto; } .kaynak-notu { clear: both; color: var(--metin-soluk); font-size: 0.875em; } /* 7. Durumlar */ a:focus-visible, input:focus-visible { outline: 3px solid var(--marka-koyu); outline-offset: 2px; } input, select, textarea, button { font: inherit; color: inherit; } input[required] { border-inline-start: 3px solid var(--uyari); } input:invalid { border-color: var(--uyari); } .gorsel-gizli { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
Dosya yedi bölüme ayrılmış durumda ve sıra rastgele değil: taban kuralları en üstte, en düşük özgüllükle; bileşen kuralları altta. Basamaklama dersinde kurulan sıra ölçütü, bu düzenin öngörülebilir olmasını sağlar — aynı özgüllükteki bir çakışma her zaman sonra yazılan lehine çözülür.
Ölçekler tek bir yerde tanımlı ve birbirinden türetilmiş durumda. --aralik-1 değeri
--aralik-0 değerine bağlı; taban değiştiğinde bütün aralıklar birlikte değişir.
main ögesinin genişliği iki kısıtın küçüğü: okunabilir satır uzunluğu ve ekran kenarında
bırakılacak boşluk. Bu, kutu boyutlandırma, birim ve fonksiyon derslerinin birleşimidir.
Özet
calc()farklı birimleri aynı ifadede karıştırır; toplama ve çıkarma işleçlerinin iki yanında boşluk zorunludur ve çarpmada en az bir işlenen birimsiz olmalıdır.min()bir üst sınır,max()bir alt sınır koyar; adlar işlevlerin tersi gibi görünse de seçilen değer sırasıyla en küçük ve en büyüktür.clamp(a, t, b),max(a, min(t, b))bileşiminin adıdır ve üç bölgeli davranır: tercih edilen değer aralıktaysa kullanılır, dışındaysa ilgili sınıra kelepçelenir.- Ölçeklenen tipografide tercih edilen değer sabit bir taban ile görüntü alanına oranlı bir bileşenin toplamı olarak yazılır; yalnızca görüntü alanı birimi yazmak yakınlaştırma bağını koparır.
- Fonksiyonlar özel özelliklerle birleştirildiğinde bir ölçek tek bir tabandan türetilir ve ölçeğin tamamı tek bir değerin değiştirilmesiyle kaydırılır.
Kurs Kapanışı
Bu kurs, Web’in Temelleri ve HTML kursunda kurulan ölçüm istasyonu belgesini biçimlendirdi ve bunu üç katmanda yaptı.
Birinci konu kuralların belgeye nasıl ulaştığını kurdu: bir bildirimin sözdizimi, seçicinin döndürdüğü küme, çakışmaların basamaklama ve özgüllükle çözümü, değerin kalıtımla ya da başlangıç değeriyle doldurulması. Bu konunun ayırt edici yanı, sorulan her sorunun hesaplanabilir bir yanıtı olmasıydı: özgüllük bir üçlü, basamaklama bir sıralama, kalıtım bir ağaç yürüyüşüdür.
İkinci konu kutuların nasıl ölçüldüğünü ve dizildiğini kurdu: kutu modelinin aritmetiği, iki boyutlandırma modelinin sayısal farkı, normal akışın kuralları, dış boşluk çökmesi, kaydırma, konumlandırma ve yığılma bağlamı. Buradaki tekrarlanan ders şuydu: bir yerleşim sorunu önce akışın kurallarıyla çözülmeye çalışılır; akıştan çıkaran her bildirim bir bedelle gelir.
Üçüncü konu görsel kararları ölçeğe bağladı: renk uzayları ve kontrast hesabı, modüler tipografi ölçeği, yazı tipi yükleme davranışı, arka plan katmanları, geçişler, kenarlıklar, birimler ve hesap fonksiyonları. Buradaki ilke, tek tek değerler yerine türetilmiş ölçekler kurmaktı.
Kursun kapsamadığı bir şey kaldı: iki boyutlu düzen. Bu kursta kutular ya akışta alt alta dizildi ya da kaydırmayla bir kenara itildi. Sütunlar kurmak, kutuları bir ızgaraya yerleştirmek, aralarındaki boşlukları çökmeden vermek ve bütün bunları ekran genişliğine göre uyarlamak ayrı bir modelin işidir.
Düzen Sistemleri ve Duyarlı Tasarım kursu bu modeli kurar. Esnek kutu ve ızgara düzenleriyle iki boyutlu yerleşim, içerikten türetilen kesme noktalarıyla duyarlı tasarım ve biçem mimarisinin ölçeklenebilir biçimde düzenlenmesi orada ele alınır. Bu kursta öğrenilen her şey orada da geçerlidir: özgüllük hesabı aynı hesaptır, kutu modeli aynı modeldir, ölçekler aynı ölçeklerdir. Değişen tek şey, kutuların birbirine göre nasıl yerleştirildiğidir.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.