افزونه را نصب می‌کنید، همه‌چیز در پیشخوان درست کار می‌کند ولی روی سایت زنده، دکمه‌ها بی‌رنگ هستند، فاصله‌ها به‌هم ریخته و بعضی عناصر کاملاً بی‌ظاهرند. اگر با خطای عدم بارگذاری CSS افزونه روبرو هستید، این مقاله همان مسیری را طی می‌کند که در سال‌ها کار روی صدها پروژه واقعی وردپرس بارها پیموده‌ام. این خطا در نگاه اول به‌نظر یک راز مرموز می‌رسد، ولی در عمل همیشه در یکی از پنج لایه مشخص ریشه دارد: استفاده از هوک نادرست برای enqueue، ترتیب و وابستگی نادرست فایل‌ها، مسیر یا URL اشتباه، تعارض با افزونه‌های کش و بهینه‌ساز، و بارگذاری شرطی نادرست. اگر این پنج لایه را به ترتیب بررسی کنید، تقریباً همیشه به علت دقیق می‌رسید بدون آنکه ساعت‌ها وقت خود را صرف آزمون‌وخطا کنید.

استایل افزونه لود نمی‌شود — تفکیک حالت‌های مختلف

قبل از هر اقدامی، باید مشخص کنید کدام یک از این چهار حالت را تجربه می‌کنید، چون هرکدام سرنخ متفاوتی به دست می‌دهند. حالت اول: هیچ تغییری در ظاهر سایت دیده نمی‌شود — گویا فایل CSS اصلاً به صفحه نمی‌رسد. این حالت تقریباً همیشه به لایه اول (هوک نادرست) یا لایه سوم (مسیر اشتباه) برمی‌گردد. اگر با معماری پایه افزونه‌ها آشنا نیستید، بهتر است ابتدا نگاهی به افزونه وردپرس چیست بیندازید تا لایه‌بندی افزونه، هوک‌ها و بارگذاری فایل‌ها را در ذهن داشته باشید.

حالت دوم: استایل تا حدی اعمال می‌شود ولی بخشی از آن نادیده گرفته می‌شود — مثلاً رنگ‌ها تغییر می‌کنند ولی فاصله‌ها نه. این حالت نشانه این است که فایل لود می‌شود ولی ترتیب بارگذاری به نفع قالب است و selectorهای عمومی قالب روی افزونه غالب می‌شوند. حالت سوم: در پیشخوان کار می‌کند ولی در front-end لود نمی‌شود یا برعکس. این تفکیک جهت عیب‌یابی را کوتاه می‌کند، چون نشان می‌دهد کد شما فقط در یک context اجرا می‌شود. حالت چهارم: در مرورگر اول درست است ولی در مرورگر دیگر بی‌اثر — که معمولاً نشانه کش یا تفاوت رفتار مرورگرها در برابر محتوای مخلوط (Mixed Content) است.

در عیب‌یابی بارگذاری CSS، اولین سوال این نیست که «کد من کجاست»، بلکه «آیا مرورگر اصلاً فایل را درخواست می‌کند؟». تفاوت میان «لود شدن و بی‌اثر بودن» و «لود نشدن» کل مسیر تشخیص را تغییر می‌دهد.

wp_enqueue_style در وردپرس چطور کار می‌کند؟

وردپرس برای بارگذاری استایل و اسکریپت یک سیستم صف‌بندی رسمی دارد. به‌جای اینکه فایل‌ها را مستقیم در header با تگ <link> اضافه کنید، تابعی مثل wp_enqueue_style را صدا می‌زنید و وردپرس خودش در زمان مناسب، تگ‌های لازم را در head یا footer تولید می‌کند. مزیت این روش: امکان تعریف وابستگی بین فایل‌ها، امکان کنترل کش با نسخه، امکان حذف یا جایگزینی فایل توسط افزونه‌های دیگر، و جلوگیری از تکرار بارگذاری. اگر با مفهوم افزونه و لایه‌های معماری آن آشنا نیستید، توصیه می‌کنم اول آن مفهوم را تثبیت کنید و بعد به سراغ این مقاله برگردید.

