HTML की दिशा स्पष्ट रूप से सेट करके, दिशात्मक स्पेसिंग के लिए लॉजिकल प्रॉपर्टीज़ का उपयोग करके और लेआउट आइटमों के बीच gap रखकर LTR और RTL पेजों के बीच एक CSS फ़ाइल साझा करें। यह गाइड दो स्थानीय पेजों का उदाहरण बनाती है, जिनकी तुलना आप Mac ब्राउज़र में कर सकते हैं।

काम यह है कि इनलाइन दिशा बदलने पर भी वही छोटा कॉम्पोनेंट अपनी तय स्पेसिंग बनाए रखे। आपको एक साधारण टेक्स्ट एडिटर और मौजूदा डेस्कटॉप ब्राउज़र चाहिए। इस उदाहरण में काल्पनिक लेबल और सजावटी वृत्त का उपयोग है; इसमें कोई फ़्रेमवर्क, बाहरी एसेट या JavaScript नहीं है।

साझा स्टाइलशीट को क्या नियंत्रित करना चाहिए?

दिशा की ज़िम्मेदारी HTML को दें और स्पेसिंग की ज़िम्मेदारी स्टाइलशीट को। दोनों पेज एक ही CSS संसाधन लोड करते हैं और एक ही कॉम्पोनेंट क्लास इस्तेमाल करते हैं; पेज का रूट या तो dir="ltr" या dir="rtl" देता है। HTML, rel="stylesheet" को दस्तावेज़ की स्टाइलिंग में योगदान देने वाले बाहरी संसाधन लिंक के रूप में परिभाषित करता है। HTML Standard: स्टाइलशीट लिंक।

दिशा ज्ञात हो तो HTML dir का उपयोग करें। आम तौर पर वंशज दिशा इनहेरिट करते हैं, और lang इसे सेट नहीं करता। इस नियंत्रित तुलना के लिए dir="auto" की जगह स्पष्ट दिशा चुनें: स्वचालित दिशा सामग्री पर निर्भर करती है और इससे लैटिन नमूना लेबल LTR चुनेंगे। MDN: dir एट्रिब्यूट।

यहाँ उपयोगी अंतर किसी भौतिक किनारे और सामग्री के प्रवाह में किसी स्थिति के बीच है। इस उदाहरण के horizontal-tb लेखन मोड में, इनलाइन स्टार्ट का अर्थ LTR में बायाँ और RTL में दायाँ है। ब्लॉक स्टार्ट ऊपर ही रहता है। लॉजिकल प्रॉपर्टीज़ इन संबंधों को सीधे व्यक्त करती हैं। MDN: लॉजिकल मार्जिन, बॉर्डर और पैडिंग।

अपेक्षित स्पेसिंग साझा CSS विकल्प दिशा बदलने पर परिणाम
कॉम्पोनेंट के अग्रणी किनारे के अंदर की जगह padding-inline-start दूसरी भौतिक ओर चली जाती है
दोनों इनलाइन किनारों के अंदर की जगह padding-inline नई दिशा में स्टार्ट और एंड मान लागू करती है
Flexbox आइटमों के बीच की जगह gap आइटमों के बीच निर्दिष्ट गैप बनाए रखती है
इस क्षैतिज लेआउट में ऊपर और नीचे की जगह padding-block ऊपर और नीचे ही रहती है
इनलाइन प्रवाह में किसी एलिमेंट से पहले का मार्जिन margin-inline-start नई इनलाइन-स्टार्ट ओर पर मैप होता है

मार्जिन और पैडिंग की मैपिंग एलिमेंट के लेखन मोड और दिशा के अनुसार होती है। इसके बजाय gap समर्थित लेआउट कंटेनरों में गटर बनाता है। ये अलग-अलग काम हैं: सामग्री के चारों ओर पैडिंग और सिबलिंग आइटमों के बीच गैप इस्तेमाल करें। MDN: लॉजिकल स्पेसिंग, MDN: gap।

एक CSS फ़ाइल इस्तेमाल करने वाले दो स्थानीय पेज बनाएँ

अपने Mac पर spacing-demo नाम का फ़ोल्डर बनाएँ। नीचे दी गई फ़ाइलों को उनके सटीक एक्सटेंशन के साथ सादे टेक्स्ट के रूप में सहेजें। ऐसा एडिटर इस्तेमाल न करें जो .html या .css के बाद .txt जोड़ दे।

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

यह पूरा HTML दस्तावेज़ ltr.html नाम से सहेजें। फिर इसकी दूसरी प्रति rtl.html नाम से सहेजें और केवल रूट एट्रिब्यूट को dir="ltr" से बदलकर dir="rtl" करें। स्टाइलशीट संदर्भ और कॉम्पोनेंट मार्कअप एक जैसे रखें। लेबल अंग्रेज़ी में ही रहेंगे, क्योंकि यह लेआउट की काल्पनिक तुलना है।

