HTML yönünü açıkça ayarlayarak, yönlü boşluklandırma için mantıksal özellikleri kullanarak ve yerleşim öğeleri arasında gap kullanarak LTR ve RTL sayfaları arasında tek bir CSS dosyası paylaşın. Bu kılavuz, Mac tarayıcısında karşılaştırabileceğiniz iki sayfalı yerel bir örnek oluşturur.

Görev, aynı küçük bileşenin satır içi yönü değiştiğinde amaçlanan boşluklandırmayı korumasını sağlamaktır. Düz metin düzenleyiciye ve güncel bir masaüstü tarayıcıya ihtiyacınız var. Örnek, herhangi bir framework, harici varlık veya JavaScript içermeyen sentetik etiketler ve dekoratif bir daire kullanır.

Paylaşılan stil sayfası neyi denetlemeli?

Yönü HTML’ye, boşluklandırmayı ise stil sayfasına bırakın. Her iki sayfa da aynı CSS kaynağını yükler ve aynı bileşen sınıflarını kullanır; sayfa kökü, dir="ltr" veya dir="rtl" değerlerinden birini sağlar. HTML, belge stiline katkıda bulunan harici bir kaynak bağlantısı olarak rel="stylesheet" öğesini tanımlar. HTML Standardı: stil sayfası bağlantıları.

Yön biliniyorsa HTML dir öğesini kullanın. Alt öğeler genellikle yönü devralır ve lang bunu ayarlamaz. Bu kontrollü karşılaştırma için dir="auto" yerine açık yön belirtmeyi tercih edin: otomatik yön, içeriğe bağlıdır ve Latin örnek etiketlerinin LTR seçmesine yol açar. MDN: dir özniteliği.

Önemli ayrım, fiziksel bir kenarla içerik akışındaki konum arasındadır. Bu örneğin horizontal-tb yazım kipinde satır içi başlangıç, LTR’de sol, RTL’de sağ anlamına gelir. Blok başlangıcı ise üstte kalır. Mantıksal özellikler bu ilişkileri doğrudan ifade eder. MDN: mantıksal kenar boşlukları, kenarlıklar ve iç boşluklar.

Amaçlanan boşluklandırma Paylaşılan CSS seçimi Yön değiştiğinde sonuç
Bileşenin başlangıç kenarının iç tarafındaki boşluk padding-inline-start Diğer fiziksel tarafa geçer
Her iki satır içi kenarın iç tarafındaki boşluk padding-inline Başlangıç ve bitiş değerlerini yeni yönde uygular
Flexbox öğeleri arasındaki boşluk gap Belirtilen öğeler arası boşluğu korur
Bu yatay düzende üstteki ve alttaki boşluk padding-block Üstte ve altta kalır
Satır içi akışta bir öğeden önceki kenar boşluğu margin-inline-start Yeni satır içi başlangıç tarafına eşlenir

Kenar boşluğu ve iç boşluk eşlemeleri, öğenin yazım kipini ve yönünü izler. gap ise desteklenen yerleşim kapsayıcılarında aralıklar oluşturur. Bunlar ayrı işlerdir: içeriğin çevresinde iç boşluk, kardeş öğeler arasında aralık kullanın. MDN: mantıksal boşluklandırma, MDN: gap.

Tek bir CSS dosyası kullanan iki yerel sayfa oluşturma

Mac’inizde spacing-demo adlı bir klasör oluşturun. Aşağıdaki dosyaları tam uzantılarıyla düz metin olarak kaydedin. .html veya .css uzantılarının sonuna .txt ekleyen bir düzenleyici kullanmayın.

spacing-demo/
  ltr.html
  rtl.html
  components.css

Bu HTML belgesinin tamamını ltr.html olarak kaydedin. Ardından ikinci bir kopyasını rtl.html olarak kaydedin ve yalnızca kök özniteliğini dir="ltr" değerinden dir="rtl" değerine değiştirin. Stil sayfası referansını ve bileşen işaretlemesini aynı tutun. Sentetik yerleşim karşılaştırması olduğu için etiketler İngilizce kalır.

<!doctype html>
<html lang="en" dir="ltr">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Component spacing sample</title>
  <link rel="stylesheet" href="components.css">
</head>
<body>
  <main class="demo">
    <h1>Spacing sample</h1>
    <article class="sample-card">
      <span class="sample-card__shape" aria-hidden="true"></span>
      <div class="sample-card__copy">
        <h2 class="sample-card__title">Module A</h2>
        <p class="sample-card__description">A compact sample tile</p>
      </div>
      <span class="sample-card__tag">Set B</span>
    </article>
  </main>
</body>
</html>