هسته مکانیزم این است: هر فایل استایل با یک handle (شناسه یکتا) در صف قرار می‌گیرد، و در زمان تولید خروجی HTML، وردپرس تگ‌های <link> مربوطه را در head چاپ می‌کند. ترتیب چاپ بر اساس وابستگی‌ها و اولویت عددی تعیین می‌شود. اگر handle اشتباه، وابستگی نادرست یا هوک نادرست باشد، فایل به خروجی HTML اضافه نمی‌شود — و بی‌آنکه پیام خطایی ببینید، استایل شما روی سایت اعمال نمی‌شود. این سکوت، همان چیزی است که عیب‌یابی را دشوار می‌کند. برای درک عمیق‌تر چرخه اجرای هوک‌ها و جایگاه wp_enqueue_scripts در آن، نحوه استفاده صحیح از هوک‌های وردپرس را ببینید.

Contextهوک enqueueتابع مناسب
Front-end سایتwp_enqueue_scriptswp_enqueue_style
پیشخوان ادمینadmin_enqueue_scriptswp_enqueue_style
صفحه ورودlogin_enqueue_scriptswp_enqueue_style
ویرایشگر بلوکیenqueue_block_editor_assetswp_enqueue_style
صفحه سفارشی‌سازیcustomize_controls_enqueue_scriptswp_enqueue_style

هر ناحیه از وردپرس، هوک اختصاصی خودش را برای enqueue دارد. تشخیص اینکه در کدام ناحیه می‌خواهید استایل بارگذاری شود، اولین گام عیب‌یابی است. تجربه من از پروژه‌های واقعی این است که بیش از نیمی از موارد «استایل لود نمی‌شود»، به همین جدول ساده برمی‌گردد: کد در هوک اشتباه ثبت شده و در context مورد نظر اصلاً اجرا نمی‌شود.

لایه اول — استفاده از هوک نادرست برای enqueue

شایع‌ترین علت عدم بارگذاری CSS افزونه، استفاده از هوک اشتباه است. اگر می‌خواهید استایل روی front-end سایت لود شود ولی کد را داخل admin_enqueue_scripts نوشته‌اید، وردپرس آن را فقط در پیشخوان اجرا می‌کند. اگر می‌خواهید استایل در پیشخوان لود شود ولی کد را داخل wp_enqueue_scripts گذاشته‌اید، باز هم نتیجه نمی‌گیرید. اگر می‌خواهید استایل در صفحه ورود (wp-login.php) لود شود، باید از login_enqueue_scripts استفاده کنید.

الگوی درست برای front-end

الگویی که در همه افزونه‌های خودم به کار می‌برم، سه بخش دارد: تعریف تابع enqueue، اتصال به هوک درست، و استفاده از URL صحیح برای فایل:

add_action( 'wp_enqueue_scripts', 'my_plugin_enqueue_frontend_assets' );

function my_plugin_enqueue_frontend_assets() {
    wp_enqueue_style(
        'my-plugin-frontend',
        plugins_url( 'assets/css/frontend.css', __FILE__ ),
        array(),
        '1.0.0'
    );
}

سه نکته کلیدی در این کد: اول، handle یکتا که با پیشوند افزونه شروع می‌شود و شانس تصادم با افزونه‌های دیگر را کاهش می‌دهد. دوم، استفاده از plugins_url به‌جای URL دستی — اگر سایت روی HTTPS اجرا شود و شما URL را با http سخت‌کد کرده باشید، مرورگر آن را بلاک می‌کند. سوم، پارامتر نسخه (1.0.0) که به کش مرورگر می‌گوید هر بار که نسخه عوض شود، فایل دوباره دانلود شود.

الگوی درست برای پیشخوان

برای استایل‌های پیشخوان، فقط نام هوک تغییر می‌کند:

add_action( 'admin_enqueue_scripts', 'my_plugin_enqueue_admin_assets' );

function my_plugin_enqueue_admin_assets( $hook_suffix ) {
    // فقط در صفحه تنظیمات افزونه لود شود
    if ( 'settings_page_my-plugin' !== $hook_suffix ) {
        return;
    }
    wp_enqueue_style(
        'my-plugin-admin',
        plugins_url( 'assets/css/admin.css', __FILE__ ),
        array(),
        '1.0.0'
    );
}

نکته مهم در این کد: پارامتر $hook_suffix که به‌طور خودکار به تابع پاس داده می‌شود. با بررسی آن، می‌توانید استایل را فقط در صفحه‌های مربوط به افزونه خودتان لود کنید. این الگو جلوی بارگذاری استایل روی همه صفحه‌های پیشخوان را می‌گیرد و به کاهش مصرف منابع کمک می‌کند. اگر می‌خواهید بدانید چرا این جداسازی مهم است، مرور اصول کاهش مصرف منابع هاست را توصیه می‌کنم. همچنین، اگر ساختار افزونه شما چند فایل دارد و بارگذاری‌ها پخش شده‌اند، بررسی ساختار فایل‌های یک افزونه استاندارد وردپرس به شما کمک می‌کند تا کد را مرتب کنید.

