CSS-in-JS ছাড়াই ডাইনামিক থিমিং

আমি styled-components এর একজন বড় ভক্ত ছিলাম। এর নমনীয়তা (flexibility) আমার খুব পছন্দ ছিল। তারপর আমি একটি বাধার সম্মুখীন হলাম।

একটি প্রজেক্টের রানটাইম ওয়েট (runtime weight) কমানোর প্রয়োজন ছিল। আমি CSS Modules এবং native CSS ব্যবহার করার সিদ্ধান্ত নিলাম। ফলাফল আমাকে অবাক করে দিয়েছে। আমি আমার প্রজেক্ট থেকে styled-components, Emotion এবং goober মুছে ফেলেছি। আসলে আমার যা প্রয়োজন ছিল, তার কিছুই আমি হারাইনি।

সবচেয়ে বড় সাফল্য শুধু পারফরম্যান্সের ক্ষেত্রে ছিল না। এটি ছিল স্টাইলিং ডিপেন্ডেন্সি (styling dependency) দূর করা। একটি প্রজেক্টে, CSS-in-JS রানটাইম ক্লায়েন্ট বান্ডেলের (client bundle) ৩০% জায়গা দখল করে ছিল।

সাধারণ CSS এখন অনেক উন্নত হয়েছে। এই কাজগুলোর জন্য আপনার আর ভারী JS লাইব্রেরির প্রয়োজন নেই:

• Nesting: native CSS nesting ব্যবহার করুন। • Color shifts: color-mix() ব্যবহার করুন। • Specificity control: @layer ব্যবহার করুন। • Responsive components: container queries ব্যবহার করুন।

শুধুমাত্র একটি ফাইল এবং custom properties ব্যবহার করে কীভাবে একটি থিম তৈরি করবেন তা নিচে দেওয়া হলো।

  1. একটি CSS ফাইলে টোকেনগুলো ডিফাইন করুন।
:root {
  --color-bg: #ffffff;
  --color-text: #1a1a1a;
  --color-accent: #3c7dc4;
}

[data-theme="dark"] {
  --color-bg: #14161a;
  --color-text: #f5f5f0;
  --color-accent: #6aa6e8;
}
  1. আপনার কম্পোনেন্টগুলোতে সেই ভেরিয়েবলগুলো ব্যবহার করুন।
.button {
  background: var(--color-accent);
  color: var(--color-bg);
}
  1. একটি মাত্র অ্যাট্রিবিউট পরিবর্তন করে থিম পরিবর্তন করুন।
function setTheme(theme) {
  document.documentElement.dataset.theme = theme;
  localStorage.setItem("theme", theme);
}

কম্পোনেন্টগুলোর জন্য ThemeProvider-এর প্রয়োজন নেই। সেগুলোর re-render হওয়ারও প্রয়োজন নেই। ব্রাউজার ক্যাসকেডের (cascade) মাধ্যমে আপডেটটি হ্যান্ডেল করে। এটি আপনার অ্যাপের বেশিরভাগ অংশকে Server Components হিসেবে রাখতে সাহায্য করে।

পেজ লোড হওয়ার সময় ভুল থিমের "flash" এড়াতে, আপনার HTML head-এ একটি ছোট inline script ব্যবহার করুন:

<script>
  const t = localStorage.getItem("theme") || 
  (matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light");
  document.documentElement.dataset.theme = t;
</script>

রানটাইমে স্টাইল জেনারেট করতে JS ব্যবহার করা বন্ধ করুন। আপনার টোকেনগুলোর জন্য native CSS variables ব্যবহার করুন। এতে কোড কম হয় এবং লোড টাইম দ্রুত হয়।

উৎস: https://dev.to/kirill_c_7b35589230/dynamic-theming-without-css-in-js-d7e