---
title: 'Ön ve Son İşlemciler'
source: 'https://academia.sh/tr/kurslar/duzen-ve-duyarli-tasarim/on-ve-son-islemciler'
course: 'Düzen Sistemleri ve Duyarlı Tasarım'
language: tr
updated: '2026-08-17T18:09:29+00:00'
license: 'CC BY-SA 4.0'
---

# Ön ve Son İşlemciler

Derleme zamanında çalışan biçem araçları; iç içe yazımın düzleştirilmesi, gövde kopyalamanın bedeli, derleme zamanı değeriyle çalışma zamanı değerinin ayrımı ve son işlemcilerin dönüştürmeleri.

Önceki dersteki bütün adlar tarayıcıda, sayfa çalışırken çözülüyordu. Bir başka araç sınıfı
işlerin bir bölümünü daha erken yapar: dosya tarayıcıya ulaşmadan önce, derleme sırasında.

Bu ders o araçların ne yaptığını, hangi işin derleme zamanına hangisinin çalışma zamanına
ait olduğunu ve derleme adımının bedelini ele alır. Belirli bir araç değil, iki araç sınıfı
anlatılır.

## İki Araç Sınıfı

**Ön işlemci (preprocessor)**, CSS olmayan bir kaynak dilini girdi alır ve CSS üretir.
Kaynak dil CSS'in üzerine yazım kolaylıkları ekler: iç içe kural yazımı, derleme zamanı
değişkenleri, yeniden kullanılan bildirim gövdeleri, dosya bölme ve içe alma, döngü ve
koşul.

**Son işlemci (postprocessor)**, CSS alır ve CSS üretir. Yaptığı iş dönüştürmedir: yazımı
başka bir yazıma çevirmek, gereksiz karakterleri atmak, kuralları birleştirmek, kullanılmayan
kuralları çıkarmak.

Sınır kesin değildir; ikisi de derleme zamanında çalışan program dönüştürücüleridir. Ayrımı
yapan, girdinin CSS olup olmadığıdır. Bir yapı zincirinde ikisi art arda kullanılabilir.

## İç İçe Yazımın Düzleştirilmesi

En çok kullanılan kolaylık iç içe yazımdır. Kaynakta kurallar birbirinin içine yazılır,
derleme sonunda düz kurallara açılır.