اشتباه رایج: enqueue بعد از wp_head

هوک wp_enqueue_scripts پیش از تولید تگ‌های head اجرا می‌شود. اگر کد enqueue را در هوک دیرهنگامی مثل wp_head (که خودش در زمان تولید head اجرا می‌شود) یا در wp_footer بگذارید، فایل استایل خیلی دیر به صف اضافه می‌شود و در خروجی HTML ظاهر نمی‌شود. این اشتباه در کدهای قدیمی رایج است. برای مطالعه فهرست کامل این نوع اشتباهات، به اشتباهات رایج هنگام استفاده از هوک‌ها مراجعه کنید.

لایه دوم — ترتیب، وابستگی و اولویت enqueue

وقتی استایل لود می‌شود ولی اثر نمی‌کند یا بخشی از آن نادیده گرفته می‌شود، مشکل معمولاً در ترتیب و اولویت است. وردپرس فایل‌ها را بر اساس آرایه وابستگی‌ها و سپس ترتیب صف مرتب می‌کند. اگر استایل قالب بعد از استایل افزونه لود شود و selectorهای آن عمومی‌تر باشند، استایل قالب برنده می‌شود.

الگوی درست تعریف وابستگی

برای اطمینان از اینکه استایل افزونه پس از استایل قالب لود می‌شود — یا برعکس، قبل از آن — باید وابستگی را صریح تعریف کنید:

wp_enqueue_style(
    'my-plugin-frontend',
    plugins_url( 'assets/css/frontend.css', __FILE__ ),
    array( 'mytheme-main-style' ), // وابسته به استایل قالب
    '1.0.0'
);

اما تعریف وابستگی زمانی کار می‌کند که handle آن وابستگی قبلاً ثبت شده باشد. اگر قالب شما استایل خودش را با handle متفاوتی ثبت می‌کند، وردپرس وابستگی را نادیده می‌گیرد. راه‌حل: یا handle را در کد خودتان با wp_register_style ثبت کنید، یا از یک هوک با اولویت بالاتر برای اجرای enqueue استفاده کنید:

add_action( 'wp_enqueue_scripts', 'my_plugin_enqueue_late', 999 );

اولویت عددی 999 تضمین می‌کند که کد شما پس از کد قالب و سایر افزونه‌ها اجرا شود. این تکنیک ساده، در پروژه‌هایی که افزونه‌های متعددی استایل‌های مشترک بارگذاری می‌کنند بسیار کارساز است.

وابستگی به کتابخانه‌های عمومی

اگر استایل شما بر پایه یک فریمورک CSS یا یک کتابخانه عمومی (مثل Bootstrap، Tailwind یا Foundation) نوشته شده، باید وابستگی را به آن کتابخانه اعلام کنید. اگر افزونه شما فریمورک را خودش ثبت می‌کند و افزونه دیگری هم همان فریمورک را با handle متفاوت ثبت می‌کند، ترتیب‌ها مبهم می‌شود. راه‌حل: بررسی اینکه افزونه دیگری همان کتابخانه را لود می‌کند یا نه، و اگر بله، از handle همان افزونه استفاده کنید. اگر نه، خودتان نسخه‌تان را ثبت کنید ولی با یک handle یکتا که شانس تصادم نداشته باشد. اگر چند افزونه از یک کتابخانه مشترک استفاده می‌کنند، پیگیری این تصادم‌ها اهمیت بالایی دارد؛ بخشی از این مسئله در بررسی سازگاری افزونه‌های وردپرس توضیح داده شده است.

استایل‌های inline وابسته به فایل

گاهی استایل اصلی فایل لود می‌شود ولی متغیرهای CSS (مانند رنگ اصلی برند) که با wp_add_inline_style تزریق می‌شوند، نادیده گرفته می‌شوند. علت شایع این است که wp_add_inline_style پیش از ثبت handle اصلی فراخوانی می‌شود. توالی درست:

wp_enqueue_style( 'my-plugin-frontend', $css_url, array(), '1.0.0' );
wp_add_inline_style( 'my-plugin-frontend', '--my-brand: #2a7ae2;' );

اگر ترتیب برعکس باشد، inline style به صف اضافه نمی‌شود و متغیرهای CSS روی صفحه اعمال نمی‌شوند — درحالی‌که فایل اصلی کاملاً سالم لود شده است. این حالت نمونه‌ای از یک «عدم بارگذاری پنهان» است که در نگاه اول ظاهر سالمی دارد ولی ظاهر نهایی ناقص است.

