متغیرهای CSS؛ کلید انعطاف پذیری و طراحی مدرن

متغیرهای CSS؛ کلید انعطاف پذیری و طراحی مدرن

فهرست عناوین مهم پست
مشاهده بیشتر

فرض کنید سایتی با صدها صفحه دارید و مدیر بازاریابی تصمیم می گیرد رنگ برند شرکت را تغییر دهد. بدون متغیرهای CSS، باید به طور دستی هر کد رنگ را در ده ها یا حتی صدها فایل جستجو و جایگزین کنید. این فرآیند پرخطا، وقت گیر و غیرقابل تحمل است. اما با متغیرهای CSS، فقط یک خط کد را تغییر می دهید و تمام سایت در چند ثانیه به روز می شود.

متغیرهای CSS (که به آن ها Custom Properties یا خواص سفارشی هم می گویند) ابزاری انقلابی هستند که از سال 2017 در تمام مرورگرهای مدرن پشتیبانی می شوند. این ابزار به شما قدرت می دهد تا مقادیر تکراری را یک بار تعریف کنید و در سراسر پروژه استفاده کنید. در این مقاله از فاتحی اسکول، به صورت دقیق به این موضوع می پردازیم و تمام نکات پیشرفته را با مثال های ملموس بررسی می کنیم.

متغیرهای CSS چه هستند و چگونه کار می کنند

ساختار اصلی:

:root {
  --primary-color: #007bff;
  --spacing-unit: 16px;
  --border-radius: 8px;
}
Code language: CSS (css)

در این کد، دو خط تیره (--) ابتدای نام متغیر نشان می دهد این یک «خاصیت سفارشی» است. مرورگر این مقادیر را در حافظه نگه می دارد و هر جا که var(--primary-color) را ببیند، به طور خودکار آن را با #007bff جایگزین می کند.

مکانیزم var() در عمل

