मुख्य सामग्री पर जाएँ

थीमिंग

यह पृष्ठ अंग्रेज़ी से अनुवादित है। अंग्रेज़ी पृष्ठ पढ़ें

स्थिति: crates/zeyn/assets/zeyn.css में लागू।

डिफ़ॉल्ट UI किट हर रंग, फ़ॉन्ट, आकार और त्रिज्या :root पर CSS custom properties से पढ़ती है। संगठन उनमें से कुछ को ओवरराइड करके रूप बदलता है। उसे कभी zeyn.css संपादित करने या सेलेक्टर लिखने की ज़रूरत नहीं।

1. थीम कैसे लागू होती है

सर्वर पहले zeyn.css परोसता है और फिर, जब ऐप के पास हो, टोकन ओवरराइड वाली एक अतिरिक्त स्टाइलशीट। ओवरराइड फ़ाइल में केवल :root ब्लॉक होते हैं:

:root {
  --z-brand: #7a2448;
  --z-font: "Source Sans 3", "Segoe UI", system-ui, sans-serif;
  --z-radius: 8px;
  --z-density: 0.75;
}

ओवरराइड फ़ाइल के नियम:

  • इसे ऐप के अपने origin से परोसा जाना चाहिए। Content Security Policy style-src 'self' है, इसलिए इनलाइन <style> ब्लॉक और तीसरे पक्ष की स्टाइलशीट अवरुद्ध हैं।
  • फ़ॉन्ट उपयोगकर्ताओं की मशीनों पर पहले से इंस्टॉल होने चाहिए या ऐप के origin से परोसे जाने चाहिए। किट खुद कोई वेब फ़ॉन्ट लोड नहीं करती।
  • इसे zeyn.css के बाद लोड करें, ताकि समान सेलेक्टर में क्रम से जीत तय हो।
  • खंड 2 के आधार टोकन सेट करें। खंड 3 के व्युत्पन्न टोकन अपने आप साथ चलते हैं। व्युत्पन्न टोकन केवल तब ओवरराइड करें जब गणना किया मान आपके ब्रांड के लिए काम न करे।

लाइट, डार्क और ऐप थीम

हर ऐप के मेनू में भाषा चयनकर्ता के पास थीम चयनकर्ता है। यह System (prefers-color-scheme का पालन करता है), Light, Dark और ऐप द्वारा परिभाषित कोई भी थीम देता है:

App::new("Billing")
    .theme(Theme::new().brand("#7a2448").radius(6))
    .themes([
        Theme::light(),
        Theme::dark(),
        Theme::named("sand", [("--z-bg", "#f5f1ea"), ("--z-surface", "#fffdf8")]).label(t!("theme.sand")),
    ])
    .default_theme("system")
  • App::theme संगठन का रूप है और हर थीम के नीचे लागू होता है।
  • App::themes सूचीबद्ध करता है कि उपयोगकर्ता क्या चुन सकते हैं। इसके बिना सूची Light और Dark है। जब दोनों सूची में हों तब System दिया जाता है। Theme::named(...) लाइट थीम पर बनती है; .dark_base() इसे डार्क पर बनाता है।
  • App::default_theme उन उपयोगकर्ताओं की थीम है जिन्होंने नहीं चुना। जब तक सेट न हो system।
  • App::theme_picker(false) चयनकर्ता छिपाता है; सबको डिफ़ॉल्ट थीम मिलती है।
  • एक अकेली थीम ऐप को लॉक कर देती है: .themes([Theme::named("acme", tokens)]) या .theme(Theme::dark())।

