آکادمی بنو/آموزش CSS

متغیرها و توابع CSS

بهنام نوبخت · ۱۴۰۵/۶/۲۸

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

CSS برای حل چنین مشکلاتی قابلیتی به نام Custom Properties یا CSS Variables دارد. با استفاده از این قابلیت می‌توانیم یک مقدار را در یک محل تعریف کنیم و سپس در قسمت‌های مختلف CSS از آن استفاده کنیم. علاوه بر متغیرها، CSS مجموعه‌ای از توابع مانند var()، calc()، min()، max() و clamp() دارد که امکان ساخت استایل‌های انعطاف‌پذیرتر و Responsive را فراهم می‌کنند.

در این مقاله ابتدا مفهوم متغیرهای CSS را یاد می‌گیریم و سپس با توابع مهم CSS آشنا می‌شویم و در پایان یک پروژه کوچک و کاربردی ایجاد خواهیم کرد.

متغیر CSS چیست؟

متغیر CSS یا Custom Property مقداری است که خودمان با یک نام مشخص تعریف می‌کنیم و می‌توانیم آن را در قسمت‌های مختلف CSS دوباره استفاده کنیم.

نام متغیرهای CSS باید با دو خط تیره -- شروع شود.

برای مثال:

:root {
    --primary-color: #ff6b00;
    --text-color: #222;
    --border-radius: 12px;
}

در این مثال سه متغیر ایجاد کرده‌ایم:

--primary-color
--text-color
--border-radius

هر کدام یک مقدار مشخص دارند.

سپس می‌توانیم از این متغیرها در قوانین CSS استفاده کنیم.

button {
    background-color: var(--primary-color);
    color: white;
    border-radius: var(--border-radius);
}

در اینجا به جای نوشتن مستقیم مقدار رنگ و شعاع گوشه، از متغیرهایی که قبلاً تعریف کرده‌ایم استفاده شده است.

Custom Propertyها با -- تعریف می‌شوند و معمولاً با تابع var() مورد استفاده قرار می‌گیرند.

چرا باید از متغیرهای CSS استفاده کنیم؟

مهم‌ترین مزیت متغیرها، مدیریت ساده‌تر مقادیر تکراری است.

فرض کنید رنگ اصلی وب‌سایت شما این باشد:

#ff6b00

و این رنگ در بخش‌های مختلف استفاده شده باشد:

header {
    background-color: #ff6b00;
}

button {
    background-color: #ff6b00;
}

.title {
    color: #ff6b00;
}

.link {
    color: #ff6b00;
}

اگر تصمیم بگیرید رنگ اصلی را به رنگ دیگری تغییر دهید، باید چندین قسمت را تغییر دهید.

اما با متغیر CSS می‌توانیم مقدار را فقط یک بار تعریف کنیم:

:root {
    --primary-color: #ff6b00;
}

و سپس:

header {
    background-color: var(--primary-color);
}

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

.title {
    color: var(--primary-color);
}

.link {
    color: var(--primary-color);
}

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

:root {
    --primary-color: #7c3aed;
}

تمام قسمت‌هایی که از این متغیر استفاده می‌کنند، مقدار جدید را دریافت خواهند کرد.

تعریف متغیرهای CSS

برای تعریف یک Custom Property از ساختار زیر استفاده می‌کنیم:

selector {
    --variable-name: value;
}

مثلاً:

:root {
    --primary-color: #ff6b00;
    --secondary-color: #111827;
    --text-color: #333;
    --spacing: 20px;
}

نام متغیر می‌تواند شامل حروف، اعداد، خط تیره و سایر کاراکترهای مجاز باشد، اما باید با -- شروع شود.

برای مثال:

--main-color
--font-size-large
--card-radius
--space-small

استفاده از متغیر با var

برای استفاده از یک Custom Property از تابع var() استفاده می‌کنیم:

var(--variable-name)

مثلاً:

:root {
    --primary-color: #ff6b00;
}

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