تابع var() کلید دسترسی به متغیرهاست. سه نکته حیاتی درباره آن باید بدانید:

  1. نام متغیر باید دقیقاً مطابقت داشته باشد--primary-color و --Primary-color دو چیز متفاوت هستند.
  2. مقادیر پشتیبان (fallback): می توانید مقدار دوم را به عنوان بک آپ اضافه کنید: var(--color, #000).
  3. تکه تکه کردن مقادیر: متغیرها می توانند قسمتی از یک مقدار باشند، مثلاً: var(--spacing-unit) auto.

مثال کاربردی:

button {
  background-color: var(--primary-color, #3498db);
  padding: calc(var(--spacing-unit) / 2) var(--spacing-unit);
  border-radius: var(--border-radius);
}
Code language: CSS (css)

اگر --primary-color تعریف نشده باشد، دکمه به جای آن از #3498db استفاده می کند. این پشتوانه سازی امنیت طراحی شما را تضمین می کند.

حوزه (Scope) و ارث بری—کلید قدرت متغیرها

حوزه سراسری (Global Scope) با :root

وقتی متغیرها را در :root تعریف می کنید، در دسترس تمام المان های صفحه قرار می گیرند. :root همان تگ <html> را هدف می گیرد، اما اولویت بالاتری دارد. این بهترین جا برای تعریف «طراحی توکن» (design tokens) مانند رنگ های برند، تایپوگرافی و فاصله هاست.

نمونه عملی:

:root {
  --color-primary: #2563eb;
  --color-secondary: #10b981;
  --font-sans: 'Inter', system-ui, sans-serif;
  --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
}
Code language: CSS (css)

حوزه محلی (Local Scope) برای انعطاف پذیری

می توانید متغیرها را در انتخابگرهای خاص تعریف کنید تا فقط در آن بخش کار کنند. این ویژگی برای کامپوننت های مستقل یا تم های موضعی بسیار ارزشمند است.

مثال کارت محصول:

.product-card {
  --card-bg: #ffffff;
  --card-border: #e5e7eb;
  background: var(--card-bg);
  border: 1px solid var(--card-border);
  padding: var(--spacing-unit);
}


/* تم تاریک برای کارت خاص */
.product-card.dark {
  --card-bg: #1f2937;
  --card-border: #374151;
}
Code language: CSS (css)

متغیرهای محلی از والدین ارث می برند. اگر --card-bg در .product-card.dark نباشد، مرورگر به .product-card نگاه می کند، اگر آنجا هم نباشد، به :root برمی گردد.

نحوه کار Cascade با متغیرها

سیستم Cascade (آبشاری) CSS روی متغیرها هم اعمال می شود. وقتی یک متغیر هم در :root و هم در یک کلاس محلی تعریف شود، مرورگر نزدیک ترین تعریف را به المان استفاده می کند.

مثال تم روشن/تاریک:

:root {
  --text-color: #000000; /* حالت پیش فرض روشن */
}


[data-theme="dark"] {
  --text-color: #ffffff; /* بازنویسی در حالت تاریک */
}


body {
  color: var(--text-color);
}
Code language: CSS (css)

همین مکانیزم ساده باعث می شود پیاده سازی دکمه تغییر تم بدون نیاز به CSS جدید ممکن شود.

مقادیر پشتیبان (Fallback Values)—بیمه طراحی شما

چرا fallback ها حیاتی هستند

متغیرها ممکن است به دلایلی وجود نداشته باشند: شاید مرورگر قدیمی است، شاید جاوااسکریپت بارگذاری نشده، یا شاید کد را اشتباه تایپ کرده اید. بدون fallback، استایل کلاً اعمال نمی شود و المان شما بی شکل می ماند.

ساختار صحیح fallback

روش اشتباه: var(--color, --backup-color, blue) ← این کار نمی کند.

روش صحیح (nested): var(--color, var(--backup-color, blue)) ← درست است.

مثال عملی:

.alert {
  background-color: var(--alert-bg, var(--info-bg, #eff6ff));
  border-left: 4px solid var(--alert-border, #3b82f6);
  padding: var(--spacing-unit);
}
Code language: CSS (css)

در این کد، اگر --alert-bg نبود، از --info-bg استفاده می شود، اگر آن هم نبود، به #eff6ff برمی گردد. این زنجیره پشتیبان اطمینان می دهد که هیچ وقت بدون استایل نمی مانید.

استفاده از @supports برای مرورگر های قدیمی

برای مرورگر هایی که CSS Variables را پشتیبانی نمی کنند (مثل IE)، از feature query استفاده کنید:

.button {
  background-color: #3498db; /* Fallback برای IE */
}


@supports (--css: variables) {
  .button {
    background-color: var(--primary-color, #3498db);
  }
}
Code language: CSS (css)

این روش تضمین می کند که در IE11 به جای متغیر، مستقیماً از #3498db استفاده شود.

به روزرسانی زنده با JavaScript

قدرت setProperty()

برخلاف پیش پردازنده ها (مثل Sass)، متغیرهای CSS در زمان اجرا (runtime) قابل تغییر هستند. این قابلیت را با setProperty() در اختیار می گیرد.

ساختار:

element.style.setProperty('--variable-name', 'new-value', 'optional-priority');
Code language: JavaScript (javascript)

مثال عملی: تغییر تم رنگی

HTML:

<button id="theme-toggle">تم را تغییر ده</button>
Code language: HTML, XML (xml)

CSS:

:root {
  --primary-color: #007bff;
}


body {
  background-color: var(--primary-color);
  transition: background-color 0.3s ease;
}
Code language: CSS (css)

JavaScript:

const button = document.getElementById('theme-toggle');
const root = document.documentElement;
let isDefault = true;


button.addEventListener('click', () => {
  const newColor = isDefault ? '#ff4500' : '#007bff';
  root.style.setProperty('--primary-color', newColor);
  isDefault = !isDefault;
});
Code language: JavaScript (javascript)

کلیک روی دکمه، رنگ پس زمینه را بدون نیاز به ریلود صفحه تغییر می دهد.

مقایسه عملکرد روش های JS

یک تست jsPerf نشان داد که:

  • Safari: element.style = "--color: green" سریع تر است
  • Firefox: setProperty() بسیار سریع تر است
  • Chrome: تفاوت چندانی ندارد

اما setProperty() در تمام مرورگرها پایدارتر و استاندارد است، پس استفاده از آن توصیه می شود.

استفاده در Vue.js برای رابط کاربری واکنش گرا

در Vue.js می توانید از watch برای به روزرسانی خودکار متغیرها استفاده کنید:

<script setup>
import { ref, watch } from 'vue'


const isDark = ref(false)


watch(isDark, (newValue) => {
  const root = document.documentElement
  const newBg = newValue ? '#1a1a1a' : '#ffffff'
  root.style.setProperty('--bg-color', newBg)
})
</script>
Code language: HTML, XML (xml)

هر تغییر در isDark بلافاصله تم سایت را به روز می کند.

پشتیبانی مرورگرها

تا آگوست 2025، CSS Variables در 98% مرورگرهای مدرن پشتیبانی می شوند. این یعنی می توانید بدون نگرانی از آن ها استفاده کنید.

جدول دقیق پشتیبانی:

  • Chrome: از نسخه 49+ (کامل)
  • Firefox: از نسخه 31+ (کامل)
  • Safari: از نسخه 10+ (کامل)، نسخه 9.1 (جزئی)
  • Edge: از نسخه 16+ (کامل)، نسخه 15 (جزئی)
  • IE: بدون پشتیبانی
  • Opera: از نسخه 36+ (کامل)

استراتژی های سازگاری

1. Fallback های دستی:

.button {
  background: #3498db; /* برای IE */
  background: var(--primary-color, #3498db); /* برای مدرن */
}
Code language: CSS (css)

2. استفاده از @supports:

@supports (--css: variables) {
  /* استایل های پیشرفته فقط برای مرورگرهای پشتیبانی کننده */
  .card {
    background: var(--surface-bg);
    box-shadow: var(--shadow-lg);
  }
}
Code language: CSS (css)

ملاحظات عملکرد—چه چیزی را باید بدانید

واقعیت عملکرد

متغیرهای CSS در زمان رندر محاسبه می شوند. این قدرت آن هاست، اما می تواند در صورت استفاده نادرست مشکل ساز شود.

تله های عملکردی

1. استفاده بیش از حد در انیمیشن ها:

/* ❌ BAD: این باعث بازمحاسبه در هر فریم می شود */
.animated {
  transition: all 0.3s;
  transform: var(--transform-value);
}
Code language: CSS (css)

2. تودرتوی بیش از حد:

/* ❌ BAD: زمان پردازش را افزایش می دهد */
.box {
  padding: var(--spacing, var(--base-spacing, 10px));
}
Code language: CSS (css)

3. تغییر متغیرهای سراسری در تکرارهای زیاد: هر بار که متغیر :root را با JS تغییر دهید، مروربر باید تمام المان هایی که از آن استفاده می کنند را دوباره استایل دهی کند.

بهترین شیوه ها برای عملکرد بهینه

✅ استفاده محتاط از calc():

:root {
  --spacing-unit: 16px;
  --spacing-lg: calc(var(--spacing-unit) * 2); /* فقط یک محاسبه */
}
Code language: CSS (css)

✅ محدود کردن انیمیشن ها به transform و opacity:

/* ✅ GOOD: این ها از GPU استفاده می کنند */
.smooth {
  transition: transform 0.3s, opacity 0.3s;
  transform: translateY(var(--offset, 0));
}
Code language: CSS (css)

✅ به روزرسانی دسته ای با requestAnimationFrame:

// ✅ GOOD: برای تغییرات مکرر
requestAnimationFrame(() => {
  root.style.setProperty('--x', x);
  root.style.setProperty('--y', y);
});
Code language: JavaScript (javascript)

تست های عملکرد نشان داده اند که استفاده صحیح از متغیرها تأثیر چشمگیری روی سرعت رندر ندارد و حتی می تواند با کاهش تکرار کد، بهبودی ایجاد کند.

پیاده سازی حالت تاریک (Dark Mode)

الگوی استاندارد

حالت تاریک محبوب ترین کاربرد متغیرهاست. مراحل ساده است:

مرحله 1: تعریف متغیرهای تم:

:root {
  --bg-color: #ffffff;
  --text-color: #000000;
  --card-bg: #f3f4f6;
}


[data-theme="dark"] {
  --bg-color: #1a1a1a;
  --text-color: #ffffff;
  --card-bg: #2d2d2d;
}
Code language: CSS (css)

مرحله 2: استفاده در استایل ها:

body {
  background-color: var(--bg-color);
  color: var(--text-color);
  transition: background-color 0.3s, color 0.3s;
}


.card {
  background-color: var(--card-bg);
  padding: var(--spacing-unit);
}
Code language: CSS (css)

مرحله 3: تغییر تم با JS:

const toggleDarkMode = () => {
  const isDark = document.documentElement.getAttribute('data-theme') === 'dark';
  const newTheme = isDark ? 'light' : 'dark';
  document.documentElement.setAttribute('data-theme', newTheme);
  localStorage.setItem('theme', newTheme); // ذخیره ترجیحات کاربر
};
Code language: JavaScript (javascript)

این روش حتی در Next.js با پکیج هایی مثل next-themes بهینه تر شده است.

استفاده از prefers-color-scheme

برای احترام به ترجیحات سیستمی کاربر:

@media (prefers-color-scheme: dark) {
  :root {
    --bg-color: #1a1a1a;
    --text-color: #ffffff;
  }
}
Code language: CSS (css)

اما توجه داشته باشید که این روزها بیشتر سایت ها دکمه دستی تم را ترجیح می دهند چون به کاربر کنترل بیشتری می دهد.

متغیرها در سیستم های طراحی (Design Systems)

ساختاردهی هوشمندانه

در پروژه های بزرگ، سازمان دهی متغیرها کلیدی است.

نمونه ساختار:

:root {
  /* رنگ ها */
  --color-primary: #3498db;
  --color-primary-light: #5dade2;
  --color-primary-dark: #2980b9;

  /* تایپوگرافی */
  --font-family-base: 'Inter', sans-serif;
  --font-size-xs: 0.75rem;
  --font-size-sm: 0.875rem;
  --font-size-base: 1rem;
  --font-size-lg: 1.125rem;
  --font-size-xl: 1.25rem;

  /* فاصله ها */
  --spacing-xs: 0.25rem;
  --spacing-sm: 0.5rem;
  --spacing-md: 1rem;
  --spacing-lg: 1.5rem;
  --spacing-xl: 2rem;

  /* سایه ها */
  --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
  --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
  --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
}
Code language: CSS (css)

نام گذاری معنایی (Semantic Naming)

نام متغیر را بر اساس کاربرد انتخاب کنید، نه مقدار:

✅ خوب:

--color-surface: #ffffff;
--color-text-primary: #000000;
Code language: CSS (css)

❌ بد:

--color-white: #ffffff;
--color-black: #000000;
Code language: CSS (css)

چرا؟ چون در تم تاریک، --color-white ممکن است سیاه شود و نام آن گمراه کننده می شود.

مستندسازی برای تیم

در پروژه های تیمی، حتماً متغیرها را در style guide مستند کنید:

/* 
 * Design Tokens
 * رنگ های اصلی برند—فقط اینجا تغییر کنید
 * --color-primary: برای دکمه های CTA و لینک ها
 * --color-secondary: برای تگ ها و برچسب ها
 */
:root {
  --color-primary: #2563eb;
  --color-secondary: #10b981;
}
Code language: CSS (css)

این کار از ایجاد متغیرهای تکراری جلوگیری می کند و هماهنگی تیم را حفظ می کند.

مقایسه با پیش پردازنده ها (Sass/Less)

تفاوت های بنیادین

ویژگیCSS VariablesSass/Less Variables
زمان ارزیابیزمان اجرا (runtime)زمان کامپایل
دسترسی JS✅ مستقیم با setProperty()❌ غیرممکن
ScopeCascading (CSS)Nested (Sass)
نیاز به build tool❌ ندارد✅ دارد
پشتیبانی مرورگرمدرن ها (98%)همه (پس از کامپایل)

چه زمانی از کدام استفاده کنید

استفاده از CSS Variables:

  • تم های داینامیک (Dark Mode)
  • سفارشی سازی کاربر
  • واکنش به رویدادهای زنده
  • پروژه هایی که build tool ندارند

استفاده از Sass Variables:

  • پروژه هایی که باید در IE11 کار کنند
  • محاسبات پیچیده ریاضی
  • توابع و لوپ های پیشرفته
  • کتابخانه هایی که قبل از 2017 ساخته شده اند

نکته مهم: می توانید از هر دو استفاده کنید! Sass variables برای محاسبات، و CSS Variables برای تم های داینامیک.

تله های رایج و راه های حل آن ها

تله 1: فراموش کردن حوزه (Scope)

مشکل:

.sidebar {
  --sidebar-width: 250px;
}


.main-content {
  width: var(--sidebar-width); /* ❌ کار نمی کند! */
}
Code language: CSS (css)

حل:

:root {
  --sidebar-width: 250px; /* ✅ در root تعریف کنید */
}
Code language: CSS (css)

تله 2: استفاده بیش از حد

مشکل: تعریف متغیر برای هر مقدار کوچک باعث پیچیدگی بی مورد می شود.

حل: فقط مقادیری را متغیر کنید که:

  • در چند جا تکرار می شوند
  • احتمال تغییر دارند
  • برای تم سازی مهم هستند

تله 3: عدم استفاده از fallback در محیط های بحرانی

مشکل:

button {
  background: var(--btn-bg); /* اگر این متغیر نباشد، دکمه شفاف می شود! */
}
Code language: CSS (css)

حل:

button {
  background: var(--btn-bg, #007bff); /* ✅ همیشه پشتیبان داشته باشید */
}
Code language: CSS (css)

تله 4: آپدیت های مکرر متغیرهای سراسری

مشکل: تغییر متغیر :root در یک loop باعث رندر مجدد سنگین می شود.

حل: از requestAnimationFrame یا محدود کردن تغییرات به المان های کوچک استفاده کنید.

چک لیست عملی برای پیاده سازی

قبل از شروع

  •  تمام مقادیر تکراری را لیست کنید
  •  تصمیم بگیرید کدام مقادیر باید قابل تغییر باشند
  •  ساختار پوشه ها و فایل های CSS را مشخص کنید

حین پیاده سازی

  •  متغیرها را فقط در :root یا انتخابگرهای والد تعریف کنید
  •  برای هر متغیر حیاتی، fallback مناسب اضافه کنید
  •  نام ها را معنایی و توصیفی بنویسید
  •  مستندسازی را در کامنت ها اضافه کنید

تست و بهینه سازی

  •  در Chrome DevTools قسمت، tab “CSS Overview” را بررسی کنید
  •  از Coverage استفاده کنید تا متغیرهای استفاده نشده را پیدا کنید
  •  در مرورگر های قدیمی (یا حالت IE11 در DevTools) تست کنید
  •  Performance tab را بررسی کنید تا رندر مجدد ناخواسته نداشته باشید

نگهداری

  •  هر فصل، متغیرهای اضافی را حذف کنید
  •  مقادیر را با طراح سیستم هماهنگ کنید
  •  تغییرات را در CHANGELOG مستند کنید

نتیجه گیری: تبدیل دانش به کاربرد عملی

متغیرهای CSS دیگر یک ویژگی اختیاری نیستند—آن ها پایه طراحی وب مدرن هستند. با این ابزار:

  • توسعه سریع تر می شود (کمتر تایپ می کنید)
  • نگهداری آسان تر می شود (یک جا تغییر می دهید)
  • انعطاف پذیری بیشتر دارید (تم داینامیک)
  • همکاری تیمی بهبود می یابد (مستندات واضح)

اما قدرت مسئولیت می آورد. استفاده بی رویه از متغیرها می تواند کد را پیچیده کند. همیشه از fallback استفاده کنید، حوزه را مدیریت کنید و عملکرد را تست کنید.

پیشنهاد من: همین امروز یک پروژه کوچک را باز کنید و سه متغیر برای رنگ های اصلی بسازید. آن ها را در کل پروژه جایگزین کنید و تجربه سهولت تغییر را لمس کنید. این اولین قدم به سمت یک سیستم طراحی مقیاس پذیر است.

در دنیایی که کاربران انتظار شخصی سازی و سرعت دارند، متغیرهای CSS کلید بقای شما در صنعت هستند. آن ها را جدی بگیرید و مهارت تسلط بر آن ها را در رزومتان درج کنید. آینده وب، آینده ای متغیر است.

علی فاتحی موسس فاتحی اسکول
Omid Moghadasi

امید مقدسی یک توسعه دهنده فول استک وب و مهندس DevOps است که تجربه گسترده ای در طراحی و پیاده سازی وب اپلیکیشن های سریع و مقیاس پذیر دارد. او در فرانت اند با React.js، Next.js، TypeScript و Vue.js کار کرده و در بک اند با Node.js، Nest.js، GraphQL، PHP و Python پروژه های موفقی را هدایت کرده است. همچنین در حوزه DevOps با لینوکس، Docker، CI/CD و Ansible تخصص دارد.


نظرات کاربران
ارسال دیدگاه