CSS Custom Properties در React
15 دقیقه زمان برای خواندن این مطلب نیاز است.
فهرست مطالب
- CSS Custom Properties در React: راهنمای کامل تمسازی پویا و استایل داینامیک
- مقدمه: چرا CSS Custom Properties در React؟
- تفاوت CSS Custom Properties با متغیرهای Sass/SCSS
- اصول پایه: تعریف و استفاده از CSS Custom Properties در React
- مزایای استفاده از CSS Custom Properties در React نسبت به Context API و Redux برای استایل
- پیادهسازی یک سیستم تم پیشرفته با CSS Custom Properties در React
- تعامل با Props و State در React
- بهینهسازی عملکرد و جلوگیری از flickering
- رفع مشکل پشتیبانی مرورگرها
- ترکیب CSS Custom Properties با CSS Modules و Styled Components
- انیمیشنهای داینامیک با CSS Custom Properties در React
- عیبیابی خطاهای رایج در CSS Custom Properties در React
- نتیجهگیری نهایی
- سوالات متداول (FAQ)
CSS Custom Properties در React: راهنمای کامل تمسازی پویا و استایل داینامیک
در دنیای مدرن توسعه frontend، مدیریت استایلهای پویا و تمهای قابل تغییر یکی از چالشهای اساسی است. راهحلهای سنتی مانند Sass متغیرها یا CSS-in-JS هر کدام نقاط قوت و ضعفی دارند. اما یک فناوری بومی و فوقالعاده قدرتمند به نام CSS Custom Properties در React میتواند انقلابی در نحوه مدیریت استایلهای پویا ایجاد کند. CSS Custom Properties در React به معنای استفاده از متغیرهای بومی CSS (که با نام CSS Variables نیز شناخته میشوند) درون کامپوننتهای React است. این متغیرها امکان تعریف مقادیر (مانند رنگها، ابعاد، فونتها) را در سطح دامنه (global، component، یا حتی inline) فراهم کرده و سپس بهروزرسانی آنها را در زمان اجرا با جاوااسکریپت ممکن میسازند. در این مقاله جامع از داناپدیا، قصد داریم به طور کامل CSS Custom Properties در React را بررسی کنیم، از مفاهیم پایه و مزایا نسبت به روشهای سنتی گرفته تا پیادهسازی سیستم تم پیشرفته، بهینهسازی عملکرد، رفع مشکل پشتیبانی مرورگرها، ترکیب با CSS Modules و Styled Components، و ایجاد انیمیشنهای داینامیک. اگر به دنبال تسلط کامل بر هستید، این مقاله منبع نهایی شما خواهد بود.
مقدمه: چرا CSS Custom Properties در React؟
توسعهدهندگان React همواره با این سؤال مواجه بودهاند: چگونه میتوان استایلهایی ساخت که در پاسخ به تعاملات کاربر (مثل کلیک، هاور، یا تغییر تم) به صورت لحظهای تغییر کنند؟ راهحلهای متداول عبارتند از:
- استایلهای inline:
style={{ color: dynamicColor }}– ساده اما فاقد قابلیت استفاده مجدد و شبهکلاسها (مثل:hover). - CSS-in-JS (مانند styled-components): قدرتمند اما با حجم باندل اضافی و افت عملکرد در زمان اجرا.
- دستکاری کلاسهای CSS: تغییر کلاسها به صورت شرطی – که برای تغییرات کوچک (مثل یک رنگ) بسیار سنگین است.
CSS Custom Properties در React با ترکیب نقاط قوت CSS بومی و پویایی جاوااسکریپت، راهحلی ایدهال ارائه میدهد. شما یک متغیر CSS تعریف میکنید (مثلاً --primary-color: blue;)، سپس در جاوااسکریپت آن را تغییر میدهید: element.style.setProperty('--primary-color', 'red'). همه المانهایی که از آن متغیر استفاده میکنند، بلافاصله بهروزرسانی میشوند، بدون نیاز به رندر مجدد کامپوننت یا دستکاری DOM اضافی. در داناپدیا از این تکنیک برای پیادهسازی سیستم تم در داشبوردهای مدیریتی با بیش از ۵۰ کامپوننت استفاده کردهایم و نتایج شگفتانگیزی در کاهش پیچیدگی و افزایش سرعت کسب کردهایم.
تفاوت CSS Custom Properties با متغیرهای Sass/SCSS
بسیاری از توسعهدهندگان متغیرهای Sass را با CSS Custom Properties در React اشتباه میگیرند، اما تفاوت اساسی وجود دارد:
- متغیرهای Sass: در زمان کامپایل (build time) به مقادیر ثابت تبدیل میشوند. پس از خروجی گرفتن CSS، دیگر نمیتوان آنها را تغییر داد. برای مثال
$primary-color: blue;در Sass، پس از کامپایل بهcolor: blue;تبدیل میشود. - CSS Custom Properties: متغیرهایی در زمان اجرا (runtime) هستند. مرورگر آنها را به عنوان مقادیر زنده نگهداری میکند و جاوااسکریپت میتواند در هر لحظه آنها را بهروزرسانی کند.
این تفاوت کلیدی باعث میشود برای سناریوهایی مانند تمهای پویا (dark mode/light mode)، انیمیشنهای وابسته به اسکرول، شخصیسازی کاربر (مانند تغییر رنگ پسزمینه داشبورد) و کوئریهای مدیای پویا ایدهال باشد. در مقابل، متغیرهای Sass برای ثابتهای طراحی (مانند فونتهای اصلی، مقادیر breakpoint) مناسبتر هستند. در داناپدیا توصیه میکنیم از هر دو به صورت مکمل استفاده کنید: Sass برای ثابتهای طراحی، برای مقادیر پویا.
برنامه نویسی با هوش مصنوعی Claude