لایه سوم — مسیر، URL و مشکلات SSL/Mixed Content

لایه سوم جایی است که مکانیزم بارگذاری درست انجام می‌شود ولی آدرس فایل اشتباه است. این حالت در عیب‌یابی به‌سادگی «فایل پیدا نشد» یا «محتوا مخلوط» می‌دهد. در تجربه من، این لایه بیشتر از آنکه به کد مربوط باشد، به محیط مربوط است و معمولاً روی محیط محلی دیده نمی‌شود و فقط روی سرور واقعی ظاهر می‌شود.

استفاده از توابع صحیح برای ساخت مسیر

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

// برای فایل‌های داخل افزونه
plugins_url( 'assets/css/style.css', __FILE__ );

// برای فایل‌های داخل قالب
get_stylesheet_directory_uri() . '/assets/css/style.css';

// برای فایل‌های داخل child theme
get_stylesheet_directory_uri() . '/assets/css/style.css';

// برای فایل‌های داخل parent theme (وقتی در child theme هستید)
get_template_directory_uri() . '/assets/css/style.css';

اشتباه رایج: استفاده از get_template_directory_uri() در child theme و انتظار دسترسی به فایل‌های child. تفاوت این دو تابع یکی از اولین چیزهایی است که در توسعه قالب باید تثبیت شود. برای درک کامل جایگاه هرکدام، قالب چایلد وردپرس چیست را ببینید. اگر استایل‌های شما در قالب هستند و مشکل بارگذاری دارید، راهنمای تخصصی‌تر در رفع خطای عدم بارگذاری استایل قالب آمده است.

Mixed Content و SSL

اگر سایت شما روی HTTPS اجرا می‌شود ولی URL فایل CSS شما با http:// سخت‌کد شده است، مرورگر مدرن آن را بلاک می‌کند و در کنسول پیام Mixed Content: The page was loaded over HTTPS but requested an insecure stylesheet نمایش داده می‌شود. این حالت زمانی رخ می‌دهد که:

  • از plugins_url یا get_template_directory_uri استفاده نکرده‌اید و URL را با http:// دستی نوشته‌اید.
  • دیتابیس شما هنوز روی http:// تنظیم است و فایل‌ها از همان دامنه درخواست می‌شوند.
  • افزونه‌ای در مسیر بارگذاری، URL را بازنویسی کرده و پروتکل را از دست داده است.

راه‌حل عمومی: در wp-config.php مقادیر WP_HOME و WP_SITEURL را با https:// تنظیم کنید، و سپس در دیتابیس تمام URLهای http:// را با ابزار safe search-replace به https:// تبدیل کنید. اگر با ابزار WP-CLI آشنا هستید، دستور wp search-replace این کار را امن انجام می‌دهد. اگر شک دارید که مشکل از SSL است، ابزار Network مرورگر را باز کنید و ببینید آیا درخواست CSS با کد خطای مرورگر رد می‌شود یا با کد ۲۰۰ ولی محتوای خالی.

مسیر باگ‌دار روی سیستم‌عامل سرور

یک مورد نادر ولی تکرارشونده: روی ویندوز سرور، مسیرها case-insensitive هستند ولی روی لینوکس case-sensitive. اگر مسیر فایل شما در کد assets/css/Style.css نوشته شده ولی فایل واقعی assets/css/style.css است، روی محیط محلی کار می‌کند و روی سرور لینوکسی خطای ۴۰۴ می‌دهد. این نکته ساده اما بسیار شایع است و در پروژه‌های تیمی که اعضای تیم روی سیستم‌عامل‌های متفاوت کار می‌کنند، بیشتر پیش می‌آید. برای پیشگیری، همه نام‌های فایل و پوشه را با حروف کوچک استاندارد کنید — این یکی از اصول رعایت استانداردهای کدنویسی وردپرس است.

مرورگر فقط با «URL اشتباه» کاری ندارد؛ با «URL درست ولی مسیر فیزیکی غلط» هم بی‌رحم است. در این لایه، عیب‌یابی روی سرور واقعی ضروری است — روی محیط محلی، بسیاری از این مشکلات اصلاً دیده نمی‌شوند.

لایه چهارم — تعارض با افزونه‌های کش و Minify

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

تشخیص ساده