می‌توانیم از یک متغیر در چندین ویژگی مختلف استفاده کنیم:

:root {
    --primary-color: #ff6b00;
}

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

a {
    color: var(--primary-color);
}

تابع var() مقدار Custom Property را در مقدار یک ویژگی CSS قرار می‌دهد.

استفاده از root: برای متغیرهای عمومی

اگر بخواهیم یک متغیر تقریباً در تمام صفحه قابل استفاده باشد، معمولاً آن را روی :root تعریف می‌کنیم.

:root {
    --primary-color: #ff6b00;
    --secondary-color: #111827;
    --text-color: #333;
    --background-color: #f5f5f5;
}

سپس:

body {
    background-color: var(--background-color);
    color: var(--text-color);
}

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

footer {
    background-color: var(--secondary-color);
}

این روش برای ساخت یک سیستم رنگ یا Design System ساده بسیار کاربردی است.

متغیرهای محلی

متغیرها الزاماً نباید در :root تعریف شوند.

می‌توانیم یک متغیر را فقط در یک عنصر یا یک بخش خاص تعریف کنیم:

.card {
    --card-color: #2563eb;
}

.card-title {
    color: var(--card-color);
}

در این حالت متغیر در محدوده .card و فرزندان آن قابل استفاده است.

مثلاً:

<div class="card">
    <h2 class="card-title">دوره طراحی وب</h2>
</div>
.card {
    --card-color: #2563eb;
}

.card-title {
    color: var(--card-color);
}

Custom Propertyهای معمولی CSS از عنصر والد به فرزندان به ارث می‌رسند و در Cascade نیز شرکت می‌کنند.

تغییر مقدار متغیر در یک بخش خاص

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

مثلاً:

:root {
    --primary-color: #ff6b00;
}

.card {
    color: var(--primary-color);
}

.card.special {
    --primary-color: #7c3aed;
}

حالا کارت عادی:

<div class="card">
    کارت معمولی
</div>

رنگ نارنجی خواهد داشت.

اما:

<div class="card special">
    کارت ویژه
</div>

رنگ بنفش خواهد داشت.

این قابلیت در ساخت کامپوننت‌های قابل تنظیم بسیار مفید است.

متغیرهای CSS و Inheritance

در مقاله قبل درباره Inheritance صحبت کردیم.

متغیرهای CSS نیز به‌صورت معمول از والد به فرزند منتقل می‌شوند.

برای مثال:

.parent {
    --box-color: blue;
}

.child {
    color: var(--box-color);
}

اگر HTML به شکل زیر باشد:

<div class="parent">
    <div class="child">
        متن
    </div>
</div>

عنصر .child می‌تواند مقدار --box-color را از والد دریافت کند.

این موضوع یکی از دلایلی است که متغیرهای CSS برای ساخت کامپوننت‌های قابل شخصی‌سازی بسیار مناسب هستند.

مقدار پیش‌فرض در var

گاهی ممکن است متغیری تعریف نشده باشد.

مثلاً:

.title {
    color: var(--title-color);
}

اگر --title-color وجود نداشته باشد، استفاده از آن ممکن است باعث نامعتبر شدن مقدار ویژگی شود.

می‌توانیم برای متغیر یک مقدار جایگزین یا Fallback تعریف کنیم:

.title {
    color: var(--title-color, black);
}

یعنی:

اگر --title-color وجود داشت، از آن استفاده کن؛ در غیر این صورت black را استفاده کن.

مثال:

button {
    background-color: var(--button-color, #ff6b00);
}

این قابلیت برای ساخت CSS مقاوم‌تر بسیار مفید است.

حتی می‌توانیم Fallback دیگری از نوع متغیر تعریف کنیم:

color: var(
    --primary-color,
    var(--fallback-color, black)
);

متغیرهای CSS به حروف بزرگ و کوچک حساس هستند

نام متغیرها Case-Sensitive است.

یعنی:

--main-color

با:

--Main-color

یکسان نیست.

برای جلوگیری از خطا بهتر است یک استاندارد نام‌گذاری مشخص داشته باشیم.

مثلاً:

--primary-color
--secondary-color
--text-color
--background-color
--border-color

ساخت یک سیستم طراحی ساده با متغیرها

می‌توانیم مجموعه‌ای از متغیرها را برای پروژه تعریف کنیم:

:root {
    --primary-color: #ff6b00;
    --secondary-color: #111827;
    --text-color: #1f2937;
    --muted-color: #6b7280;
    --background-color: #f9fafb;
    --white: #ffffff;

    --spacing-small: 8px;
    --spacing-medium: 16px;
    --spacing-large: 24px;

    --radius-small: 6px;
    --radius-medium: 12px;
    --radius-large: 20px;
}

حالا می‌توانیم از این مقادیر در تمام پروژه استفاده کنیم:

.card {
    background-color: var(--white);
    padding: var(--spacing-large);
    border-radius: var(--radius-medium);
}

.card-title {
    color: var(--secondary-color);
}

.card-description {
    color: var(--muted-color);
}

این روش باعث می‌شود CSS ما منظم‌تر و قابل نگهداری‌تر شود.

توابع CSS چیستند؟

در CSS فقط با مقادیر ثابت کار نمی‌کنیم.

CSS توابع مختلفی دارد که می‌توانند بر اساس شرایط، محاسبات یا ترکیب مقادیر، مقدار نهایی یک ویژگی را مشخص کنند.

برای مثال:

width: calc(100% - 40px);

در اینجا calc() یک تابع CSS است.

توابع دیگری نیز وجود دارند:

var()
calc()
min()
max()
clamp()

در ادامه مهم‌ترین آن‌ها را بررسی می‌کنیم.

تابع calc()

تابع calc() برای انجام محاسبات در CSS استفاده می‌شود.

مثلاً:

width: calc(100% - 40px);

یعنی عرض عنصر برابر باشد با:

100% - 40px

یکی از مزایای مهم calc() این است که می‌توانیم در یک محاسبه از واحدهای مختلف CSS استفاده کنیم.

مثلاً:

.container {
    width: calc(100% - 32px);
}

یا:

.main {
    min-height: calc(100vh - 80px);
}

مثال دوم بسیار کاربردی است.

فرض کنید ارتفاع Header برابر 80px باشد و بخواهیم بخش اصلی صفحه تمام فضای باقی‌مانده از ارتفاع صفحه را بگیرد:

main {
    min-height: calc(100vh - 80px);
}

ترکیب calc() با متغیرها

یکی از کاربردهای قدرتمند CSS زمانی است که calc() را با متغیرها ترکیب کنیم.

مثلاً:

:root {
    --page-padding: 24px;
}

.container {
    width: calc(100% - (2 * var(--page-padding)));
}

اگر مقدار متغیر تغییر کند:

:root {
    --page-padding: 32px;
}

محاسبه نیز به‌صورت خودکار تغییر خواهد کرد.

تابع min

تابع min() کوچک‌ترین مقدار بین چند مقدار را انتخاب می‌کند.

مثلاً:

.container {
    width: min(90%, 1200px);
}

یعنی عرض عنصر نمی‌تواند بیشتر از 1200px شود، اما در صفحات کوچک می‌تواند 90% عرض صفحه را بگیرد.

این الگو برای ساخت Containerهای Responsive بسیار کاربردی است.

مثلاً:

.container {
    width: min(90%, 1200px);
    margin-inline: auto;
}

در یک صفحه بزرگ، عرض Container حداکثر 1200px خواهد بود و در صفحه‌های کوچک‌تر می‌تواند درصدی از عرض صفحه را اشغال کند.

تابع max

تابع max() برعکس min() عمل می‌کند و بزرگ‌ترین مقدار را انتخاب می‌کند.

مثلاً:

.container {
    padding-inline: max(20px, 5vw);
}

در اینجا Padding حداقل 20px خواهد بود، اما اگر 5vw مقدار بیشتری ایجاد کند، همان مقدار استفاده می‌شود.

تابع clamp

تابع clamp() یکی از کاربردی‌ترین توابع CSS مدرن برای طراحی Responsive است.

ساختار آن:

clamp(min, preferred, max)

یعنی:

حداقل مقدار
مقدار ترجیحی
حداکثر مقدار

مثلاً:

h1 {
    font-size: clamp(2rem, 5vw, 4rem);
}

در این مثال:

  • اندازه فونت کمتر از 2rem نمی‌شود.

  • مقدار ترجیحی 5vw است.

  • اندازه فونت بیشتر از 4rem نمی‌شود.

بنابراین اندازه فونت می‌تواند با عرض صفحه تغییر کند، اما از محدوده تعیین‌شده خارج نمی‌شود. clamp() دقیقاً برای محدود کردن یک مقدار بین حداقل و حداکثر طراحی شده است.

یک مثال ساده از clamp

.title {
    font-size: clamp(24px, 5vw, 64px);
}

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

با بزرگ‌تر شدن صفحه، مقدار فونت نیز افزایش پیدا می‌کند.

اما در نهایت از 64px بیشتر نمی‌شود.

این روش برای طراحی Responsive بسیار کاربردی است.

تفاوت min، max و clamp

برای درک ساده:

min

می‌گوید:

از بین این مقادیر، کوچک‌ترین مقدار را انتخاب کن.

width: min(90%, 1200px);

max

می‌گوید:

از بین این مقادیر، بزرگ‌ترین مقدار را انتخاب کن.

padding: max(20px, 5vw);

clamp

می‌گوید:

مقدار را بین حداقل و حداکثر نگه دار.

font-size: clamp(24px, 5vw, 64px);

به زبان ساده:

min()   → سقف انتخاب می‌کند
max()   → کف انتخاب می‌کند
clamp() → هم کف دارد، هم سقف

ترکیب var و calc

حالا می‌توانیم قابلیت‌های مختلف CSS را با هم ترکیب کنیم.

مثلاً:

:root {
    --page-padding: 24px;
}

.container {
    width: calc(100% - (2 * var(--page-padding)));
}

یا:

:root {
    --base-size: 16px;
}

.title {
    font-size: calc(var(--base-size) * 2);
}

این روش به ما اجازه می‌دهد یک سیستم طراحی انعطاف‌پذیر ایجاد کنیم.

ترکیب متغیرها با clamp()

یکی از الگوهای بسیار کاربردی در طراحی Responsive:

:root {
    --title-size: clamp(2rem, 5vw, 4rem);
}

h1 {
    font-size: var(--title-size);
}

حالا اندازه عنوان در یک متغیر قرار گرفته است.

حتی می‌توانیم برای فاصله‌ها چنین کاری انجام دهیم:

:root {
    --section-padding: clamp(32px, 6vw, 100px);
}

section {
    padding-block: var(--section-padding);
}

در نتیجه فاصله بخش‌های صفحه نیز با اندازه صفحه به‌صورت روان تغییر می‌کند.

پروژه عملی: طراحی یک کارت دوره

حالا یک پروژه کوچک ایجاد کنیم.

هدف ما ساخت یک کارت دوره آموزشی است که از CSS Variables و توابع CSS استفاده کند.

HTML

<div class="course-card">
    <span class="course-badge">پیشنهاد ویژه</span>

    <h2>دوره آموزش طراحی وب</h2>

    <p>
        در این دوره با HTML، CSS و اصول طراحی Responsive
        آشنا می‌شوید.
    </p>

    <div class="course-footer">
        <span class="price">۱,۵۰۰,۰۰۰ تومان</span>
        <a href="#">مشاهده دوره</a>
    </div>
</div>

CSS

:root {
    --primary-color: #ff6b00;
    --primary-dark: #e85f00;

    --text-color: #1f2937;
    --muted-color: #6b7280;

    --background-color: #f5f7fa;
    --card-color: #ffffff;

    --spacing: 24px;
    --radius: 16px;

    --title-size: clamp(20px, 3vw, 30px);
}

* {
    box-sizing: border-box;
}

body {
    margin: 0;
    background-color: var(--background-color);
    font-family: sans-serif;
}

.course-card {
    width: min(90%, 500px);
    margin: 60px auto;

    padding: var(--spacing);

    background-color: var(--card-color);

    border-radius: var(--radius);

    box-shadow: 0 10px 30px rgb(0 0 0 / 10%);
}

.course-badge {
    display: inline-block;

    padding: 6px 12px;

    background-color: var(--primary-color);
    color: white;

    border-radius: 999px;

    font-size: 14px;
}

.course-card h2 {
    margin-top: 20px;

    color: var(--text-color);

    font-size: var(--title-size);
}

.course-card p {
    color: var(--muted-color);

    line-height: 1.8;
}

.course-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;

    gap: 16px;

    margin-top: 24px;
}

