עיצוב נושאי דינמי ללא CSS-in-JS

פעם הייתי מעריץ מושבע של styled-components. אהבתי את הגמישות. ואז נתקלתי בקיר.

פרויקט אחד היה צריך להפחית את משקל ה-runtime. החלטתי לנסות CSS Modules ו-CSS טבעי. התוצאה הפתיעה אותי. מחקתי את styled-components, Emotion ו-goober מהפרויקטים שלי. לא איבדתי שום דבר שהייתי באמת צריך.

הרווח הגדול ביותר לא היה רק בביצועים. זה היה הסרת התלות בעיצוב (styling). בפרויקט אחד, ה-runtime של CSS-in-JS תפס 30% מה-client bundle.

CSS רגיל התבגר. אתם כבר לא צריכים ספריות JS כבדות למשימות האלו:

• Nesting: השתמשו בקינון CSS טבעי. • Color shifts: השתמשו ב-color-mix(). • Specificity control: השתמשו ב-@layer. • Responsive components: השתמשו ב-container queries.

כך בונים theme באמצעות קובץ אחד בלבד ומשתנים מותאמים אישית (custom properties).

  1. הגדירו tokens בקובץ 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. החליפו ערכות נושא על ידי שינוי attribute בודד.
function setTheme(theme) {
  document.documentElement.dataset.theme = theme;
  localStorage.setItem("theme", theme);
}

רכיבים לא זקוקים ל-ThemeProvider. הם לא צריכים לבצע re-render. הדפדפן מטפל בעדכון דרך ה-cascade. זה מאפשר להשאיר את רוב האפליקציה שלכם ב-Server Components.

כדי למנוע "הבהוב" (flash) של ערכת הנושא הלא נכונה בעת טעינת הדף, השתמשו בסקריפט inline קטן בתוך ה-head של ה-HTML שלכם:

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

הפסיקו להשתמש ב-JS כדי לייצר עיצובים בזמן ריצה (runtime). השתמשו במשתני CSS טבעיים עבור ה-tokens שלכם. זה מביא לקוד פחות וזמני טעינה מהירים יותר.

מקור: https://dev.to/kirill_c_7b35589230/dynamic-theming-without-css-in-js-d7e