কম্পোনেন্ট-নির্দিষ্ট লাইট/ডার্ক থিম

ওয়েব ফিচার: color-scheme light-dark()

সাধারণত রুটে সেট করা হলেও, color-scheme প্রপার্টি স্বতন্ত্র এলিমেন্টে সেট করা যেতে পারে যাতে পৃষ্ঠার বাকি অংশের থেকে আলাদা রঙের স্কিমে সেগুলি দেখানো যায়। এটি এমন কম্পোনেন্টের জন্য উপযোগী হতে পারে যা সবসময় নির্দিষ্ট রঙের স্কিমে (যেমন, সবসময় ডার্ক বা লাইট মোডে) দেখতে হবে।

ব্যবহারের উদাহরণে এগুলি অন্তর্ভুক্ত:

  • এমন এলিমেন্ট যা নান্দনিক কারণে লাইট মোড পৃষ্ঠাতেও প্রায়শই ডার্ক মোডে থাকে, যেমন কোড ব্লক, মিডিয়া প্লেয়ার, ফটো গ্যালারি
  • যেসব অংশে লাইট ব্যাকগ্রাউন্ডের জন্য ডিজাইন করা মিডিয়া (যেমন, ছবি, ভিডিও, ইলাস্ট্রেশন, প্রিন্ট প্রিভিউ) থাকে, সেগুলি লাইট মোডে সেট করা যেতে পারে, এমনকি পৃষ্ঠার বাকি অংশ ডার্ক মোডে থাকলেও।
  • যেসব এলিমেন্টের কালার-স্কিম ব্যবহারকারী-লেভেল সেটিং দ্বারা নিয়ন্ত্রিত হয়, যেমন কম্পোনেন্ট প্রিভিউ
  • লাইট ও ডার্ক মোড, দুটিতেই কাজ করে না এমন এম্বেড
  • ডিজাইন টুল, ম্যাপ, ভিজ্যুয়ালাইজেশন, গেম ইত্যাদি।

কখন রঙ পরিবর্তন করতে হবে বনাম কখন color-scheme জোর করে করতে হবে?

লাইট মোডে গাঢ় ব্যাকগ্রাউন্ডে হালকা টেক্সট বা ডার্ক মোডে হালকা ব্যাকগ্রাউন্ডে গাঢ় টেক্সট ব্যবহার করা প্রতিটি এলিমেন্টের জন্য আলাদা color-scheme-এর প্রয়োজন হয় না। যেমন, লাইট মোডে সাদা টেক্সট সহ নীল রঙের প্রাথমিক বোতাম দেখানো হতে পারে, তবে তার জন্য color-scheme: dark-এর প্রয়োজন নেই।

সাধারণত, যেসব এলিমেন্ট আলাদা color-scheme ব্যবহার করে সেগুলি হল জটিল সারফেস যা সাধারণ অগভীর কন্টেনারের পরিবর্তে নিজস্ব ভিজ্যুয়াল কন্টেক্সট তৈরি করে।

কোনও এলিমেন্টে অন্য color-scheme ব্যবহার করার কথা বিবেচনা করার সময়, নিজেকে জিজ্ঞাসা করুন:

  • বিল্ট-ইন ব্রাউজার UI যা অন্যভাবে কাস্টমাইজ করা হয়নি (যেমন ফর্ম কন্ট্রোল, স্ক্রলবার ইত্যাদি) সেটির কি সেই কালার-স্কিম ব্যবহার করা উচিত নাকি পৃষ্ঠার কালার-স্কিমের সাথে মানিয়ে নেওয়া উচিত? -> যদি প্রথমটি হয়, তাহলে color-scheme ব্যবহার করবেন না।
  • কোনও light-dark() রঙ কি পৃষ্ঠার বাকি অংশের মতো বা ওভাররাইডের ভিত্তিতে সমাধান করা উচিত? -> যদি প্রথমটি হয়, তাহলে color-scheme ব্যবহার করবেন না।
  • বংশধররা কি সেই color-scheme-এ থাকবে? যদি না হয়, তাহলে color-scheme ব্যবহার করবেন না।

প্রাথমিক প্রয়োগ