.price {
    color: var(--primary-color);
    font-weight: bold;
}

.course-footer a {
    padding: 10px 18px;

    background-color: var(--primary-color);
    color: white;

    text-decoration: none;

    border-radius: 10px;

    transition: background-color 0.2s;
}

.course-footer a:hover {
    background-color: var(--primary-dark);
}

در این پروژه چند مفهوم جدید را همزمان استفاده کردیم:

CSS Variables
var()
min()
clamp()
Flexbox
Responsive sizing

برای مثال:

width: min(90%, 500px);

باعث می‌شود عرض کارت از 500px بیشتر نشود.

و:

font-size: clamp(20px, 3vw, 30px);

باعث می‌شود اندازه عنوان بین 20px و 30px کنترل شود.

ساخت Theme با CSS Variables

یکی از کاربردهای بسیار جذاب متغیرها، ساخت Theme است.

مثلاً:

:root {
    --background: #ffffff;
    --text: #222222;
    --primary: #ff6b00;
}

حالا می‌توانیم Theme دیگری تعریف کنیم:

.dark {
    --background: #111827;
    --text: #ffffff;
    --primary: #fb923c;
}

سپس:

body {
    background-color: var(--background);
    color: var(--text);
}

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

این تکنیک پایه بسیاری از سیستم‌های Theme در رابط‌های کاربری مدرن است.