```js
// onisleme.mjs — ic ice yazimin duzlestirilmesi ve derleme zamani yinelemesinin sayimi
// Ic ice bir kural agaci, derleme zamaninda duz kurallara acilir.
const KAYNAK = {
  secici: ".olcum-kart",
  bildirim: ["display: grid", "gap: var(--aralik-0)"],
  ic: [
    { secici: "&__baslik", bildirim: ["color: var(--metin-soluk)"], ic: [] },
    { secici: "&__deger", bildirim: ["font-size: 2rem"], ic: [
      { secici: "&--eksik", bildirim: ["color: var(--uyari)"], ic: [] },
    ] },
    { secici: "&:hover", bildirim: ["transform: translateY(-8px)"], ic: [] },
    { secici: ".olcum-kartlari &", bildirim: ["margin: 0"], ic: [] },
    { secici: "p", bildirim: ["margin-block: 0"], ic: [] },              // & yok: alt oge birlestiricisi
    { secici: "@media (min-width: 48rem)", bildirim: [], ic: [
      { secici: "&", bildirim: ["gap: var(--aralik-1)"], ic: [] },
    ] },
  ],
};

function duzlestir(dugum, ustSecici = null, kosul = null, cikti = []) {
  const kosullu = dugum.secici.startsWith("@");
  const yeniKosul = kosullu ? dugum.secici : kosul;
  let secici = ustSecici;
  if (!kosullu) {
    if (ustSecici === null) secici = dugum.secici;
    else if (dugum.secici.includes("&")) secici = dugum.secici.replaceAll("&", ustSecici);
    else secici = `${ustSecici} ${dugum.secici}`;
  }
  if (dugum.bildirim.length > 0) cikti.push({ kosul: yeniKosul, secici, bildirim: dugum.bildirim });
  for (const c of dugum.ic) duzlestir(c, secici, yeniKosul, cikti);
  return cikti;
}

// ozgulluk uclusu: a=kimlik, b=sinif/oznitelik/sozde sinif, c=tur
const ozgulluk = (s) => [
  (s.match(/#[\w-]+/g) || []).length,
  (s.match(/\.[\w-]+/g) || []).length + (s.match(/\[[^\]]+\]/g) || []).length + (s.match(/:(?!:)[\w-]+/g) || []).length,
  (s.replace(/:(?!:)[\w-]+/g, " ").match(/(^|[\s>+~])([a-zA-Z][\w-]*)/g) || []).length,
];

console.log("--- ic ice kaynagin duzlestirilmesi ---");
for (const k of duzlestir(KAYNAK)) {
  const [a, b, c] = ozgulluk(k.secici);
  const on = k.kosul ? `${k.kosul} { ` : "";
  const arka = k.kosul ? " }" : "";
  console.log(`  ${(on + k.secici + " { " + k.bildirim.join("; ") + " }" + arka).padEnd(78)} (${a}, ${b}, ${c})`);
}

// --- derleme zamani yinelemesi: her cagrida govde kopyalanir ---
console.log("\n--- ayni bildirim kumesini paylasmanin iki yolu ---");
const GOVDE = ["border: 1px solid var(--cizgi)", "border-radius: 4px", "padding: var(--aralik-1)"];
const govdeBayt = GOVDE.join("; ").length + 2;
const BILESENLER = [".olcum-kart", ".yan-bilgi__kutu", ".kunye", ".konum-bolumu__pano", ".olcum-suzgeci"];

let kopyali = 0;
for (const b of BILESENLER) kopyali += b.length + 3 + govdeBayt;
const ortakSecici = BILESENLER.join(", ");
const ortak = ortakSecici.length + 3 + govdeBayt;

console.log(`  govde: ${GOVDE.length} bildirim, ${govdeBayt} bayt`);
console.log(`  ${BILESENLER.length} bilesene govdeyi kopyalayan yazim : ${kopyali} bayt`);
console.log(`  ortak secici listesiyle tek kural          : ${ortak} bayt`);
console.log(`  fark: ${kopyali - ortak} bayt (%${(((kopyali - ortak) / kopyali) * 100).toFixed(1)} daha az)`);

// --- derleme zamani degeri ile calisma zamani degerinin ayrimi ---
console.log("\n--- ayni ad, iki cozum ani ---");
const DERLEME = { "$aralik": "1.5rem" };                    // derleme zamaninda yerine konur
const uretilen = "padding: $aralik;".replace(/\$[\w-]+/g, (m) => DERLEME[m]);
console.log("  derleme zamani degiskeni -> uretilen CSS:", uretilen);
console.log("  calisma zamani ozelligi  -> uretilen CSS: padding: var(--aralik-1);");
console.log("  ilk yazimda uretilen dosyada 'aralik' adi yoktur; deger sabittir.");
```

```
--- ic ice kaynagin duzlestirilmesi ---
  .olcum-kart { display: grid; gap: var(--aralik-0) }                            (0, 1, 0)
  .olcum-kart__baslik { color: var(--metin-soluk) }                              (0, 1, 0)
  .olcum-kart__deger { font-size: 2rem }                                         (0, 1, 0)
  .olcum-kart__deger--eksik { color: var(--uyari) }                              (0, 1, 0)
  .olcum-kart:hover { transform: translateY(-8px) }                              (0, 2, 0)
  .olcum-kartlari .olcum-kart { margin: 0 }                                      (0, 2, 0)
  .olcum-kart p { margin-block: 0 }                                              (0, 1, 1)
  @media (min-width: 48rem) { .olcum-kart { gap: var(--aralik-1) } }             (0, 1, 0)

--- ayni bildirim kumesini paylasmanin iki yolu ---
  govde: 3 bildirim, 78 bayt
  5 bilesene govdeyi kopyalayan yazim : 471 bayt
  ortak secici listesiyle tek kural          : 155 bayt
  fark: 316 bayt (%67.1 daha az)

--- ayni ad, iki cozum ani ---
  derleme zamani degiskeni -> uretilen CSS: padding: 1.5rem;
  calisma zamani ozelligi  -> uretilen CSS: padding: var(--aralik-1);
  ilk yazimda uretilen dosyada 'aralik' adi yoktur; deger sabittir.
```

Düzleştirme tek bir kurala dayanır: iç kuralda `&` varsa üst seçicinin yerine konur, yoksa
üst seçiciyle arasına alt öge birleştiricisi girer.

Bu ayrım çıktının yedinci satırında görünüyor. `p` seçicisi `&` taşımadığı için
`.olcum-kart p` oluyor; üçlüsü de $(0, 1, 1)$'e çıkıyor. Dördüncü satırda ise `&__deger`
yazımı seçiciyi **birleştirerek** tek sınıfa çeviriyor ve üçlü $(0, 1, 0)$ kalıyor. Önceki
dersin adlandırma yöntemi iç içe yazımla ancak bu ikinci biçimde birlikte çalışır.

Beşinci satır `&` işaretinin sonda da yazılabileceğini gösteriyor: `.olcum-kartlari &`
yazımı bileşeni bir bağlamın içine yerleştirir ve üçlüyü büyütür.

Bir uyarı gerekir: iç içe yazım CSS'in kendisinde de tanımlıdır. Bu durumda düzleştirmeyi
derleyici değil tarayıcı yapar ve kural aynı kalır. Yani iç içe yazım tek başına bir derleme
adımını gerektirmez.

## Yinelemenin Bedeli

Ön işlemcilerin ikinci yaygın kolaylığı, bir bildirim gövdesini adlandırıp birden çok yerde
çağırmaktır. Çağrı derleme zamanında **kopyalanır**; üretilen dosyada aynı bildirimler her
seçicinin altında ayrı ayrı yer alır.

Çıktının ikinci bloğu beş bileşen için bunu sayıyor: kopyalayan yazım 471 bayt, ortak seçici
listesiyle yazılan tek kural 155 bayt. Fark, gövdenin kaç kez çağrıldığıyla doğru orantılı
büyür.

Bu, gövde paylaşımının yasak olduğu anlamına gelmez; kararın ölçütünü verir. Gövde birkaç
bildirimden uzunsa ve çok sayıda yerde çağrılıyorsa ortak bir seçici listesi ya da ortak bir
sınıf daha az bayt üretir. Kısa ve az sayıda çağrılan gövdelerde kopyalama okunurluğu artırır.

## Derleme Zamanı Değeri ile Çalışma Zamanı Değeri

Üçüncü blok iki değişken türünü aynı sonuç üzerinden karşılaştırıyor. Derleme zamanı
değişkeni üretilen dosyada **iz bırakmaz**: `padding: 1.5rem` yazılıdır, `aralik` adı yoktur.
Çalışma zamanı özelliği ise dosyada durur ve tarayıcıda çözülür.

Ayrım, hangisinin seçileceğini belirler:

- Değer bağlama göre değişecekse — ortam sorgusuna, kullanıcı tercihine, bir öznitelik
  değerine, betiğe göre — **çalışma zamanı** özelliği gerekir. Derleme zamanı değeri
  bunların hiçbirini göremez.
- Değer yalnız kaynağı düzenlemek içinse — bir dosya yolu, bir kesme noktası sayısı, bir
  döngü sınırı — derleme zamanı değişkeni yeterlidir ve üretilen dosyayı küçültür.

Karışık kullanım da olağandır: kaynak ölçek derleme zamanında hesaplanır, hesaplanan
değerler çalışma zamanı özelliklerine yazılır.

## Son İşlemcilerin İşleri

Son işlemcilerin dönüştürmeleri dört öbekte toplanabilir.

**Yazım genişletme.** Bir özelliğin henüz her yerde çözülmeyen yazımı, eşdeğer eski yazımla
birlikte üretilir. Kaynak tek yazımla kalır, üretilen dosya iki yazımı da taşır.

**Küçültme.** Boşluk, yorum ve gereksiz noktalı virgüller atılır; renkler ve sayılar en kısa
eşdeğer yazımlarına çevrilir. Anlam değişmez, bayt sayısı düşer.

**Birleştirme.** Aynı koşulu taşıyan ortam sorguları tek bloğa toplanır; aynı bildirim
kümesine sahip seçiciler tek kuralda birleştirilir.

**Kullanılmayan kural ayıklama.** Belgede eşleşmeyen seçiciler çıkarılır. Bu dönüştürme
risklidir: sınıf adı çalışma zamanında üretiliyorsa — bir öznitelik değerinden birleştirilerek
ya da betikle eklenerek — ayıklayıcı o adı göremez ve gerekli kuralı siler. Bu yüzden
adların kaynakta tam metin olarak geçmesi bir yazım kuralına dönüşür.

## Derleme Adımının Bedeli

Derleme adımı üç maliyet getirir. Birincisi kurulumdur: kaynak dosyaların doğrudan
çalışmaması, her değişikliğin bir yapı komutundan geçmesi.

İkincisi hata ayıklama uzaklığıdır. Tarayıcı üretilen dosyayı gösterir, yazdığınız dosyayı
değil. **Kaynak eşlemesi (source map)** bu uzaklığı kapatır: üretilen dosyadaki her konumun
kaynaktaki karşılığını tutan bir yan dosya üretilir ve geliştirici araçları kuralı kaynak
satırıyla gösterir.

Üçüncüsü bağımlılıktır. Kaynak dil CSS değilse, dosyalar o dilin araç zinciri olmadan
okunamaz. Bu bedel, kaynak dilin sağladığı kolaylıklar platformun kendisine geçtikçe azalır.

## İstasyon Sayfasının Kaynağı

```css
/* bilesenler/olcum-kart.css — 3. adım: iç içe yazımla aynı bileşen */
.olcum-kart {
  display: grid;
  gap: var(--aralik-0);

  &__baslik { color: var(--metin-soluk); }
  &__deger  { font-size: 2rem; font-variant-numeric: tabular-nums; }
  &__deger--eksik { color: var(--uyari); }

  &:hover,
  &:focus-within { transform: translateY(var(--kart-vurgu-yolu, -8px)); }

  @media (prefers-reduced-motion: reduce) {
    &:hover,
    &:focus-within { transform: none; }
  }
}
```

Bileşenin bütün kuralları tek bir blokta toplandı ve hepsi `&` ile birleşen tek sınıf
seçicileri üretiyor. Ortam sorgusu da bileşenin içinde duruyor; hareket azaltma kuralı artık
ayrı bir dosyada değil, ait olduğu bileşenin yanında.

Bu yazımın sınırı, iç içe girmenin derinliğidir. İki düzeyden fazla iç içe yazım, üretilen
seçicilerin okunmasını zorlaştırır ve `&` taşımayan bir iç kural üçlüyü sessizce büyütür.

## Özet

- Ön işlemci CSS olmayan bir kaynak dilinden CSS üretir; son işlemci CSS alıp CSS üretir.
  İkisi de derleme zamanında çalışır ve sınırları kesin değildir.
- İç içe yazım tek kuralla düzleşir: `&` varsa üst seçicinin yerine konur, yoksa alt öge
  birleştiricisi girer ve özgüllük üçlüsü büyür.
- Adlandırılmış bir bildirim gövdesinin her çağrısı üretilen dosyaya kopyalanır; çok sayıda
  çağrıda ortak bir seçici listesi daha az bayt üretir.
- Derleme zamanı değeri üretilen dosyada iz bırakmaz ve bağlamı göremez; bağlama göre
  değişmesi gereken her değer çalışma zamanı özelliği olmalıdır.
- Kullanılmayan kural ayıklama, sınıf adları kaynakta tam metin olarak geçmiyorsa gerekli
  kuralları silebilir.

## Sonraki Adım

Derleme adımı bir sorunu çözmedi: adlar hâlâ küresel. İki ayrı bileşen dosyasında aynı sınıf
adı yazılırsa kurallar birbirine karışır ve önceki dersteki adlandırma yöntemi bunu yalnız
**sözleşmeyle** önler — kimse denetlemezse çakışma olur. Sonraki ders adların kapsamını
gerçekten sınırlayan yaklaşımları ele alır.