Şimdi aşağıdaki stil sayfasının tamamını components.css olarak kaydedin. Bilerek eşit olmayan satır içi iç boşluk, yön değişikliklerini incelemeyi kolaylaştırır: daha büyük iç boşluk satır içi başlangıcı izlemelidir.

:root {
  --space-small: 8px;
  --space-medium: 16px;
  --space-large: 24px;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  padding: 24px;
  font-family: system-ui, sans-serif;
  line-height: 1.5;
  color: #243447;
  background: #f2f5f8;
}

.demo {
  writing-mode: horizontal-tb;
  max-width: 640px;
  margin-inline: auto;
}

.sample-card {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: var(--space-medium);
  padding-block: var(--space-medium);
  padding-inline: var(--space-large) var(--space-small);
  border: 1px solid #8594a5;
  border-radius: 12px;
  background: #ffffff;
}

.sample-card__shape {
  flex: 0 0 32px;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: #5477a3;
}

.sample-card__copy {
  flex: 1 1 0;
  min-width: 0;
  overflow-wrap: anywhere;
}

.sample-card__title,
.sample-card__description {
  margin: 0;
}

.sample-card__title {
  font-size: 18px;
}

.sample-card__description {
  margin-block-start: var(--space-small);
}

.sample-card__tag {
  flex: 0 0 auto;
  padding-block: 4px;
  padding-inline: var(--space-small);
  border: 1px solid #8594a5;
  border-radius: 6px;
}

Burada padding-inline: 24px 8px, önce başlangıç, sonra bitiş iç boşluğu anlamına gelir. Soldan sağa sıralama anlamına gelmez. Tek bir değer, her iki satır içi kenara da uygulanır. MDN: padding-inline.

Her iki sayfada da flex-direction: row değerini koruyun. Flexbox satırı zaten kapsayıcısının yönünü izler: LTR’de soldan sağa, RTL’de sağdan sola ilerler. RTL sürümüne row-reverse eklemek bu yönü yeniden tersine çevirir. MDN: flex-direction.

Nötr dairenin yönsel bir anlamı yoktur; bu nedenle çizimi değişmeden kalırken konumu satırı izler. Latin etiketleri de harf sıralarını korur; bu örnek, çevrilmiş metni değil bileşen yerleşimini denetler.

Boşluklandırmanın gerçekten paylaşıldığını nasıl doğrularsınız?

Her iki HTML dosyasını da Mac tarayıcınızda açın ve aynı pencere genişliğinde karşılaştırın. Aşağıdaki değerler, bildirilen tarayıcı ölçümleri değil, bildirimlerden beklenen değerlerdir. Kartın kenarlığı, iç boşluğundan ayrıdır.

Denetim LTR sayfası RTL sayfası
Dairenin konumu Soldaki ilk öğe Sağdaki ilk öğe
Kartın sol iç boşluğu 24px 8px
Kartın sağ iç boşluğu 8px 24px
Bitişik flex öğeleri arasındaki aralık 16px 16px
Kartın üst ve alt iç boşluğu 16px 16px
Açıklamadan önceki boşluk Üstte 8px Üstte 8px

Kaynak paylaşımını yönden ayrı olarak sınayın. components.css dosyasındaki --space-medium değerini 16px değerinden 20px değerine değiştirin, kaydedin ve her iki sayfayı yeniden yükleyin. Her iki sayfada da öğeler arası aralık ve blok iç boşluğu büyümelidir; çünkü bu bildirimler aynı değişkene başvurur. Karşılaştırmadan sonra değeri 16px olarak geri yükleyin.

Ardından tarayıcı penceresini daraltın ve açıklamayı Module A extended sample description gibi daha uzun, sentetik bir etiketle değiştirin. Metnin dairenin veya etiketin üzerine binmeden satır kaydırdığını kontrol edin. Bu, ikinci bir yararlı sınama sağlar: bir bileşen tek bir genişlikte doğru biçimde aynalanırken başka bir genişlikte sıkışık hale gelebilir.

Görünen her mesafeyi yalnızca gap değerine bakarak değerlendirmeyin. Öğe kenar boşlukları, iç iç boşluk ve dağıtılmış hizalama, görünen ayrımı bildirilen aralıktan daha büyük hale getirebilir. Örnek, karşılaştırmanın anlaşılır kalması için metin kenar boşluklarını sıfırlar ve dağıtılmış hizalamadan kaçınır. MDN: gap açıklaması.

Boşluklandırma çakışmaları olmadan mevcut bir bileşeni nasıl geçirirsiniz?