<!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>

अब नीचे दी गई पूरी स्टाइलशीट को components.css नाम से सहेजें। जान-बूझकर असमान इनलाइन पैडिंग रखी गई है, ताकि दिशा का बदलाव आसानी से देखा जा सके: बड़ा इनसेट इनलाइन स्टार्ट के साथ जाना चाहिए।

: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;
}

यहाँ, padding-inline: 24px 8px का अर्थ है स्टार्ट पैडिंग के बाद एंड पैडिंग। इसका अर्थ बाएँ के बाद दायाँ नहीं है। एक मान देने पर वह दोनों इनलाइन किनारों पर लागू होगा। MDN: padding-inline।

दोनों पेजों में flex-direction: row रखें। Flexbox की row पहले से ही अपने कंटेनर की दिशा का अनुसरण करती है: LTR में यह बाएँ से दाएँ और RTL में दाएँ से बाएँ चलती है। RTL संस्करण में row-reverse जोड़ने पर दिशा फिर से उलट जाएगी। MDN: flex-direction।

तटस्थ वृत्त का कोई दिशात्मक अर्थ नहीं है, इसलिए इसकी आकृति अपरिवर्तित रहती है, जबकि इसकी स्थिति row के साथ चलती है। लैटिन लेबलों में अक्षरों का क्रम भी वही रहता है; यह उदाहरण कॉम्पोनेंट लेआउट की जाँच करता है, अनूदित टेक्स्ट की नहीं।

कैसे जाँचें कि स्पेसिंग वास्तव में साझा है?

दोनों HTML फ़ाइलें अपने Mac ब्राउज़र में खोलें और समान विंडो चौड़ाई पर उनकी तुलना करें। नीचे दिए गए मान घोषणाओं से अपेक्षित हैं; ये ब्राउज़र में मापे गए मान नहीं हैं। कार्ड का बॉर्डर उसकी पैडिंग से अलग है।

जाँच LTR पेज RTL पेज
वृत्त की स्थिति बाईं ओर पहला आइटम दाईं ओर पहला आइटम
कार्ड की बाईं पैडिंग 24px 8px
कार्ड की दाईं पैडिंग 8px 24px
पास-पास के flex आइटमों के बीच गैप 16px 16px
कार्ड की ऊपर और नीचे की पैडिंग 16px 16px
विवरण से पहले की जगह ऊपर 8px ऊपर 8px

दिशा से अलग संसाधन साझा होने की जाँच करें। components.css में --space-medium को 16px से बदलकर 20px करें, सहेजें और दोनों पेज फिर से लोड करें। दोनों में आइटमों के बीच का गैप और ब्लॉक पैडिंग बढ़नी चाहिए, क्योंकि ये घोषणाएँ उसी वेरिएबल का संदर्भ देती हैं। तुलना के बाद इसे फिर 16px पर सेट करें।

फिर ब्राउज़र विंडो की चौड़ाई कम करें और विवरण को किसी लंबे काल्पनिक लेबल से बदलें, जैसे Module A extended sample description। जाँचें कि टेक्स्ट वृत्त या टैग को ढके बिना रैप होता है। इससे दूसरी उपयोगी जाँच होती है: कोई कॉम्पोनेंट एक चौड़ाई पर सही ढंग से मिरर हो सकता है, लेकिन दूसरी चौड़ाई पर तंग पड़ सकता है।

हर दिखाई देने वाली दूरी का आकलन केवल gap से न करें। आइटम मार्जिन, आंतरिक पैडिंग और वितरित संरेखण से दिखाई देने वाला अंतर घोषित गटर से बड़ा हो सकता है। तुलना को समझने योग्य रखने के लिए नमूने में टेक्स्ट मार्जिन रीसेट किए गए हैं और वितरित संरेखण का उपयोग नहीं किया गया है। MDN: gap का विवरण।

स्पेसिंग टकराव के बिना मौजूदा कॉम्पोनेंट को कैसे माइग्रेट करें?

हर मौजूदा घोषणा का आशय समझने से शुरुआत करें। टेक्स्ट का अग्रणी इनसेट आम तौर पर इनलाइन स्टार्ट से जुड़ा होता है; डिज़ाइन में जान-बूझकर तय किए गए भौतिक किनारे के लिए भौतिक प्रॉपर्टी की ज़रूरत हो सकती है। डिज़ाइन के आशय के अनुसार बदलाव करें; left की हर आवृत्ति को यांत्रिक रूप से न बदलें।

