ডার্ক মোড টগল

ডার্ক মোড টগল ব্যবহারকারীদের একটি সাইটের জন্য সিস্টেম কালার স্কিম ওভাররাইড করতে দেয়। <meta name="color-scheme"> আপডেট করার মাধ্যমে ওভাররাইড প্রয়োগ করা হয়: light dark মানে "সিস্টেম প্রেফারেন্স ফলো করুন", light বা dark একটি এক্সপ্লিসিট স্কিম পিন করুন। রঙ (light-dark()), সিস্টেমের রঙ এবং নেটিভ UI-এর সব কী CSS color-scheme প্রপার্টি বন্ধ করে দেয়, তাই টগল সেই প্রপার্টিকে <meta>-এর সাথে সিঙ্ক করে কাজ করে (CSS-এ ওভাররাইড প্রতিফলিত করুন দেখুন)।

পারসিস্টেন্ট টগল, সেটিংস কন্ট্রোল নাকি কোনও টগলই নয়?

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

OS-এর বিপরীতে কোনও স্কিম পিন করা একটি বৈধ কিন্তু বিরল উদ্দেশ্য এবং বিরল উদ্দেশ্যগুলি প্রগ্রেসিভ ডিসক্লোজারের পিছনে থাকে, এমন কোনও কন্ট্রোলে নয় যা সব সময় দেখা যায়।

পারসিস্টেন্ট টগল বেশিরভাগ ক্ষেত্রে ডেভেলপার-ফেসিং বা ডেভেলপার-অ্যাডজাসেন্ট (যেমন, ডিজাইনারদের জন্য) সাইটে দেখা যায়, যেখানে স্কিম পরিবর্তন করার কাজটি সাধারণ ওয়েব ব্যবহারকারীর তুলনায় অনেক বেশি ঘন ঘন করতে হয়। ডেভেলপার সাইটে এটি একটি সাধারণ প্যাটার্ন বলে এটি যোগ করবেন না: এই কন্ট্রোলে ডেভেলপারের আগ্রহ সাধারণ ব্যবহারকারীদের প্রতিনিধিত্ব করে না।

প্রয়োগ

প্রথমে, সিস্টেম প্রেফারেন্সকে ডিফল্ট হিসেবে সেট করে দুটি স্কিমই যাতে কাজ করে তার জন্য ডার্ক মোড-এর সব ধাপ অনুসরণ করুন।

ডেটা মডেল

ডার্ক মোড টগলের ডেটা মডেলে সাধারণত তিনটি অবস্থা থাকে:

  1. সিস্টেম (কোনও স্টোর করা ভ্যালু নেই): UI সিস্টেমের রঙের স্কিম ফলো করে। এটি ডিফল্ট হিসেবে সেট করা থাকলে ভালো হয়।
  2. লাইট ("light" হিসেবে সেভ করা): সিস্টেমের রঙের স্কিম যাই হোক না কেন, UI-তে লাইট থিম ব্যবহার করা হয়।
  3. ডার্ক ("dark" হিসেবে সেভ করা): সিস্টেমের রঙের স্কিম যাই হোক না কেন, UI ডার্ক থিম ব্যবহার করে।

এই স্টেট সাধারণত localStorage-এ স্টোর করা হয় এবং ডকুমেন্টের হেডে <meta name="color-scheme"> এলিমেন্টে দেখানো হয়।

CSS-এ ওভাররাইড দেখান

<meta> হল শুধুমাত্র একটি প্রেজেন্টেশনাল ইঙ্গিত: লেখক CSS-এ যেকোনও color-scheme ঘোষণা এটিকে ওভাররাইড করে। যেহেতু ডার্ক মোড :root-এ color-scheme: light dark সেট করে, তাই শুধু <meta> আপডেট করা হল নো-অপ — CSS-এর জয়। <meta>-কে প্রপার্টিতে আবার ম্যাপ করুন যাতে ক্যাসকেড এটি অনুসরণ করে:

:root {
  color-scheme: light dark;

  &:has(> head > meta[name="color-scheme"][content="dark"]) {
    color-scheme: dark;
  }
  &:has(> head > meta[name="color-scheme"][content="light"]) {
    color-scheme: light;
  }
}