Mevcut her bildirimin ne anlama geldiğiyle başlayın. Öndeki metin iç boşluğu genellikle satır içi başlangıca karşılık gelir; bilerek sabitlenmiş fiziksel bir kenar ise fiziksel özellik gerektirebilir. Her left kullanımını mekanik biçimde değiştirmek yerine tasarımın amacına göre dönüştürün.

Bu örnekteki gibi bir bileşen için şu sırayı izleyin:

  1. Yönü sağlayan üst öğeyi belirleyin.
  2. Yönlü iç boşluğu mantıksal iç boşlukla değiştirin.
  3. Gerektiğinde yönlü dış boşluğu mantıksal kenar boşluklarıyla değiştirin.
  4. Flex öğeleri arasındaki olağan boşluk için üst öğenin gap özelliğini kullanın ve aynı boşluğu daha önce sağlayan kenar boşluklarını kaldırın.
  5. Her iki yönde de eşit olmayan iç boşluk ve dar pencere karşılaştırmalarını tekrarlayın.

Geçiş sırasında eski fiziksel bildirimleri ve daha sonra gelen kısa gösterimleri kontrol edin. Aynı tarafa eşlenen mantıksal ve fiziksel özellikler kademede birlikte yer alır; mantıksal bir özellik sırf mantıksal olduğu için otomatik olarak öncelik kazanmaz. Diğer kademe etkenleri eşitse daha sonra gelen bir padding bildirimi, mantıksal özelliklerle daha önce atanmış iç boşluğu sıfırlayabilir. CSS Mantıksal Özellikler ve Değerler Düzey 1: kutu modeli özellikleri.

Yön sınırını da göz önünde bulundurun. Kendi dir="ltr" özelliği bulunan iç içe bir bileşen, RTL sayfasının içinde bile LTR eşlemelerini kullanmalıdır. Buna karşılık margin-inline özelliğinin kendisi devralınmaz; bu nedenle bir üst öğenin kenar boşluğunun kendisine aktarılmasını beklemek yerine her bileşene ihtiyaç duyduğu boşluklandırma bildirimlerini verin. MDN: yönün devralınması, MDN: margin-inline resmi tanımı.

Bu yaklaşımı hangi tarayıcı sınırlamaları etkiler?

MDN, padding-inline ve margin-inline özelliklerinin Nisan 2021’den bu yana tarayıcılar genelinde yaygın olarak kullanılabildiğini belirtiyor. Bu, güncel masaüstü tarayıcılarında kullanılmalarını destekler; ancak daha eski her tarayıcı veya bu referans sayfalarında gösterilen her yeni sözdizimi için garanti vermez. Bu örnek, daha yeni boyutlandırma işlevleri olmadan sıradan uzunlukları ve auto özelliğini kullanır. MDN: padding-inline, MDN: margin-inline.

Flexbox aralığının ayrı bir geçmişi vardır. Safari bu özelliği 14.1 sürümünde ekledi; Grid aralığı ise Safari 12’den beri destekleniyordu. WebKit, bir özellik sorgusunun bu bağlamları ayırt edemediğini özellikle belirtiyor; bu nedenle eski Safari’de Flexbox aralığı desteğini saptamak için yalnızca @supports (gap: 16px) yeterli değildir. WebKit: Safari 14.1’deki yeni WebKit özellikleri.

Hedef tarayıcınız mantıksal kenar boşluklarını destekliyor ancak Flexbox aralığını desteklemiyorsa, bu değiştirme parçasını ana stil sayfası kurallarından sonra ekleyin. Bu, bu tek satırlı bileşene özel boşluk sağlar. Gösterildiği gibi etkin aralıklandırmanın yerine kullanın; satırları kaydıran düzenler için genel bir çözüm değildir.

/* Optional single-row replacement for Flexbox gap. */
.sample-card {
  gap: 0;
}

.sample-card > * + * {
  margin-inline-start: var(--space-medium);
}

Mantıksal özellikleri de desteklemeyen tarayıcılar için bu yedek çözüm yeterli değildir. Yerel görev için güncel bir tarayıcı kullanın veya eski hedef için açık fiziksel LTR ve RTL kuralları yazıp sınayın. Tarayıcıya özgü bu kararı, paylaşılan stil sayfasının ana tasarımından ayrı tutun.

Tamamlanan karşılaştırma tek ve tutarlı bir kuralı göstermelidir: yönü HTML sağlar, boşluklandırmayı paylaşılan CSS sağlar ve bileşenin başlangıç iç boşluğu satır içi başlangıcı izler. Bileşenin boşluklandırmasını veya yerleşimini her değiştirdiğinizde kısa bir regresyon fikstürü olarak iki yerel sayfayı da saklayın.

Kaynaklar