কম্পোনেন্ট-নির্দিষ্ট ওভাররাইড সাধারণত (যদিও কঠোরভাবে প্রয়োজনীয় নয়) এমন পৃষ্ঠাগুলিতে ব্যবহার করা হয় যা গ্লোবাল color-scheme-এর মাধ্যমে একাধিক রঙের স্কিমও সমর্থন করে। পৃষ্ঠা-ব্যাপী ডার্ক মোড ভালভাবে প্রয়োগ করার জন্য, ডার্ক মোড দেখুন।

পৃষ্ঠা-ব্যাপী color-scheme সেট করা হয়ে গেলে এবং আপনি এটির প্রতি সংবেদনশীল কালার টোকেন ব্যবহার করলে (যেমন, light-dark()-এর মাধ্যমে), আপনি নির্দিষ্ট কম্পোনেন্টে color-scheme সেট করে সেই সাব-ট্রির জন্য কালার মোড ওভাররাইড করতে পারবেন:

pre, code, .dark {
  color-scheme: dark;
}

মনে রাখবেন, কিছু ব্রাউজার অটোমেটিক কম্পোনেন্টকে অন্য রঙের স্কিমে অ্যাডাপ্ট করে। সব ক্ষেত্রে নির্দিষ্ট রঙের স্কিম প্রয়োগ করতে, only ব্যবহার করুন, অর্থাৎ color-scheme: dark;-এর পরিবর্তে color-scheme: only dark;।

রঙ ছাড়া অন্যান্য ভ্যালু অ্যাডাপ্ট করা হচ্ছে

light-dark() বর্তমানে শুধুমাত্র রঙের জন্য কাজ করে।

পেশাদার পদ্ধতি

  • বাধ্যতামূলক: ব্যাকগ্রাউন্ড ছাড়া এলিমেন্টে color-scheme সেট করবেন না, কারণ এর ফলে বিভিন্ন রঙের স্কিম থেকে ব্যাকগ্রাউন্ড এবং টেক্সটের রঙের জোড়া মিশে যাওয়ার ঝুঁকি থাকে, যার ফলে টেক্সট পড়া যায় না।
  • ঐচ্ছিক: পৃষ্ঠা-ব্যাপী ডার্ক মোডের মতো একই রঙের জোড়া আবার ব্যবহার করা সহজ হলেও, আমরা এই কম্পোনেন্টগুলির জন্য বিভিন্ন রঙের জোড়া নির্ধারণ করতে পারি। যেমন, আমরা চাইতে পারি যে লাইট মোড পৃষ্ঠায় ব্যবহৃত ডার্ক মোড কম্পোনেন্টটি যেন ডার্ক মোড পৃষ্ঠায় ব্যবহৃত একই ডার্ক মোড কম্পোনেন্টের চেয়ে একটু কম ডার্ক হয়।

পরিচিত সমস্যা সম্পর্কে সচেতন থাকুন

গুরুত্বপূর্ণ বিষয়: light-dark() রঙের ইনহেরিটেন্স

light-dark() কম্পিউটেড ভ্যালু টাইমে সমাধান করে। এর অর্থ হল, light-dark() রঙে সেট করা যেকোনও ইনহেরিট করা <color> প্রপার্টি, তার ডিসেন্ডেন্টকে দুটি রঙের মধ্যে শুধুমাত্র একটি রঙ পাস করবে, light-dark() এক্সপ্রেশনটি নিজে নয়।

এর মধ্যে রয়েছে:

  • বিল্ট-ইন রঙের প্রপার্টি যা ইনহেরিট করে, যেমন color, accent-color, fill, stroke, text-shadow, caret-color
  • syntax: <color> এবং inherits: true-এর সাথে রেজিস্টার করা যেকোনও উত্তরাধিকার সূত্রে প্রাপ্ত কাস্টম প্রপার্টি
  • অন্য যেকোনও <color> প্রপার্টি inherit-এ সেট করা হয়েছে