در مرورگر، تب Network را باز کنید و روی فیلتر «CSS» کلیک کنید. صفحه را ریلود کنید و ببینید آیا فایل استایل افزونه شما اصلاً درخواست می‌شود. اگر درخواست می‌شود ولی محتوای آن خالی است یا ناقص، مسئله در افزونه بهینه‌ساز است. اگر درخواست اصلاً فرستاده نمی‌شود ولی تگ <link> آن در View Source دیده می‌شود، افزونه کش آن را به دامنه خودش منتقل کرده و در آن مسیر ناپیدا شده است.

راه‌حل: استثنا کردن فایل از ادغام

اکثر افزونه‌های بهینه‌ساز، امکان استثنا کردن فایل‌های خاصی از فرآیند minify یا combine را دارند. الگوی معمول: نام handle یا مسیر فایل را در تنظیمات افزونه کش وارد کنید تا هرگز ادغام نشود. برای مرور رفتار افزونه‌های محبوب در این زمینه، بهترین افزونه‌های کش وردپرس را ببینید — توضیحات هر افزونه درباره استثنا کردن فایل‌ها در همان مقاله آمده است.

پاک کردن کش پس از هر تغییر

اگر استایل شما تغییر می‌کند ولی تغییرات روی سایت اعمال نمی‌شود، کش سرور، کش افزونه، کش CDN یا کش مرورگر می‌تواند مسئول باشد. توالی درست پاک کردن کش:

  1. پاک کردن کش افزونه کش وردپرس (معمولاً دکمه Clear Cache در پیشخوان).
  2. پاک کردن کش CDN اگر از Cloudflare یا سرویس مشابه استفاده می‌کنید.
  3. پاک کردن کش مرورگر با Ctrl + Shift + R یا از تنظیمات Developer Tools (گزینه Disable Cache).
  4. تست در پنجره ناشناس (Incognito) که کش کمتری دارد.

برای مطالعه کامل نقش CDN و رفتار آن در بافت استایل‌ها و اسکریپت‌ها، نقش CDN در سرعت سایت را بررسی کنید. اگر پس از پاک کردن همه این چهار لایه، هنوز استایل اعمال نمی‌شود، مشکل از کش نیست — به لایه پنجم بروید.

minify تهاجمی و شکستن متغیرهای CSS

برخی افزونه‌های بهینه‌ساز، CSS را با متغیرهای سفارشی (--variable) اشتباه پردازش می‌کنند و در نسخه ادغام‌شده، این متغیرها نامعتبر می‌شوند. نتیجه: فایل لود می‌شود ولی رنگ‌ها و ابعاد اعمال نمی‌شوند. راه‌حل: فایل‌هایی که از CSS Custom Properties استفاده می‌کنند را از فرآیند minify تهاجمی استثنا کنید، یا از نسخه‌های جدیدتر افزونه بهینه‌ساز استفاده کنید که با CSS مدرن سازگارند.

لایه پنجم — بارگذاری شرطی و تشخیص صفحه جاری

در پروژه‌های بزرگ، افزونه‌ها معمولاً استایل خود را فقط در صفحه‌های خاصی لود می‌کنند تا بار سایت را کاهش دهند. اگر منطق تشخیص صفحه نادرست باشد، استایل در صفحه‌های مورد انتظار لود نمی‌شود. سه تابع تشخیصی که در بافت بارگذاری شرطی به کار می‌روند:

is_singular, is_page, is_single

تابع is_singular() برای نوشته یا برگه تک، is_page() برای برگه، و is_single() برای نوشته به کار می‌رود. اگر از is_single() استفاده کنید و انتظار داشته باشید روی یک برگه اعمال شود، منطق شما هیچ‌وقت اجرا نمی‌شود و استایل لود نمی‌شود. اشتباه رایج در پروژه‌ها این است که توسعه‌دهنده فکر می‌کند is_single() برای «هر صفحه‌ای که یک محتوا دارد» به کار می‌رود؛ در حالی که این تابع فقط برای post type پیش‌فرض post به کار می‌رود و برای برگه‌ها باید is_page() صدا شود.

add_action( 'wp_enqueue_scripts', function() {
    if ( is_singular( array( 'post', 'page', 'product' ) ) ) {
        wp_enqueue_style( 'my-plugin-frontend', $css_url, array(), '1.0.0' );
    }
} );

با استفاده از آرایه‌ای از post typeها در is_singular، می‌توانید استایل را فقط در بافت‌های مورد نظر لود کنید. اگر در یک پروژه بزرگ با چند post type سفارشی کار می‌کنید، این الگو بسیار مهم است. ساخت post type سفارشی و رفتار آن در بارگذاری‌ها در ساخت نوع نوشته سفارشی در وردپرس توضیح داده شده است.