রুট ডিফল্ট হিসেবে color-scheme: light বা color-scheme: dark হার্ডকোড করবেন না; মূল ঘোষণা অবশ্যই light dark থাকতে হবে। CSS-কে JS-এর উপর নির্ভর করলে চলবে না: JS কখনও রান না করলে, <meta> light dark থেকে যায় এবং সাইট সিস্টেম প্রেফারেন্স অনুসরণ করে — কোনও কিছু ভেঙে যায় না।

পারসিস্টেন্স ও FOUC প্রতিরোধ

localStorage-এ ওভাররাইড বজায় রাখুন; সিস্টেম ডিফল্টে ফিরে যাওয়ার সময় এন্ট্রি সরিয়ে দিন।

ভুল স্কিম যাতে ফ্ল্যাশ না করে, তার জন্য <meta> এলিমেন্টের ঠিক পরে ইনলাইন স্ক্রিপ্টে (type=module নয়, defer নয়) সেভ করা ভ্যালু প্রয়োগ করুন:

<meta name="color-scheme" content="light dark">
<script>
document.querySelector('meta[name="color-scheme"]').content = localStorage.getItem("color-scheme") ?? "light dark";
</script>
  • এই ইনলাইন স্ক্রিপ্ট শুধুমাত্র FOUC প্রতিরোধের জন্য আছে। এটি যতটা সম্ভব ছোট রাখুন; রঙের স্কিম টগল করার জন্য অতিরিক্ত JS পরে লোড করা যেতে পারে।
  • বিরল ক্ষেত্রে localStorage অ্যাক্সেস থ্রো করতে পারে (যেমন, সাইট ডেটা ব্লক করা), কিন্তু যেহেতু এই স্ক্রিপ্ট অন্য কিছু করে না, তাই একমাত্র পার্শ্বপ্রতিক্রিয়া হবে একটি কনসোল ত্রুটি। এটি গুরুত্বপূর্ণ হলে try .. catch-এ র‍্যাপ করুন। পৃষ্ঠায় থিম এখনও প্রয়োগ করা হয়েছে কিনা তা নিশ্চিত করুন, এমনকি এটি পারসিস্ট করা না গেলেও।
  • ওভাররাইড অন্য ট্যাব থেকে পরিবর্তন হতে পারে: সিঙ্ক করে রাখতে window-এর storage ইভেন্ট ম্যানেজ করুন।
  • সিস্টেম প্রেফারেন্স পরিবর্তন করে সেভ করা ভ্যালুর সাথে ম্যাচ করলে, সেভ করা ভ্যালু সরানোর জন্য matchMedia() ব্যবহার করবেন না। দিনের সময়ের উপর ভিত্তি করে অনেক ব্যবহারকারীর OS অটোমেটিক স্কিম পরিবর্তন করে; যখনই দুটি একসাথে ঘটবে তখনই সেভ করা ভ্যালু সরিয়ে দিলে, কোনও স্কিম পিন করা অসম্ভব হয়ে যাবে।

HTML এবং রঙ ছাড়া অন্যান্য ভ্যালুর জন্য ব্রাঞ্চিং

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

পৃষ্ঠাটি সিস্টেম প্রেফারেন্স অনুসরণ করলে, (prefers-color-scheme: dark) ব্রাঞ্চিংয়ের জন্য ব্যবহার করা যেতে পারে, যার মধ্যে <picture> বা <video> সোর্স অন্তর্ভুক্ত। রঙের স্কিম ওভাররাইড করলে অতিরিক্ত জটিলতা তৈরি হয়: সিস্টেম প্রেফারেন্স আর সোর্স অফ ট্রুথ থাকে না এবং যেসব API শুধুমাত্র মিডিয়া কোয়েরি গ্রহণ করে সেগুলির জন্য কোনও সরাসরি বিকল্প থাকে না।

ব্রাঞ্চিংয়ের জন্য .dark-এর মতো JS-প্রয়োগ করা ক্লাসের উপর সম্পূর্ণভাবে নির্ভর করবেন না, কারণ JS লোড না হলে এবং OS ডিফল্ট ডার্ক হলে সেগুলি ভুল হবে।