استفاده از متغیرها داخل Media Query

متغیرهای CSS را می‌توانیم در Media Query نیز تغییر دهیم.

مثلاً:

:root {
    --page-padding: 40px;
}

@media (max-width: 768px) {
    :root {
        --page-padding: 20px;
    }
}

سپس:

.container {
    padding-inline: var(--page-padding);
}

در صفحه‌های بزرگ:

40px

و در صفحه‌های کوچک:

20px

استفاده خواهد شد.

این روش باعث می‌شود به‌جای تغییر دادن چندین Rule مختلف، فقط مقدار متغیر را تغییر دهیم.

CSS Variable با متغیرهای Sass چه تفاوتی دارد؟

ممکن است در آینده با Sass و SCSS نیز روبه‌رو شوید.

مثلاً در Sass می‌توانیم بنویسیم:

$primary-color: orange;

اما این با CSS Custom Property یکی نیست.

CSS Variable مستقیماً توسط CSS و مرورگر مدیریت می‌شود:

--primary-color: orange;

و می‌توان مقدار آن را در زمان اجرای صفحه و بر اساس Context، Cascade و حالت عناصر تغییر داد.

در این مقاله تمرکز ما روی قابلیت داخلی خود CSS است و در این مرحله نیازی نیست وارد Sass شویم.

اشتباهات رایج در استفاده از متغیرهای CSS

اشتباه اول: فراموش کردن دو خط تیره

این اشتباه است:

primary-color: red;