इस नमूने जैसे कॉम्पोनेंट के लिए यह क्रम अपनाएँ:

  1. उस पूर्वज की पहचान करें जो दिशा देता है।
  2. दिशात्मक आंतरिक स्पेसिंग को लॉजिकल पैडिंग से बदलें।
  3. जहाँ ज़रूरी हो, दिशात्मक बाहरी स्पेसिंग को लॉजिकल मार्जिन से बदलें।
  4. Flex आइटमों के बीच सामान्य स्पेसिंग के लिए पैरेंट का gap इस्तेमाल करें और पहले उसी जगह देने वाले मार्जिन हटा दें।
  5. दोनों दिशाओं में असमान पैडिंग और संकरी विंडो की तुलना फिर से करें।

माइग्रेशन के दौरान पुराने भौतिक डिक्लेरेशन और बाद में आने वाले शॉर्टहैंड देखें। एक ही किनारे पर मैप होने वाली लॉजिकल और भौतिक प्रॉपर्टीज़ कैस्केड में साथ भाग लेती हैं; लॉजिकल होने से प्रॉपर्टी को अपने-आप प्राथमिकता नहीं मिलती। अगर कैस्केड के अन्य कारक समान हों, तो बाद में आने वाला padding लॉजिकल प्रॉपर्टीज़ के ज़रिए तय की गई पैडिंग को रीसेट कर सकता है। CSS Logical Properties and Values Level 1: बॉक्स मॉडल प्रॉपर्टीज़।

दिशा की सीमा का भी ध्यान रखें। अपने dir="ltr" वाले नेस्टेड कॉम्पोनेंट को RTL पेज के भीतर भी LTR मैपिंग इस्तेमाल करनी चाहिए। दूसरी ओर, margin-inline स्वयं इनहेरिट नहीं होता, इसलिए हर कॉम्पोनेंट को उसकी ज़रूरत वाली स्पेसिंग घोषणाएँ दें; यह न मानें कि पूर्वज का मार्जिन उस तक पहुँच जाएगा। MDN: दिशा का इनहेरिटेंस, MDN: margin-inline की औपचारिक परिभाषा।

इस तरीके पर ब्राउज़र की कौन-सी सीमाएँ असर डालती हैं?

MDN के अनुसार padding-inline और margin-inline अप्रैल 2021 से ब्राउज़रों में व्यापक रूप से उपलब्ध हैं। इससे मौजूदा डेस्कटॉप ब्राउज़रों में उनका उपयोग समर्थित होता है, लेकिन इससे हर पुराने ब्राउज़र या उन संदर्भ पेजों पर दिखाए गए हर नए सिंटैक्स की गारंटी नहीं मिलती। यह उदाहरण साधारण लंबाइयों और auto का उपयोग करता है, नए साइज़िंग फ़ंक्शन का नहीं। MDN: padding-inline, MDN: margin-inline।

Flexbox gap का इतिहास अलग है। Safari संस्करण 14.1 में इसका समर्थन जोड़ता है; Grid gap Safari 12 से समर्थित था। WebKit विशेष रूप से बताता है कि प्रॉपर्टी फ़ीचर क्वेरी इन संदर्भों में अंतर नहीं कर सकती थी, इसलिए पुराने Safari में Flexbox gap समर्थन का पता लगाने के लिए केवल @supports (gap: 16px) पर्याप्त नहीं है। WebKit: Safari 14.1 में नई WebKit सुविधाएँ।

अगर आपका लक्षित ब्राउज़र लॉजिकल मार्जिन का समर्थन करता है, लेकिन Flexbox gap का नहीं, तो मुख्य स्टाइलशीट नियमों के बाद यह प्रतिस्थापन फ़्रैगमेंट जोड़ें। यह इस खास सिंगल-row कॉम्पोनेंट के लिए स्पेसिंग देता है। दिखाए अनुसार, इसे सक्रिय gap स्पेसिंग के बजाय इस्तेमाल करें; यह रैप होने वाली rows के लिए सामान्य समाधान नहीं है।

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

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

जिन ब्राउज़रों में लॉजिकल प्रॉपर्टीज़ का भी समर्थन नहीं है, उनके लिए यह फ़ॉलबैक पर्याप्त नहीं है। स्थानीय काम के लिए मौजूदा ब्राउज़र इस्तेमाल करें, या पुराने लक्षित ब्राउज़र के लिए स्पष्ट भौतिक LTR और RTL नियम लिखकर उनका परीक्षण करें। ब्राउज़र-विशिष्ट इस निर्णय को साझा स्टाइलशीट के मुख्य डिज़ाइन से अलग रखें।

पूरी हुई तुलना में एक सुसंगत अनुबंध दिखना चाहिए: HTML दिशा देता है, साझा CSS स्पेसिंग देता है और कॉम्पोनेंट का अग्रणी इनसेट इनलाइन स्टार्ट का अनुसरण करता है। कॉम्पोनेंट की स्पेसिंग या लेआउट बदलने पर इन दोनों स्थानीय पेजों को छोटे regression fixture के रूप में रखें।

स्रोत