has_shortcode و تشخیص محتوا

یکی از پرکاربردترین الگوهای بارگذاری شرطی، لود استایل فقط در صفحه‌هایی است که شورتکد افزونه شما را دارند. این الگو به‌تنهایی می‌تواند بار استایل افزونه را در ده‌ها صفحه غیرمرتبط حذف کند:

add_action( 'wp_enqueue_scripts', function() {
    global $post;
    if ( is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'my_plugin_form' ) ) {
        wp_enqueue_style( 'my-plugin-form', $css_url, array(), '1.0.0' );
    }
} );

دو نکته در این کد: اول، بررسی is_a که تضمین می‌کند $post واقعاً یک آبجکت است (در بافت‌هایی مثل آرشیو، ممکن است null باشد). دوم، استفاده از has_shortcode که یکی از سریع‌ترین راه‌های تشخیص محتوای صفحه است. این الگو، در عین کارایی، در بافت‌هایی که شورتکد از طریق بلوک گوتنبرگ اضافه شده ممکن است کار نکند؛ چون شورتکد در آن حالت به‌عنوان بلوک ذخیره می‌شود. در آن حالت باید has_block هم بررسی شود. اگر در پروژه شما شورتکدها نقش مهمی دارند، مرور ساخت شورت‌کد با کدنویسی وردپرس توصیه می‌شود.

template_redirect و wp

گاهی توسعه‌دهنده از wp یا template_redirect برای enqueue استفاده می‌کند و انتظار دارد استایل لود شود. توجه کنید که wp_enqueue_scripts پیش از این هوک‌ها اجرا می‌شود و پس از آن، صف بسته می‌شود. اگر بعد از این نقطه بخواهید فایلی به صف اضافه کنید، وردپرس آن را در خروجی HTML نمی‌آورد. راه‌حل: همیشه enqueue را در wp_enqueue_scripts انجام دهید و از هوک‌های دیگر فقط برای گرفتن اطلاعات استفاده کنید.

استایل ی که پس از بسته شدن صف enqueue شود، مثل نامه‌ای است که پس از بسته شدن پستخانه به صندوق انداخته شود — هیچ‌وقت به دست گیرنده نمی‌رسد. زمان‌بندی enqueue، همه چیز است.

چک‌لیست دیباگ گام‌به‌گام

این ترتیبی است که در پروژه‌های واقعی برای عیب‌یابی بارگذاری CSS طی می‌کنم. اگر ترتیب را حفظ کنید، از ارزان‌ترین و سریع‌ترین راه به پیچیده‌ترین می‌رسید و وقت خود را روی گام‌های غیرضروری هدر نمی‌دهید:

  1. بررسی Network در مرورگر: فایل استایل شما در درخواست‌ها دیده می‌شود؟ اگر خیر، مسئله در enqueue (لایه اول یا دوم) است. اگر بله ولی کد وضعیت ۴۰۴ دارد، مسئله در مسیر است. اگر بله ولی کد ۲۰۰ دارد ولی محتوا خالی است، مسئله در افزونه کش یا minify است.
  2. مشاهده View Source صفحه: تگ <link> برای فایل شما در HTML خروجی وجود دارد؟ اگر وجود ندارد، حتی اگر enqueue صدا زده شده باشد، خروجی نهایی آن را حذف کرده است.
  3. فعال‌سازی WP_DEBUG: در wp-config.php خطوط WP_DEBUG، WP_DEBUG_LOG و WP_DEBUG_DISPLAY را تنظیم کنید. لاگ خطاها در wp-content/debug.log نوشته می‌شود.
  4. لاگ موقت در تابع enqueue: در ابتدای تابع خود یک error_log( 'enqueue called' ); بگذارید و بررسی کنید آیا اصلاً صدا زده می‌شود. اگر صدا زده نمی‌شود، هوک شما اجرا نمی‌شود — به لایه اول برگردید.
  5. غیرفعال کردن افزونه‌های کش: افزونه‌های کش و minify را موقتاً غیرفعال کنید و سایت را رفرش کنید. اگر مشکل حل شد، تعارض در لایه چهارم است.
  6. تست با قالب پیش‌فرض: قالب Twenty Twenty-Five را موقتاً فعال کنید. اگر مشکل برطرف شد، تعارض با قالب است. اگر باقی ماند، در افزونه.
  7. غیرفعال کردن افزونه‌های دیگر: همه افزونه‌ها را غیرفعال کنید و یکی‌یکی فعال کنید تا مقصر پیدا شود. الگوی کامل این تکنیک در چگونه افزونه مشکل‌ساز وردپرس را پیدا کنیم آمده است.
  8. تست HTTPS: اگر سایت روی HTTPS است، بررسی کنید URL فایل شما با https:// بارگذاری می‌شود یا خیر. در کنسول مرورگر پیام Mixed Content را جستجو کنید.
  9. مقایسه محیط محلی و سرور: اگر روی محلی کار می‌کند و روی سرور نه، مسئله در پیکربندی محیط است — از case sensitivity فایل‌ها تا SSL و محدودیت‌های سرور.

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