اصول پایه: تعریف و استفاده از CSS Custom Properties در React
برای شروع کار با CSS Custom Properties در React، ابتدا باید نحوه تعریف این متغیرها در CSS و سپس نحوه دستکاری آنها از طریق جاوااسکریپت را بدانید.
تعریف متغیرها در CSS
متغیرهای CSS همیشه با دو خط تیره (--) آغاز میشوند و با تابع var() خوانده میشوند:
/* در فایل global.css */
:root {
--primary-color: #3498db;
--secondary-color: #2ecc71;
--font-size-base: 16px;
--spacing-unit: 8px;
}
.button {
background-color: var(--primary-color);
font-size: var(--font-size-base);
padding: var(--spacing-unit) calc(var(--spacing-unit) * 2);
}
استفاده در کامپوننت React
حال در یک کامپوننت React، میتوانید این متغیرها را مستقیماً در فایل CSS (ماژولار یا گلوبال) استفاده کنید. اما قدرت واقعی زمانی نمایان میشود که بخواهید این متغیرها را به صورت داینامیک تغییر دهید.
// ThemeToggle.jsx
import React, { useState } from 'react';
import './ThemeToggle.css'; // حاوی تعریف متغیرها در :root
const ThemeToggle = () => {
const [isDark, setIsDark] = useState(false);
const toggleTheme = () => {
const root = document.documentElement;
if (!isDark) {
root.style.setProperty('--primary-color', '#2c3e50');
root.style.setProperty('--background-color', '#1a1a2e');
root.style.setProperty('--text-color', '#ecf0f1');
} else {
root.style.setProperty('--primary-color', '#3498db');
root.style.setProperty('--background-color', '#ffffff');
root.style.setProperty('--text-color', '#2c3e50');
}
setIsDark(!isDark);
};
return (
<button onClick={toggleTheme} className="theme-toggle-btn">
تغییر به {isDark ? 'روشن' : 'تاریک'}
</button>
);
};
export default ThemeToggle;
در این مثال ساده، CSS Custom Properties در React با تغییر مستقیم متغیرهای سطح :root، کل صفحه را به تم جدید تغییر میدهد. توجه کنید که هیچ کامپوننتی رندر مجدد نمیشود؛ فقط مرورگر مقادیر CSS را بهروزرسانی کرده و صفحه را دوباره نقاشی میکند (repaint). این بسیار کارآمدتر از روشهای مبتنی بر state است.
مزایای استفاده از CSS Custom Properties در React نسبت به Context API و Redux برای استایل
یکی از سوالات رایج در داناپدیا این است: “آیا نمیتوانیم تم را در Context یا Redux ذخیره کرده و با تغییر آن، تمام کامپوننتها را ریرندر کنیم؟” پاسخ: چرا، اما این روش معایب بزرگی دارد:
- ریرندرهای گسترده: تغییر یک مقدار در Context باعث میشود تمام کامپوننتهای مصرفکننده آن Context دوباره رندر شوند. در یک برنامه بزرگ با صدها کامپوننت، این مسئله میتواند باعث افت محسوس عملکرد شود.
- پیچیدگی کد: برای هر کامپوننتی که به تم دسترسی دارد، باید
useContextیاuseSelectorنوشته شود. - عدم کارایی برای انیمیشنها: اگر قرار است تم در هر فریم تغییر کند (مثلاً انیمیشن وابسته به اسکرول)، ریرندر کردن کل درخت کامپوننت غیرممکن است.
در مقابل، کاملاً خارج از چرخه رندر React عمل میکند. تغییر یک متغیر CSS هیچ ریرندری ایجاد نمیکند، مستقل از کتابخانه state management است و میتواند در هر فریم (با استفاده از requestAnimationFrame) بهروزرسانی شود. این تفاوت بنیادین، CSS Custom Properties در React را برای سیستمهای تم پویا به گزینهای بینظیر تبدیل میکند.
پیادهسازی یک سیستم تم پیشرفته با CSS Custom Properties در React
حال بیایید یک سیستم تم کامل پیادهسازی کنیم که از dark mode، light mode و حتی تمهای سفارشی کاربر پشتیبانی میکند. این سیستم در پروژههای واقعی داناپدیا مورد استفاده قرار گرفته است.
مرحله ۱: تعریف متغیرهای پایه در CSS
فایل themes.css:
/* Light Theme (پیشفرض) */
:root {
--bg-primary: #ffffff;
--bg-secondary: #f8f9fa;
--text-primary: #212529;
--text-secondary: #6c757d;
--accent: #0d6efd;
--border: #dee2e6;
--shadow: rgba(0,0,0,0.1);
--transition: 0.2s ease;
}
/* Dark Theme - با اعمال کلاس dark-mode روی body */
.dark-mode {
--bg-primary: #121212;
--bg-secondary: #1e1e1e;
--text-primary: #e9ecef;
--text-secondary: #adb5bd;
--accent: #0d6efd;
--border: #2c2c2c;
--shadow: rgba(0,0,0,0.3);
}
مرحله ۲: ایجاد یک Provider برای مدیریت تم
// ThemeProvider.jsx
import React, { createContext, useContext, useEffect, useState } from 'react';
const ThemeContext = createContext();
export const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState(localStorage.getItem('theme') || 'light');
useEffect(() => {
const root = document.documentElement;
if (theme === 'dark') {
root.classList.add('dark-mode');
} else {
root.classList.remove('dark-mode');
}
localStorage.setItem('theme', theme);
}, [theme]);
const toggleTheme = () => {
setTheme(prev => prev === 'light' ? 'dark' : 'light');
};
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
};
export const useTheme = () => useContext(ThemeContext);
مرحله ۳: تغییر پویای تم برای یک کامپوننت خاص (نه کل صفحه)
گاهی اوقات میخواهید فقط یک کامپوننت خاص (مثل یک کارت) تم متفاوتی داشته باشد. با CSS Custom Properties در React میتوانید متغیرها را مستقیماً روی خود آن المان اعمال کنید:
// ThemedCard.jsx
import React, { useState } from 'react';
import './Card.css';
const ThemedCard = ({ title, content }) => {
const [isHighlighted, setIsHighlighted] = useState(false);
const cardStyle = {
'--card-bg': isHighlighted ? '#fff3cd' : 'var(--bg-secondary)',
'--card-border': isHighlighted ? '#ffecb5' : 'var(--border)'
};
return (
<div className="custom-card" style={cardStyle}>
<h3>{title}</h3>
<p>{content}</p>
<button onClick={() => setIsHighlighted(!isHighlighted)}>
هایلایت
</button>
</div>
);
};
export default ThemedCard;
و در فایل Card.css:
.custom-card {
background-color: var(--card-bg, var(--bg-secondary));
border: 1px solid var(--card-border, var(--border));
border-radius: 8px;
padding: 1rem;
transition: all var(--transition);
}
توجه کنید که مقدار fallback در var() تعریف شده است. اگر --card-bg تنظیم نشده باشد، از var(--bg-secondary) استفاده میکند. این یکی از قابلیتهای عالی است که به شما امنیت میدهد.
الگوی طراحی Chain of Responsibility
تعامل با Props و State در React
یکی از قویترین الگوها در CSS Custom Properties در React استفاده از props و state برای بهروزرسانی متغیرهای CSS است. این روش به شما اجازه میدهد استایلهای کاملاً داینامیک بدون ریرندر اضافی داشته باشید.
مثال: اسلایدر برای تغییر فاصله (Spacing)
// SpacingSlider.jsx
import React, { useState } from 'react';
const SpacingSlider = () => {
const [spacing, setSpacing] = useState(8);
const handleChange = (e) => {
const newSpacing = e.target.value;
setSpacing(newSpacing);
document.documentElement.style.setProperty('--dynamic-spacing', `${newSpacing}px`);
};
return (
<div>
<input type="range" min="4" max="32" value={spacing} onChange={handleChange} />
<div className="spacing-demo">
<div className="box">جعبه ۱</div>
<div className="box">جعبه ۲</div>
</div>
</div>
);
};
و CSS:
.spacing-demo {
display: flex;
gap: var(--dynamic-spacing, 8px);
}
.box {
padding: var(--dynamic-spacing, 8px);
background-color: var(--accent);
}
با حرکت اسلایدر، فاصله بین جعبهها و padding داخلی آنها بدون هیچ ریرندری تغییر میکند. این الگو در داناپدیا برای ساخت ابزارهای سفارشیسازی ظاهر در پنل کاربری استفاده میشود.
بهینهسازی عملکرد و جلوگیری از flickering
CSS Custom Properties در React ذاتاً سریع هستند، اما نکاتی برای بهینهسازی بیشتر وجود دارد:
- تغییرات دستهجمعی: به جای چندین فراخوانی
setPropertyپشت سر هم، تغییرات را در یک ریکوئست انیمیشن فریم (requestAnimationFrame) گروهبندی کنید. - استفاده از class به جای setProperty برای تغییرات بزرگ: اگر قرار است یک تم کامل تغییر کند، بهتر است یک کلاس به
document.documentElementاضافه کنید (مانند مثالdark-mode) تا مرورگر بتواند تغییرات را بهینهتر اعمال کند. - پرهیز از setProperty درون حلقههای رندر: هرگز در بدنه یک کامپوننت (نه در useEffect یا event handler) از
setPropertyاستفاده نکنید، زیرا باعث اجرای مکرر کد میشود. - کاهش repaint: اگر متغیرهای زیادی را تغییر میدهید، در نظر داشته باشید که برخی ویژگیهای CSS (مثل
box-shadowوborder-radius) سنگینتر از سایرین (مانندcolorوbackground-color) هستند.
رفع مشکل پشتیبانی مرورگرها
CSS Custom Properties در React در تمام مرورگرهای مدرن (از جمله تمام نسخههای Chrome، Firefox، Safari، Edge) پشتیبانی میشوند. تنها مرورگری که مشکل دارد Internet Explorer 11 است (که دیگر پشتیبانی نمیشود). اگر همچنان نیاز به پشتیبانی از IE11 دارید، میتوانید از پلیفیلهایی مانند css-vars-ponyfill استفاده کنید:
import cssVars from 'css-vars-ponyfill';
useEffect(() => {
cssVars({
watch: true, // تغییرات را در زمان اجرا نیز نظارت میکند
onlyLegacy: true // فقط برای مرورگرهای قدیمی اعمال شود
});
}, []);
با این حال، در داناپدیا توصیه میکنیم اگر پروژه شما نیاز به IE11 دارد، از روشهای جایگزین مانند CSS-in-JS استفاده کنید، زیرا پلیفیلها عملکرد را کاهش میدهند.
ترکیب CSS Custom Properties با CSS Modules و Styled Components
یکی از سوالات رایج: “آیا میتوانم CSS Custom Properties در React را همراه با CSS Modules یا Styled Components استفاده کنم؟” پاسخ: قطعاً بله.
با CSS Modules
در فایل Button.module.css:
.button {
background-color: var(--button-bg, var(--primary-color));
color: var(--button-text, white);
padding: var(--button-padding, 8px 16px);
}
در کامپوننت:
import styles from './Button.module.css';
const Button = ({ variant }) => {
const style = {
'--button-bg': variant === 'danger' ? '#dc3545' : '#0d6efd'
};
return <button className={styles.button} style={style}>کلیک</button>;
};
با Styled Components
import styled from 'styled-components';
const StyledDiv = styled.div`
background-color: var(--dynamic-bg, #f0f0f0);
transition: background-color 0.3s;
`;
const MyComponent = () => {
const [color, setColor] = useState('#3498db');
return (
<StyledDiv style={{ '--dynamic-bg': color }}>
محتوای پویا
</StyledDiv>
);
};
در این روش، به عنوان لایه ارتباطی بین منطق جاوااسکریپت و استایلهای تعریفشده در styled-components عمل میکنند.
انیمیشنهای داینامیک با CSS Custom Properties در React
یکی از جذابترین کاربردهای CSS Custom Properties در React، ساخت انیمیشنهایی است که به ورودی کاربر (مثل حرکت موس یا اسکرول) واکنش نشان میدهند.
مثال: انیمیشن وابسته به موقعیت موس
const MouseTrail = () => {
useEffect(() => {
const handleMouseMove = (e) => {
const x = (e.clientX / window.innerWidth) * 100;
const y = (e.clientY / window.innerHeight) * 100;
document.documentElement.style.setProperty('--mouse-x', `${x}%`);
document.documentElement.style.setProperty('--mouse-y', `${y}%`);
};
window.addEventListener('mousemove', handleMouseMove);
return () => window.removeEventListener('mousemove', handleMouseMove);
}, []);
return <div className="gradient-bg"></div>;
};
CSS:
.gradient-bg {
width: 100%;
height: 100vh;
background: radial-gradient(circle at var(--mouse-x, 50%) var(--mouse-y, 50%),
#ff6b6b, #4ecdc4);
transition: background 0.05s linear;
}
این الگو بدون هیچ ریرندری، هر حرکت موس را دنبال میکند و gradient را بهروزرسانی میکند. با روشهای سنتی React (state و re-render) این کار عملاً غیرممکن است.
عیبیابی خطاهای رایج در CSS Custom Properties در React
- خطا: متغیر تعریف شده اما اعمال نمیشود: اطمینان حاصل کنید که متغیر در محدوده (scope) صحیح تعریف شده است. اگر متغیر را روی
:rootتعریف کردهاید، در کل صفحه در دسترس است. اگر روی یک کلاس خاص تعریف کردهاید، فقط فرزندان آن کلاس به آن دسترسی دارند. - خطا: مقدار fallback کار نمیکند: سینتکس درست
var(--my-var, fallback)است. دقت کنید که بین کاما و fallback فاصله نگذارید. - مقادیر عددی: در CSS Custom Properties در React، متغیرها همیشه به عنوان رشته ذخیره میشوند. اگر میخواهید عملیات ریاضی انجام دهید، از
calc()استفاده کنید:width: calc(var(--size) * 2px); - ساختار camelCase در جاوااسکریپت: در جاوااسکریپت هنگام استفاده از
setProperty، نام متغیر حتماً باید با دو خط تیره شروع شود:setProperty('--myVar', value). اما در style attribute میتوانید از camelCase استفاده کنید:style={{ '--my-var': value }}.
نتیجهگیری نهایی
در این مقاله جامع از داناپدیا، به طور کامل بررسی کردیم. آموختیم که چگونه این متغیرهای بومی CSS میتوانند تمسازی پویا، انیمیشنهای وابسته به ورودی کاربر و شخصیسازی لحظهای استایلها را با عملکردی بینظیر ممکن سازند. دیدیم که CSS Custom Properties در React نسبت به روشهای سنتی مانند Context API یا Redux از ریرندرهای غیرضروری جلوگیری میکند و در سناریوهای پرتغییر (مثل دنبال کردن موس) تنها راه حل عملی است. همچنین یاد گرفتیم که چگونه این متغیرها را با CSS Modules، Styled Components و حتی پلیفیلها برای مرورگرهای قدیمی ترکیب کنیم.
CSS Custom Properties در React یک تکنیک ضروری برای هر توسعهدهنده frontend حرفهای است. اگر به دنبال خلق تجربههای کاربری پویا و با کارایی بالا هستید، همین امروز استفاده از را در پروژههای خود شروع کنید. داناپدیا همواره به روزترین و عمیقترین مطالب را در اختیار شما قرار میدهد.

سوالات متداول (FAQ)
سوال ۱: آیا CSS Custom Properties در React باعث کاهش سرعت صفحه میشوند؟
خیر، برعکس. معمولاً سریعتر از روشهای مبتنی بر جاوااسکریپت خالص (مانند تغییر inline style یا ریرندر کامپوننت) عمل میکنند، زیرا مرورگرها برای مدیریت متغیرهای CSS بهینه شدهاند. تنها در صورت تغییر مکرر متغیرهایی که باعث repaint ناحیه بزرگ میشوند (مثل box-shadow سنگین) ممکن است کاهش جزئی احساس شود، که این محدودیت مربوط به CSS است نه خود متغیرها.
سوال ۲: آیا میتوانم از CSS Custom Properties در React به همراه Sass استفاده کنم؟
بله، کاملاً. متغیرهای Sass در زمان کامپایل و در زمان اجرا عمل میکنند. شما میتوانید متغیرهای Sass را به عنوان مقادیر اولیه به متغیرهای CSS اختصاص دهید: --primary-color: #{$primary-color}; (با استفاده از interpolation در Sass). این ترکیب بهترین هر دو جهان را به شما میدهد.
سوال ۳: چگونه در تستهای Jest با CSS Custom Properties کار کنم؟
در محیط Jest، DOM واقعی وجود ندارد. اگر کدی که از document.documentElement.style.setProperty استفاده میکند را تست میکنید، باید محیط DOM را با jest-environment-jsdom شبیهسازی کنید. همچنین میتوانید فراخوانیهای setProperty را mock کنید. در داناپدیا توصیه میکنیم منطق مربوط به تغییر متغیرها را در custom hooks جدا کنید تا تستپذیری افزایش یابد.
سوال ۴: آیا میتوانم مقادیر CSS Custom Properties را در DevTools ببینم؟
بله، در پنل Styles مرورگر، هر جا که از var(--my-var) استفاده شده باشد، مقدار فعلی متغیر را نشان میدهد. همچنین در بخش “Computed” میتوانید مقدار نهایی هر ویژگی را ببینید. برای دیباگ، در کنسول جاوااسکریپت میتوانید بنویسید: getComputedStyle(document.documentElement).getPropertyValue('--my-var').
سوال ۵: آیا میتوانم از CSS Custom Properties در React برای RTL (راست به چپ) استفاده کنم؟
بله، یکی از قویترین کاربردها. میتوانید متغیرهایی مانند --padding-start تعریف کنید و در CSS RTL آن را به --padding-end نگاشت دهید. با تغییر یک کلاس روی body (مثلاً .rtl)، تمام فواصل به طور خودکار معکوس میشوند بدون اینکه نیاز باشد چندین فایل CSS جداگانه بنویسید.
سوال ۶: آیا مقداردهی اولیه متغیرها در :root همیشه امن است؟
بله، :root با المان <html> مطابقت دارد و بالاترین سطح specificity را دارد. متغیرهای تعریفشده در :root در کل صفحه در دسترس هستند. اگر میخواهید متغیر فقط در یک کامپوننت خاص معتبر باشد، متغیر را روی کلاس همان کامپوننت تعریف کنید.
سوال ۷: آیا میتوانم از CSS Custom Properties در React داخل کلیدهای فریم (keyframes) استفاده کنم؟
بله، هر جایی که از مقدار CSS استفاده میشود، میتوانید از var() استفاده کنید، از جمله در @keyframes. این قابلیت فوقالعاده است: میتوانید یک انیمیشن داشته باشید که رنگ نهایی آن داینامیک باشد.
سوال ۸: آیا مقالات بیشتری در داناپدیا در مورد CSS Custom Properties در React وجود دارد؟
بله، داناپدیا مرجع تخصصی آموزش React و CSS پیشرفته است. میتوانید مقالات تکمیلی در مورد ترکیب با Tailwind CSS، پیادهسازی سیستم تم پیشرفته با پشتیبانی از ذخیره در localStorage، و بهینهسازی عملکرد انیمیشنها را در سایر بخشهای سایت جستجو کنید.