আপনি ব্রাঞ্চ করার জন্য :root:has(> head > meta[name="color-scheme"][content="dark"]) (বা light) সিলেক্টরের সাথে মিডিয়া কোয়েরি একত্রিত করতে পারবেন। এটি কীভাবে সুন্দরভাবে প্রয়োগ করবেন সেই সম্পর্কে বিস্তারিত জানতে সিলেক্টর ও @-রুল কম্বিনেশন দেখুন।

কন্ট্রোলের নিজস্ব বিকল্পগুলিও নন-কালার ব্রাঞ্চ: মার্কআপে দুটি অবস্থাই অন্তর্ভুক্ত করুন (আইকন এবং দৃশ্যত লুকানো অ্যাকশন টেক্সট, যেমন "ডার্ক থিমে পাল্টান") এবং এই সিলেক্টরগুলির মাধ্যমে নিষ্ক্রিয়টি লুকান। display: none AT থেকে অপ্রয়োজনীয় বিকল্পও সরিয়ে দেয়, যাতে সিস্টেম প্রেফারেন্স পরিবর্তন হলে কন্ট্রোল আপ-টু-ডেট রাখার জন্য কোনও JS-এর প্রয়োজন না হয়।

HTML-এর মধ্যে থাকা মিডিয়ার ক্ষেত্রে, বর্তমানে একমাত্র উপায় হল দুটি ভার্সনকেই আলাদা এলিমেন্ট হিসেবে অন্তর্ভুক্ত করা এবং সেই অনুযায়ী দৃশ্যমানতা টগল করা। display: none-এর মাধ্যমে <source> এলিমেন্ট লুকানো কাজ করে না।

ইউজার ইন্টারফেস

দুই বা তিনটি রাজ্য?

সব ক্ষেত্রেই, UI-তে সিস্টেমের রঙের স্কিম ফিরিয়ে আনা বা সেট করার সুবিধা থাকতে হবে।

স্পেস-কনস্ট্রেইন্ড টগলে দুটি স্ট্যাটাস দেখানো ভালো, যেমন সাইট ক্রোমে (হেডার, নেভিগেশন, ফুটার ইত্যাদি) পারসিস্টেন্ট টগল যেখানে স্পেস সীমিত এবং সেটিংস পরিবর্তন করা সাধারণত ব্যবহারকারীর লক্ষ্যের সাথে সম্পর্কিত নয়।

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

সাইট যদি প্রসঙ্গ-সচেতন স্কিম (যেমন, OS ডার্ক মোডে থাকলে ডিমার লাইট মোড) প্রয়োগ করে, তাহলে তিনটি স্পষ্ট স্টেটও নিশ্চিত করা হয়, কারণ "লাইট" এবং "সিস্টেম (বর্তমানে লাইট)" তখন সত্যিই আলাদা হয়।

টু-স্টেট টগল

এই ধরনের কন্ট্রোল ব্যবহার করা হলে, এটি দীর্ঘমেয়াদী ভিত্তিতে বর্তমান স্ট্যাটাস বজায় রাখার পরিবর্তে সাময়িকভাবে আরামদায়ক অ্যাডজাস্টমেন্ট ("এখন খুব উজ্জ্বল") করার প্রবণতা দেখায়। তাই, দুই-স্টেট টগলের জন্য, তিনটি সেটিংসের মধ্যে দুটি দেখানোই যথেষ্ট: সিস্টেম (যাতে সেটিংটি আগের অবস্থায় ফিরিয়ে আনা যায়) এবং সিস্টেমের বর্তমান বিপরীত, যা এর বর্তমান আক্ষরিক মান হিসেবে স্টোর করা হয়।

শুধুমাত্র দুটি স্ট্যাটাস থাকতে হবে:

  1. সিস্টেম ডিফল্ট — কোনও স্টোর করা ভ্যালু নেই, <meta> কন্টেন্ট light dark। এটি বর্তমান সমাধান করা ভ্যালু হিসেবে দেখানো হয় (যেমন, আলো থাকলে সূর্যের আইকন)।
  2. ওভাররাইড — আক্ষরিকভাবে light বা dark হিসেবে স্টোর করা হয়।

মূলত, এটি একটি ত্রি-স্টেট কন্ট্রোল (light dark, light, dark) যেখানে বর্তমান সিস্টেম প্রেফারেন্সের সাথে ম্যাচ করা এক্সপ্লিসিট স্টেট অ্যাক্সেস করা যায় না।