ऐप शुरू होने पर टोकन जाँचे जाते हैं। App::check (और इसलिए router और serve) अज्ञात टोकन नाम, ऐसे मान जो अपनी घोषणा से बाहर निकल सकते हैं (;, ब्रेस, \, <, >, url(), खराब थीम नाम, अज्ञात डिफ़ॉल्ट थीम, और खंड 5 की हर रंग जोड़ी बताता है जिसे कोई थीम WCAG 2.2 AA से नीचे धकेलती है। कंट्रास्ट के लिए केवल #rgb और #rrggbb मान जाँचे जा सकते हैं; अन्य रंग सिंटैक्स पर भरोसा किया जाता है।

सभी थीम एक स्टाइलशीट /_zeyn/theme.css में परोसी जाती हैं, जो स्टार्टअप पर एक बार बनती है और किट की स्टाइलशीट के बाद लोड होती है। चुनाव zeyn_theme कुकी में रखा जाता है और, व्यू स्टोर (App::datagrid_views) वाले ऐप में साइन इन उपयोगकर्ता के लिए, उस स्टोर में, इसलिए वह उपयोगकर्ता के साथ नए डिवाइस पर जाता है। सर्वर थीम को <html> पर रेंडर करता है, इसलिए पहली पेंट पहले से सही होती है और इनलाइन स्क्रिप्ट की ज़रूरत नहीं:

मार्कअपपरिणाम
<html>System: prefers-color-scheme का पालन करता है
<html data-theme="light">हमेशा लाइट
<html data-theme="dark">हमेशा डार्क
<html data-theme="light" data-zeyn-theme="sand">ऐप थीम sand, लाइट थीम पर

चयनकर्ता में थीम बदलना केवल ये एट्रिब्यूट और color-scheme meta बदलता है, फिर POST /_zeyn/theme कॉल करता है। कुछ रीलोड नहीं होता।

हाथ से लिखी ओवरराइड फ़ाइल में डार्क थीम को अपने मान देने के लिए, वही सेलेक्टर दोहराएँ जो किट इस्तेमाल करती है:

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --z-bg: #0e1012; }
}
:root[data-theme="dark"] { --z-bg: #0e1012; }

घनत्व

--z-density स्पेसिंग इकाई को स्केल करता है। 1 सामान्य है, 0.75 कॉम्पैक्ट। <html data-density="compact"> बिना स्टाइलशीट के 0.75 सेट करता है। कंट्रोल और ग्रिड पंक्तियाँ कभी 24 px से छोटी नहीं होतीं, इसलिए कॉम्पैक्ट मोड भी WCAG 2.2 लक्ष्य आकार पूरा करता है।

वर्चुअल ग्रिड की पंक्ति ऊँचाई सर्वर तय करता है (Paging::virtual_rows(px), डिफ़ॉल्ट 32 px) क्योंकि रनटाइम स्क्रॉल स्थितियाँ उसी से निकालता है। घनत्व इसे नहीं बदलता।

2. आधार टोकन

ये वे टोकन हैं जिन्हें संगठन से सेट करने की अपेक्षा है।

टोकनउद्देश्यलाइटडार्क
--z-brandएकमात्र ब्रांड रंग। प्राइमरी बटन, ऐप नाम पट्टी, मौजूदा मेनू आइटम, फ़ोकस की गई पंक्ति, फ़ोकस रिंग#0f6674वही मान; देखें --z-accent
--z-on-brandठोस --z-brand सतह पर टेक्स्ट#ffffff#ffffff
--z-fontइंटरफ़ेस फ़ॉन्ट स्टैक"Segoe UI Variable Text", "Segoe UI", system-ui, -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, "Noto Sans", sans-serifवही
--z-font-monoकोड, API उदाहरणui-monospace, "Cascadia Mono", "SF Mono", "Segoe UI Mono", Menlo, Consolas, monospaceवही
--z-font-sizeमुख्य टेक्स्ट0.875rem (14 px)वही
--z-font-size-smग्रिड सेल, लेबल, फ़िल्टर0.8125rem (13 px)वही
--z-font-size-xsकॉलम शीर्षक, मेनू समूह शीर्षक, पृष्ठ जानकारी0.75rem (12 px)वही
--z-radiusआधार कोने की त्रिज्या, 0 से 12 px। हर कंपोनेंट इसी से स्केल होता है4pxवही
--z-densityस्पेसिंग गुणक, 1 सामान्य, 0.75 कॉम्पैक्ट1वही
--z-bgपैनल के पीछे पृष्ठ की पृष्ठभूमि#f4f5f6#121416
--z-surfaceपैनल, ग्रिड, Window, इनपुट#ffffff#1a1d20
--z-surface-2ग्रिड शीर्षक, ज़ेब्रा पंक्तियाँ, Window फ़ुटर, केवल पढ़ने योग्य इनपुट#f7f8f9#202326
--z-hoverपंक्तियों, मेनू आइटम, बटन के लिए होवर पृष्ठभूमि#eceef1#2a2e33
--z-borderविभाजक और पैनल की रूपरेखा#dcdfe3#33383e
--z-border-strongइनपुट और बटन की रूपरेखा, शीर्षक रेखा। --z-surface के विरुद्ध 3:1 तक पहुँचना चाहिए#7d848d#7a818a
--z-textमुख्य टेक्स्ट और मान#1a1d21#e4e6e9
--z-text-mutedलेबल, शीर्षक, गौण टेक्स्ट। --z-surface-2 के विरुद्ध 4.5:1 तक पहुँचना चाहिए#5b626b#a2a9b1
--z-dangerत्रुटियाँ, आवश्यक चिह्न, danger पंक्तियाँ#b3261e#f28b82
--z-warningचेतावनी पंक्तियाँ#8a5300#e6b45a
--z-successसफलता पंक्तियाँ#1e6b3a#6fcf8f
--z-infoInfo टोस्ट#2b5d8a#8ab8e6

3. व्युत्पन्न टोकन

आधार टोकन से color-mix() और relative color सिंटैक्स से गणना किए जाते हैं। जब आधार टोकन बदलता है तो ये अपने आप अपडेट होते हैं।

टोकनउद्देश्यलाइटडार्क
--z-accentसतह पर टेक्स्ट या पतली रेखा के रूप में इस्तेमाल हुआ ब्रांड रंग: लिंक, मौजूदा मेनू आइटम, फ़ोकस की गई पंक्ति की पट्टीvar(--z-brand)oklch(from var(--z-brand) 0.8 c h), ब्रांड की ह्यू एक निश्चित हल्के टोन पर। relative color सिंटैक्स के बिना ब्राउज़र को color-mix(in oklab, var(--z-brand) 45%, #fff) मिलता है
--z-primaryप्राइमरी बटन का भरावvar(--z-brand)var(--z-accent)
--z-on-primaryप्राइमरी बटन का टेक्स्टvar(--z-on-brand)#121416
--z-primary-hoverप्राइमरी बटन होवरब्रांड 86% काले के साथ मिला हुआaccent 84% सफ़ेद के साथ मिला हुआ
--z-primary-activeप्राइमरी बटन दबा हुआब्रांड 74% काले के साथ मिला हुआaccent 70% सफ़ेद के साथ मिला हुआ
--z-brand-subtleमौजूदा मेनू आइटम और फ़ोकस की गई ग्रिड पंक्ति के पीछे की हल्की छटा--z-surface के ऊपर --z-tint पर accentवही सूत्र
--z-focusफ़ोकस रिंगvar(--z-accent)var(--z-accent)
--z-danger-subtle, --z-warning-subtle, --z-success-subtle, --z-info-subtleपंक्ति और संदेश की पृष्ठभूमि--z-surface के ऊपर --z-tint पर स्टेटस रंगवही सूत्र
--z-tintहल्की छटाओं की तीव्रता9%20%
--z-spaceस्पेसिंग इकाईcalc(4px * var(--z-density))वही
--z-controlबटन और इनपुट की ऊँचाईmax(24px, 8 * --z-space) (32 px)वही
--z-rowपृष्ठबद्ध और अनंत ग्रिड के लिए ग्रिड पंक्ति ऊँचाईmax(24px, 8 * --z-space) (32 px)वही
--z-gapScreen खंडों के बीच अंतर3 * --z-space (12 px)वही
--z-radius-sm, --z-radius-lgछोटे हिस्से (फ़िल्टर, कोड), Window--z-radius का 0.75x और 1.5xवही
--z-shadow-2केवल Window और टोस्ट। ग्रिड पंक्तियों को कभी छाया नहीं मिलतीनरम दो परत की छायागहरी
--z-backdropमोडल Window के पीछेrgb(20 24 28 / 40%)rgb(0 0 0 / 60%)
--z-dirपढ़ने की दिशा का चिह्न, उन ऑफ़सेट के लिए जिनका तार्किक रूप नहीं है (शुरुआती या अंतिम तरफ़ दिखाने वाली भीतरी छाया, स्लाइड ट्रांसफ़ॉर्म): calc(2px * var(--z-dir))1, और dir="rtl" में -1वही

सर्वर मार्कअप द्वारा सेट किए प्रति एलिमेंट टोकन: --z-width (Window चौड़ाई), --z-flex (कॉलम हिस्सा), --z-row-height (वर्चुअल ग्रिड पंक्ति ऊँचाई), और कंपोनेंट लाइब्रेरी के लिए --z-stack-gap, --z-split, --z-progress, --z-columns, --z-level और --z-pop-x / --z-pop-y (पॉपअप स्थिति)।

चार्ट श्रृंखला के रंग components.css में --z-chart-1 से --z-chart-6 हैं, डार्क थीम में हल्के मानों के साथ। हर एक --z-surface के विरुद्ध 3:1 तक पहुँचता है। इन्हें किसी भी आधार टोकन की तरह ओवरराइड करें।

4. ब्रांड रंग चुनना

  • --z-brand लाइट थीम में सफ़ेद टेक्स्ट वहन करता है (बटन, ऐप नाम पट्टी)। ऐसा रंग चुनें जो --z-on-brand के विरुद्ध कम से कम 4.5:1 हो। अधिकतर मध्यम से गहरे ब्रांड रंग पास होते हैं। पीले जैसे हल्के ब्रांड रंग के लिए --z-on-brand को भी गहरे रंग पर सेट करें।
  • डार्क थीम में किट टेक्स्ट, रिंग और प्राइमरी बटन के लिए ब्रांड को हल्का करती है, और ऐप नाम पट्टी के लिए ठोस ब्रांड रखती है। अलग ब्रांड दोनों थीम में बिना दूसरे रंग के सोच-समझकर चुना दिखता है।
  • स्टेटस रंग ब्रांड से अलग रखें। लाल त्रुटि पंक्तियों के पास लाल ब्रांड त्रुटियाँ पहचानना कठिन बनाता है; ऐसे में --z-danger को अलग लाल की ओर खिसकाएँ या --z-brand-subtle ओवरराइड करके ब्रांड को ग्रिड से दूर रखें।
  • अपने रंगों को खंड 5 की तालिका को लक्ष्य मानकर जाँचें। सीमा से नीचे की कोई भी जोड़ी WCAG 2.2 AA में विफल होती है।

5. सत्यापित कंट्रास्ट

चल रहे उदाहरण ऐप पर Chromium में मापा गया: हर टोकन को उसके रेंडर किए sRGB मान तक हल किया गया (color-mix() और relative colors समेत), फिर WCAG 2.x कंट्रास्ट अनुपात गणना किया गया। सीमाएँ: टेक्स्ट के लिए 4.5:1, UI कंपोनेंट रूपरेखा और फ़ोकस संकेतकों के लिए 3:1।

जोड़ीलाइटडार्कज़रूरी
--z-text on --z-bg15.4914.774.5
--z-text on --z-surface16.9113.544.5
--z-text on --z-surface-215.9112.634.5
--z-text on --z-hover14.5510.934.5
--z-text on --z-brand-subtle (फ़ोकस की गई पंक्ति)14.799.274.5
--z-text on --z-danger-subtle14.739.764.5
--z-text on --z-warning-subtle14.829.314.5
--z-text on --z-success-subtle14.769.334.5
--z-text-muted on --z-bg5.657.784.5
--z-text-muted on --z-surface6.177.134.5
--z-text-muted on --z-surface-2 (शीर्षक)5.806.654.5
--z-text-muted on --z-hover5.315.764.5
--z-text-muted on --z-danger-subtle (धुँधली पंक्ति)5.375.144.5
--z-text-muted on --z-warning-subtle5.414.904.5
--z-accent on --z-surface (लिंक)6.629.334.5
--z-accent on --z-bg6.0610.184.5
--z-accent on --z-brand-subtle (मौजूदा मेनू आइटम)5.796.394.5
--z-on-primary on --z-primary6.6210.184.5
--z-on-primary on --z-primary-hover8.8211.264.5
--z-on-primary on --z-primary-active11.1212.264.5
--z-on-brand on --z-brand (ऐप नाम पट्टी)6.626.624.5
--z-danger on --z-surface (फ़ील्ड त्रुटियाँ)6.547.094.5
--z-danger on --z-danger-subtle5.695.114.5
--z-warning on --z-surface6.338.904.5
--z-warning on --z-warning-subtle5.556.124.5
--z-success on --z-surface6.528.874.5
--z-info on --z-surface6.928.134.5
--z-focus on --z-surface6.629.333
--z-focus on --z-bg6.0610.183
--z-focus on --z-brand-subtle5.796.393
--z-border-strong on --z-surface (इनपुट रूपरेखा)3.784.303
--z-border-strong on --z-surface-23.554.013

--z-border सजावटी है (उन आइटम के बीच विभाजक जिनमें पहले से टेक्स्ट है) और 3:1 के लिए बाध्य नहीं है।

6. अन्य सुगम्यता व्यवहार

  • हर इंटरैक्टिव एलिमेंट --z-focus में 2 px :focus-visible रिंग दिखाता है। ग्रिड पंक्तियाँ रिंग को पंक्ति के भीतर बनाती हैं ताकि वह स्क्रॉल कंटेनर से कभी कटे नहीं।
  • बटन, इनपुट, क्रम शीर्षक, फ़िल्टर बॉक्स, पेजर बटन और Window बंद करने का बटन किसी भी घनत्व पर कम से कम 24 x 24 px हैं।
  • prefers-reduced-motion: reduce टोस्ट का प्रवेश और सभी ट्रांज़िशन हटा देता है।
  • forced-colors मोड में आइकन CanvasText इस्तेमाल करते हैं, प्राइमरी बटन और फ़ोकस की गई पंक्ति Highlight इस्तेमाल करते हैं, और पृष्ठभूमि की छटाओं पर निर्भर स्थिति (मौजूदा मेनू आइटम, पंक्ति स्टेटस) को इसके बजाय आउटलाइन या बॉर्डर मिलता है।