پرسش‌های پرتکرار درباره بارگذاری نشدن CSS افزونه

این بخش به پرسش‌هایی اختصاص دارد که در انجمن‌ها و تیکت‌های پشتیبانی بیشترین تکرار را دارند و در نتایج جستجو به‌عنوان پاسخ کوتاه ارزشمندند.

چرا استایل افزونه فقط در پیشخوان کار می‌کند ولی در سایت نه؟

دلیل رایج، استفاده از هوک اشتباه است. تابع enqueue افزونه شما احتمالاً به admin_enqueue_scripts وصل شده و در front-end اصلاً اجرا نمی‌شود. برای رفع، همان تابع را به wp_enqueue_scripts هم وصل کنید (اگر استایل در هر دو بافت لازم است) یا یک تابع جدا برای front-end بنویسید. همچنین بررسی کنید که آیا افزونه شما استایل را فقط در صفحه تنظیمات خودش enqueue می‌کند یا خیر — این یکی از الگوهای رایج است که در بافت‌هایی که استایل باید در front-end هم بارگذاری شود، به سردرگمی می‌انجامد.

آیا افزونه‌های کش می‌توانند باعث بارگذاری نشدن CSS شوند؟

بله و در عمل شایع‌ترین علت لایه چهارم است. افزونه‌های minify و combine ممکن است فایل شما را با فایل دیگری ادغام کنند و در نسخه نهایی، محتوای فایل شما حذف یا شکسته شود. راه‌حل: فایل یا handle افزونه خود را در تنظیمات افزونه کش استثنا کنید. اگر با افزونه‌های محبوب کار می‌کنید، مرور توضیحات استثنا کردن فایل در مقالات تخصصی هرکدام از آن‌ها توصیه می‌شود.

چرا در مرورگر اول درست است ولی در مرورگر دیگر نه؟

دو علت اصلی: اول، کش مرورگر اول نسخه قدیمی فایل را نگه داشته. دوم، رفتار مرورگر دوم در برابر محتوای مخلوط (Mixed Content) سختگیرانه‌تر است. حالت دوم در سایت‌های HTTPS که فایل‌ها با http:// بارگذاری می‌شوند شایع است. تست در پنجره ناشناس و پاک کردن کش مرورگر دوم، این دو علت را تفکیک می‌کند.

چرا استایل در بعضی صفحات لود می‌شود ولی در بعضی نه؟

این نشانه بارگذاری شرطی نادرست است. اگر از توابع تشخیصی مثل is_page، is_single یا has_shortcode استفاده می‌کنید، احتمالاً شرایط در برخی صفحه‌ها برآورده نمی‌شود. اول شرایط منطقی را در ذهن بازبینی کنید، سپس با error_log، مقدار توابع تشخیصی را در بافت‌های مختلف مشاهده کنید. برای درک کامل این توابع در بافت post typeهای سفارشی، توابع وردپرس برای ساخت کوئری سفارشی را ببینید.

آیا استفاده از CDN می‌تواند باعث بارگذاری نشدن CSS شود؟

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

چرا استایل روی HTTPS بارگذاری نمی‌شود ولی روی HTTP بله؟

این دقیقاً همان مسئله Mixed Content است. مرورگر مدرن روی صفحه HTTPS، بارگذاری منابع با http:// را بلاک می‌کند. راه‌حل: در کد افزونه، از plugins_url یا get_template_directory_uri استفاده کنید که خودشان پروتکل فعلی سایت را تشخیص می‌دهند. اگر URL در دیتابیس ذخیره شده، از wp search-replace برای تبدیل همه URLهای http:// به https:// استفاده کنید.

آیا می‌توان استایل افزونه را با gzip یا brotli فشرده کرد؟