ব্যবহারকারী টগল করলে:

  1. টার্গেট স্কিম = বর্তমানে রেন্ডার করা স্কিমের বিপরীত (সেভ করা ভ্যালু থাকলে, অন্যথায় সিস্টেম প্রেফারেন্স)। ব্যবহারকারীর উদ্দেশ্য হল "আমি এখন যা দেখছি তার বিপরীতটি বেছে নেওয়া", "সিস্টেম ডিফল্টের বিপরীতটি বেছে নেওয়া" নয়।
  2. If the target differs from the current system preference, store it literally.
  3. টার্গেট যদি বর্তমান সিস্টেম প্রেফারেন্সের সাথে মিলে যায়, তাহলে ব্যবহারকারী তার অ্যাডজাস্টমেন্ট আগের অবস্থায় ফিরিয়ে আনছেন: স্টোর করা ভ্যালু সরিয়ে দিন। এটি সেভ করবেন না — এটি করলে ভবিষ্যতের সিস্টেম পরিবর্তনের ক্ষেত্রে স্কিমটি অদৃশ্যভাবে পিন হয়ে যাবে।
  4. <meta> কন্টেন্টকে সেভ করা ভ্যালুতে সেট করুন অথবা কিছু না থাকলে light dark-এ সেট করুন।

গুরুত্বপূর্ণ: ডাইভারজেন্স শুধুমাত্র স্টোরেজের সময় চেক করতে হবে, কখনও রেট্রোঅ্যাক্টিভভাবে নয়: সিস্টেম প্রেফারেন্স পরে ম্যাচ করার জন্য পরিবর্তন করে এমন স্টোর করা ভ্যালু অবশ্যই রাখতে হবে। দিনের সময়ের উপর ভিত্তি করে অনেক ব্যবহারকারীর OS অটোমেটিক স্কিম পরিবর্তন করে; যখনই দুটি একসাথে ঘটবে তখনই সেভ করা ভ্যালু সরিয়ে দিলে, কোনও স্কিম পিন করা অসম্ভব হয়ে যাবে।

পরিস্থিতির উদাহরণ, OS-এর থিম লাইট হিসেবে সেট করা আছে:

  1. ব্যবহারকারী টগল করেন। ডার্ক মোড সিস্টেম প্রেফারেন্সের থেকে আলাদা, তাই dark স্টোর করা হয়; সাইট ডার্ক মোডে পরিবর্তিত হয়।
  2. OS সেটিং পরিবর্তন হয়ে ডার্ক হয়ে যায়। সাইটটি ডার্ক থাকে (সেভ করা ভ্যালু এখন সিস্টেম প্রেফারেন্সের সাথে মেলে, তবে তা রাখা হয়)।
  3. OS সেটিং পরিবর্তন হয়ে আবার লাইট হয়ে যায়। সাইটটি ডার্ক মোডে থাকে।
  4. ব্যবহারকারী টগল করেন। টার্গেট (লাইট) সিস্টেম প্রেফারেন্সের সাথে মিলে যায়, তাই সেভ করা ভ্যালু সরিয়ে দেওয়া হয় এবং সাইট আবার সিস্টেম ফলো করে।

তিনটি স্ট্যাটাস টগল

যখন আরও স্পেস থাকে এবং ব্যবহারকারীরা আগে থেকেই দীর্ঘমেয়াদী পছন্দ সেট করার মানসিকতায় থাকেন, তখন ট্রাই-স্টেট কন্ট্রোল আরও স্পষ্টতা প্রদান করতে পারে। এই ক্ষেত্রে, ডেটা মডেল তিনটি UI বিকল্পে পরিষ্কারভাবে ম্যাপ করে: সিস্টেম, লাইট এবং ডার্ক।

কগনিটিভ লোড কমাতে, "সিস্টেম" বিকল্পে বর্তমান সিস্টেম সেটিং কী তাও দেখানো উচিত, যেমন:

  • আইকন, যেমন সিস্টেম আইকনের নিচে ডানদিকে সূর্যের আইকন
  • টেক্সট, যেমন "সিস্টেম (বর্তমানে লাইট)"