এর অর্থ হল, আপনাকে এগুলি করতে হবে:

  • <color> হিসেবে ডিজাইন টোকেন (যেমন, --surface-color) ধরে রাখার জন্য কাস্টম প্রপার্টি রেজিস্টার করবেন না। টোকেনকে তার light-dark() এক্সপ্রেশন লাইভ রাখতে হবে যাতে ডিসেন্ডেন্টরা অন্য color-scheme-এর অধীনে সেগুলি আবার সমাধান করতে পারে।
  • কোনও এলিমেন্টে color-scheme সেট করার সময়, উত্তরাধিকার সূত্রে প্রাপ্ত যেকোনও <color> প্রপার্টি আবার নির্দিষ্ট করুন যা হয়ত light-dark() মানে (সরাসরি বা ডিজাইন টোকেনের মাধ্যমে) সেট করা হয়েছে, এমনকি সেটি একই ডিজাইন টোকেনের ক্ষেত্রে হলেও।
  • color-scheme ওভাররাইড সহ এলিমেন্টের <color> প্রপার্টিতে inherit ব্যবহার করবেন না (তাদের ডিসেন্ডেন্টে ব্যবহার করা যেতে পারে)।
  • বিপরীত ব্যবহারের ক্ষেত্রে রেজিস্টার করা <color> প্রপার্টি ব্যবহার করুন: যখন আপনি ইচ্ছাকৃতভাবে পূর্বপুরুষের সমাধান করা রঙের স্ন্যাপশট নিতে চান এবং বংশধরের color-scheme-এর অধীনে এটিকে আবার সমাধান করা থেকে আটকাতে চান। যেমন, অন্য কোথাও ব্যবহার করার জন্য পৃষ্ঠার ব্যাকগ্রাউন্ড ক্যাপচার করা।
  • আপনাকে কোনও রঙ অ্যানিমেট করতে হলে, যে এলিমেন্ট অ্যানিমেট করা হচ্ছে সেটিতে আলাদা @property-রেজিস্টার করা <color> প্রপার্টি ব্যবহার করুন (কালার ইন্টারপোলেশনের জন্য রেজিস্ট্রেশন প্রয়োজন) — এটি কোনও ডিজাইন টোকেন নয়, বরং প্রতিটি এলিমেন্টের অ্যানিমেশন টার্গেট, তাই এটি উপরের নিয়মের সাথে বিরোধ করে না।

উদাহরণ:

:root {
    --accent-color: light-dark(blue, skyblue);
    --surface-color: light-dark(white, #222);
    --text-color: light-dark(#111, white);

    color-scheme: light dark;
    accent-color: var(--accent-color);
    color: var(--text-color);
}

body {
    /* --surface-color dynamically switches despite being inherited because --surface-color is not registered */
    background: var(--surface-color);
}

pre, code {
    color-scheme: dark;
    background: var(--surface-color);

    /* Without this, accent-color would be blue, not skyblue! */
    accent-color: var(--accent-color);

    /* Without this, text-color would be #111, not white! */
    color: var(--text-color);
}

কালার-স্কিম ব্যবহার করার সময় যেসব সমস্যা সম্পর্কে সচেতন থাকতে হবে

  • Chrome ও Firefox, iframe-এর জন্য color-scheme মেনে চলে: এগুলি সঠিক কালার স্কিমে এম্বেড করা পৃষ্ঠা রেন্ডার করে এবং এম্বেড করা পৃষ্ঠার prefers-color-scheme মিডিয়া কোয়েরি অ্যাডজাস্ট করে যাতে এম্বেডিং কনটেক্সটের color-scheme প্রতিফলিত হয়। Safari তা করে না এবং iframe-এর মধ্যেও সিস্টেম সেটিংসে prefers-color-scheme সমাধান করে।
    • আপনি যদি পেরেন্ট ও iframe, দুটিই কন্ট্রোল করেন: পেরেন্টের রঙের স্কিম iframe-এ স্পষ্টভাবে পাস করুন — iframe তৈরি করার সময় URL প্যারামিটার (?theme=dark) বা postMessage()-এর মাধ্যমে (যা আপনাকে রানটাইম পরিবর্তনগুলিতে প্রতিক্রিয়া জানাতে দেয়)। iframe-এ, prefers-color-scheme-এর উপর নির্ভর না করে সেই সিগন্যাল থেকে <html>-এ (এবং/অথবা :root-এ color-scheme) একটি ক্লাস সেট করুন।
    • আপনি যদি শুধুমাত্র এম্বেড করা পৃষ্ঠাটি নিয়ন্ত্রণ করেন: Safari-তে iframe-এর ভিতর থেকে এম্বেডিং কন্টেক্সটের color-scheme শনাক্ত করার কোনও নির্ভরযোগ্য উপায় নেই। আপনার এম্বেড API-তে (যেমন, কোয়েরি স্ট্রিং বা postMessage প্রোটোকল) একটি এক্সপ্লিসিট থিম প্যারামিটার দেখান এবং এম্বেডারদের জন্য এটি ডকুমেন্ট করুন।

ফলব্যাক স্ট্র্যাটেজি

রঙের স্কিমের জন্য ফলব্যাক ও ব্রাউজার সহায়তা

color-scheme প্রপার্টি হল প্রোগ্রেসিভ এনহ্যান্সমেন্ট। যেসব ব্রাউজারে এটি কাজ করে না, সেগুলি এই প্রপার্টি উপেক্ষা করবে এবং তাদের ডিফল্ট লাইট-মোড UI ব্যবহার করবে।

পুরনো ব্রাউজারে ব্যবহারকারীর পছন্দ অনুযায়ী অ্যাডাপ্ট করতে, ডার্ক মোড পছন্দ করা হলে বিভিন্ন রঙ প্রদান করতে prefers-color-scheme মিডিয়া কোয়েরি ব্যবহার করুন।

  • :root বা html-এ কাস্টম প্রপার্টি চালু করতে মিডিয়া কোয়েরি ব্যবহার করুন
  • কোনও কম্পোনেন্টে রঙ ছাড়া অন্য কোনও নির্দিষ্ট ধরনের ডার্ক মোড কাস্টমাইজেশনের প্রয়োজন না হলে, আলাদা আলাদা কম্পোনেন্টে মিডিয়া কোয়েরি ব্যবহার করা এড়িয়ে চলুন।
:root {
  /* Define brand colors for each mode */
  --color-brand-light: #0056b3;
  --color-brand-dark: #00e5ff;
  --color-brand: var(--color-brand-light);

  /* MANDATORY: Fallback for browsers without light-dark support */
  @media (prefers-color-scheme: dark) {
    --color-brand: var(--color-brand-dark);
  }

  /* Ignored in older browsers */
  color-scheme: light dark;
}

button.primary {
    background-color: var(--color-brand);
}

light-dark()-এর জন্য ফলব্যাক ও ব্রাউজার সাপোর্ট

যেসব ব্রাউজার color-scheme সাপোর্ট করে কিন্তু এখনও light-dark() সাপোর্ট করে না, সেগুলির ক্ষেত্রে রঙের লাইট ও ডার্ক ভার্সন প্রথমে কাস্টম প্রপার্টি হিসেবে সংজ্ঞায়িত করতে হবে এবং নিচের উদাহরণের মতো সংশ্লিষ্ট মোডের জন্য রঙ সেট করতে prefers-color-scheme মিডিয়া কোয়েরি ব্যবহার করতে হবে:

:root {
  /* Define browser UI accent color for each mode */
  --brand-accent-light: #0056b3;
  --brand-accent-dark: #00e5ff;
  --accent-color: var(--brand-accent-light);

  /* MANDATORY: Fallback for browsers without light-dark support */
  @media (prefers-color-scheme: dark) {
    --accent-color: var(--brand-accent-dark);
  }

  /* OPTIONAL: use light-dark() for more control of built-in UI colors */
  @supports (color: light-dark(white, black)) {
    --accent-color: light-dark(var(--brand-accent-light), var(--brand-accent-dark));
  }

  /* MANDATORY: Automatically adapt native UI to user system preferences */
  color-scheme: light dark;

  /* Example inherited color property */
  accent-color: var(--accent-color);
}

pre, code {
  color-scheme: dark;

  /* **Mandatory**: any inherited color properties must be set again, even if to the same design tokens */
  accent-color: var(--accent-color);
}