بله ولی فشرده‌سازی باید در سطح سرور انجام شود، نه در فایل CSS. اگر خودتان فایل را با gzip فشرده کنید و به‌عنوان .css.gz نگه دارید، سرور باید هدر Content-Encoding: gzip را ارسال کند وگرنه مرورگر فایل را نمی‌فهمد. اکثر هاست‌ها این کار را به‌طور خودکار برای فایل‌های .css معمولی انجام می‌دهند. فعال کردن فشرده‌سازی در سطح سرور از طریق htaccess یا تنظیمات هاست کافی است و نیازی به دخالت در کد افزونه ندارد.

معماری پایدار برای بارگذاری مطمئن استایل

پس از حل مشکل، ارزش دارد که معماری افزونه را طوری تنظیم کنید که این نوع مسئله در آینده تکرار نشود. فهرستی از اصول که در پروژه‌های خودم به‌طور منظم رعایت می‌کنم:

  1. یک فایل مسئول enqueue: همه enqueueها را در یک فایل اختصاصی (assets.php یا مشابه) نگه دارید تا مسئولیت‌ها روشن باشند و کد در چند فایل پخش نشود.
  2. پیشوند یکتا برای handleها: همیشه نام افزونه را به‌عنوان پیشوند handle استفاده کنید (مثل myplugin-admin) تا شانس تصادم با افزونه‌های دیگر به‌شدت کاهش یابد.
  3. وابستگی صریح: اگر استایل شما به استایل قالب یا کتابخانه دیگری وابسته است، وابستگی را صریح تعریف کنید. هرگز به ترتیب پیش‌فرض وردپرس تکیه نکنید.
  4. بارگذاری شرطی: استایل را فقط در بافت‌هایی که لازم است لود کنید. این کار هم بار سایت را کاهش می‌دهد و هم شانس تعارض را کم می‌کند.
  5. استفاده از توابع استاندارد URL: plugins_url برای افزونه، get_stylesheet_directory_uri برای child theme، get_template_directory_uri برای parent theme. هرگز URL را دستی نسازید.
  6. مدیریت نسخه: پارامتر نسخه را در همه wp_enqueue_styleها وارد کنید و با هر تغییر، نسخه را افزایش دهید. این کار جلوی کش قدیمی مرورگر را می‌گیرد.
  7. تست روی محیط استجینگ: قبل از اعمال تغییرات روی سایت زنده، روی محیط جدا تست کنید. ساخت محیط استجینگ در توسعه وردپرس با محیط لوکال و پروتکل تغییر امن در تغییر قالب بدون آسیب به سایت توضیح داده شده است.
  8. بررسی سازگاری با افزونه‌های کش: هنگام انتشار نسخه جدید افزونه، سازگاری با افزونه‌های کش و بهینه‌ساز را تست کنید. اگر فایل‌های شما با minify تهاجمی ناسازگارند، در مستندات ذکر کنید.
  9. مستندسازی handleها: در مستندات افزونه، لیست handleهای استایل و اسکریپت را فهرست کنید تا اگر افزونه دیگری خواست وابسته شود یا حذف کند، مرجع روشنی داشته باشد.

یک نکته از تجربه شخصی در پروژه‌های فروشگاهی: به‌دلیل حساسیت بالای ظاهر، هر تغییر در استایل‌ها می‌تواند نرخ تبدیل را تحت تأثیر قرار دهد. اگر افزونه شما با ووکامرس کار می‌کند، تست نرخ تبدیل پیش و پس از انتشار نسخه جدید توصیه می‌شود. برای مطالعه رویکرد کلی این سنجش، CRO برای فروشگاه‌های ووکامرس را ببینید.

سخن پایانی

خطای عدم بارگذاری CSS افزونه، در نگاه اول به‌نظر یک راز پیچیده می‌رسد ولی در عمل همیشه در یکی از پنج لایه‌ای که در این مقاله بررسی کردیم ریشه دارد: هوک نادرست، ترتیب و وابستگی، مسیر و URL، تعارض با افزونه کش و minify، و بارگذاری شرطی. مسیر عیب‌یابی که در بخش چک‌لیست ارائه کردم، همان ترتیبی است که در پروژه‌های واقعی همیشه مرا سریع به علت رسانده؛ نکته کلیدی این است که از ارزان‌ترین گام (بررسی Network مرورگر) شروع کنید و به‌تدریج به گام‌های گران‌تر (غیرفعال کردن افزونه‌ها، مقایسه محیط‌ها) بروید. در بلندمدت، انضباط در نام‌گذاری handle، تعریف صریح وابستگی‌ها، و بارگذاری شرطی استایل، مهم‌تر از هر راه‌حل لحظه‌ای است — چون این انضباط است که اجازه نمی‌دهد این نوع خطا دوباره ظاهر شود.

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