متغیر CSS باید با -- شروع شود:

--primary-color: red;

اشتباه دوم: فراموش کردن var()

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

color: --primary-color;

باید بنویسیم:

color: var(--primary-color);

اشتباه سوم: استفاده از متغیر تعریف‌نشده

مثلاً:

color: var(--unknown-color);

اگر چنین متغیری در Scope مربوطه وجود نداشته باشد، مقدار ویژگی ممکن است نامعتبر شود.

در صورت نیاز می‌توانیم Fallback تعیین کنیم:

color: var(--unknown-color, black);

اشتباه چهارم: اشتباه گرفتن نام متغیرها

این دو متغیر متفاوت هستند:

--primary-color
--Primary-color

پس بهتر است در کل پروژه از یک استاندارد ثابت برای نام‌گذاری استفاده کنیم.

اشتباه پنجم: تعریف همه چیز در :root

استفاده از :root برای متغیرهای عمومی بسیار مناسب است، اما همه متغیرها الزاماً نباید در آنجا قرار بگیرند.

اگر یک مقدار فقط مربوط به یک کامپوننت است، بهتر است Scope آن را محدود کنیم:

.card {
    --card-padding: 20px;
}

این کار ساختار CSS را منطقی‌تر می‌کند.

تمرین‌های این مقاله

تمرین ۱

یک سیستم رنگ برای یک وب‌سایت ایجاد کنید:

:root {
    --primary-color: ...;
    --secondary-color: ...;
    --text-color: ...;
    --background-color: ...;
}

سپس از آن در body، دکمه‌ها و لینک‌ها استفاده کنید.

تمرین ۲

سه متغیر برای فاصله‌ها ایجاد کنید:

--spacing-small
--spacing-medium
--spacing-large

و از آن‌ها برای padding و margin استفاده کنید.

تمرین ۳

یک Container ایجاد کنید که:

  • حداکثر عرض آن 1200px باشد.

  • در صفحه‌های کوچک 90% عرض صفحه را بگیرد.

راهنمایی:

width: min(90%, 1200px);

تمرین ۴

اندازه عنوان را با clamp() کنترل کنید.

شرایط:

حداقل: 24px
مقدار ترجیحی: 5vw
حداکثر: 64px

تمرین ۵

یک متغیر برای فاصله اصلی صفحه تعریف کنید و در Media Query مقدار آن را تغییر دهید.

چالش عملی

یک کارت محصول طراحی کنید که شامل موارد زیر باشد:

نام محصول
توضیح محصول
قیمت
دکمه خرید

سپس حداقل از این موارد استفاده کنید:

3 CSS Variable
var()
calc()
min()
clamp()

سعی کنید بدون تغییر چندین Rule، فقط با تغییر چند متغیر، ظاهر کلی کارت را تغییر دهید.

جمع‌بندی

CSS فقط مجموعه‌ای از ویژگی‌های ثابت مانند color، width و padding نیست. با استفاده از Custom Properties می‌توانیم مقادیر مهم پروژه را به شکل قابل مدیریت تعریف کنیم و در قسمت‌های مختلف صفحه دوباره استفاده کنیم.

متغیرهایی مانند:

--primary-color
--text-color
--spacing
--radius

می‌توانند پایه یک سیستم طراحی منظم باشند.

از طرف دیگر، توابعی مانند:

var()
calc()
min()
max()
clamp()

امکان ساخت Layoutها و رابط‌های کاربری انعطاف‌پذیرتر را فراهم می‌کنند. به‌خصوص clamp() در طراحی Responsive و ایجاد اندازه‌های Fluid بسیار کاربردی است.

اگر این مفاهیم را به‌درستی یاد بگیرید، CSS شما از مجموعه‌ای از مقادیر پراکنده به یک ساختار منظم‌تر و قابل نگهداری تبدیل خواهد شد.

۰۰

نظرات

کد در دسترس نیست

هنوز نظری ثبت نشده است.