問題描述

Context

我建立了一個基於二十三十三的小孩主題,效果很好。將父主題更新為 1.3 版後,我注意到由快取的父主題的 style.css 引起的造型的奇怪行為。

這是我的孩子主題的 style.css 的內容 (省略標題)

/* =Imports styles from the parent theme
-------------------------------------------------------------- */
@import url('../twentythirteen/style.css');

所以孩子主題的 style.css 只不過是匯入父主題的 style.css

我還有另一個 css 檔案,我的孩子主題的自定義,我排隊如 functions.php

// Enqueue parent theme's style.css (faster than using @import in our style.css)
$themeVersion = wp_get_theme()->get('Version');

// Enqueue child theme customizations
wp_enqueue_style('child_main', get_stylesheet_directory_uri() . '/css/main.css',
    null, $themeVersion);

這給我一個非常好的 css 網址,如下所示:domain.com/wp-content/themes/toutprettoutbon/css/main.css?ver=1.0.1,確保樣式表在子主題更新時重新載入。

現在的問題

宣告 @import url('../twentythirteen/style.css'); 完全獨立於底層父主題版本。實際上,可以更新父主題而不更新子主題,但瀏覽器仍將使用舊的../twentythirteen/style.css 的快取版本。

二十三十進入 style.css 的相關程式碼:

function twentythirteen_scripts_styles() {
    // ...

    // Add Genericons font, used in the main stylesheet.
    wp_enqueue_style( 'genericons', get_template_directory_uri() . '/genericons/genericons.css', array(), '3.03' );

    // Loads our main stylesheet.
    wp_enqueue_style( 'twentythirteen-style', get_stylesheet_uri(), array(), '2013-07-18' );
    // Note usage of get_stylesheet_uri() which actually enqueues child-theme/style.css

    // Loads the Internet Explorer specific stylesheet.
    wp_enqueue_style( 'twentythirteen-ie', get_template_directory_uri() . '/css/ie.css', array( 'twentythirteen-style' ), '2013-07-18' );
}
add_action( 'wp_enqueue_scripts', 'twentythirteen_scripts_styles' );

我可以想辦法解決這個問題,但沒有一個是令人滿意的:

  1. 每次更新父主題時更新我的​​子主題,以更改 style.css(例如 @import url('../twentythirteen/style.css?ver=NEW_VERSION');) 中的版本字串。這會在父主題版本和子版本之間建立一個不必要和惱人的連結。

  2. 在我孩子的 functions.php 中,1)wp_dequeue_style 包含的兒童主題的 style.css 和 2)wp_enqueue_style 的父主題的 style.css 直接與版本字串。這使得父主題中排隊的 css 的順序變得混亂。

  3. 使用 style_loader_tag 過濾器修改 style.css 生成的 css <link> 標籤,並修改路徑以直接指向父主題的 style.css 與版本字串。似乎對於這樣一個常見的需求 (快取破壞) 似乎是模糊的。

  4. 在我的孩子主題的 style.css 中轉儲父主題的 style.css 。與 (1) 相同,但是要快一點。

  5. 讓我的孩子主題的 style.css 成為父主題的 style.css 的符號連結。這似乎相當駭客

我錯過了什麼嗎?有什麼建議麼?

edit

在父主題中新增了 genericicons.cssie.css 樣式表,以澄清為什麼我不能將 @import css 語句更改為 wp_enqueue_style 在我的小孩主題中。目前,在我的小孩主題 style.css 中有一個 @import 語句,我在生成的頁面中有這個命令:

  1. 二十三/genericons /genericons.css – > 由父母排隊

  2. child-theme /style.css – > 由父主題排出,@imports 二十三/style.css

  3. 二十三/css /ie.css – > 由父母排隊

  4. child-theme /css /main.css – > 以小孩主題排隊

如果我排隊父母的 style.css 作為 main.css 的依賴,這將成為:

  1. 二十三/genericons /genericons.css – > 由父母排隊

  2. child-theme /style.css – > 空,由父主題排隊

  3. 二十三/css /ie.css – > 由父母排隊

  4. 二十三/style.css – > 由 child.css 作為依賴關係引導

  5. child-theme /css /main.css – > 以小孩主題排隊

請注意,ie.css 現在包含在父主題 style.css 之前。我不想改變父主題的 css 檔案的排隊順序,因為我不能假定這不會導致 CSS 優先順序的問題。

最佳解決方案

您不必使用 @import 。實際上最好不要。使用入隊的方法可能更好。

這是二十三的程式碼的相關部分:

function twentythirteen_scripts_styles() {
...
    // Loads our main stylesheet.
    wp_enqueue_style( 'twentythirteen-style', get_stylesheet_uri(), array(), '2013-07-18' );
...
}
add_action( 'wp_enqueue_scripts', 'twentythirteen_scripts_styles' );

以下是您在程式碼中所做的工作:

function child_scripts_styles() {
    wp_enqueue_style( 'child-style', get_stylesheet_directory_uri().'/css/main.css', array('twentythirteen-style'), 'YOUR_THEME_VERSION' );
}
add_action( 'wp_enqueue_scripts', 'child_scripts_styles' );

如果你的 main.css 必須來自父親的 style.css,那麼你只是依賴於它。

現在,如果你還有一個 B.css 的孩子,那麼你建立依賴關係:

function child_scripts_styles() {
    wp_enqueue_style( 'child-B-style', get_stylesheet_directory_uri().'/B.css', array('twentythirteen-style'), 'YOUR_THEME_VERSION' );
    wp_enqueue_style( 'child-style', get_stylesheet_directory_uri().'/css/main.css', array('child-B-style'), 'YOUR_THEME_VERSION' );
}
add_action( 'wp_enqueue_scripts', 'child_scripts_styles' );

使您為每個專案定義的依賴關係實際上反映了這些依賴關係是真正的。如果 main.css 必須在 B.css 之後,那麼它取決於它。如果 B.css 必須來自父親的 style.css,那麼 B 依賴於它。排隊系統將為您整理。

如果你沒有真正使用這個小孩的 style.css,那麼你根本就不需要排隊。它可以只是佔位符來儲存主題的標題資訊。不用嗎不要載入

而且,你在做什麼呢這樣依賴訂購呢?在大多數情況下,CSS 不關心載入順序。 CSS 更依賴於選擇器的特異性。如果你想要覆蓋某些東西,你可以選擇它更具體。它可以先到,最後,或之間的任何東西,更具體的選擇器總是勝利。

編輯

閱讀您的意見並仔細閱讀程式碼,我看到錯誤在這裡。 twenty-thirteen 程式碼是插入”get_stylesheet_uri()”,在一個小孩主題的情況下,它將是您的小孩主題的 style.css 檔案,而不是父檔案。這就是為什麼 @import 可以工作,並且保持相同的順序 (再一次,你的想法幾乎不重要) 。

在這種情況下,如果您不想使用匯入,我建議直接排入父級的 style.css 。像這樣:

function child_scripts_styles() {
    wp_enqueue_style( 'parent-style', get_template_directory_uri().'/style.css', array() );
}
add_action( 'wp_enqueue_scripts', 'child_scripts_styles' );

子主題的 functions.php 中的程式碼首先執行,所以您自己的 wp_enqueue_scripts 將首先執行,這將排列父主題的 style.css,父主題不會自己執行 (因為它實際上是插入您孩子的 style.css) 。透過不使它依賴於與父代相同的任何東西,那麼它只是被正確地放在輸出中。請注意,此檔案和 genericons.css 的順序並不重要,因為原始的”twentythirteen-style” 沒有 genericons.css 作為列出的依賴項。

你自己的孩子的 style.css 將載入,老實說,這是你應該把你的更改為孩子主題,而不是單獨的 main.css 。沒有什麼可以阻止你把你的改變放在那裡,但沒有什麼真正的理由有一個額外的 css 檔案。

次佳解決方案

我的 previous answer 過於複雜,可能不尊重父主題的依賴關係鏈 (見其他答案中的說明) 。

這是另一個更簡單的做法,應該工作得更好:

function use_parent_theme_stylesheet() {
    // Use the parent theme's stylesheet
    return get_template_directory_uri() . '/style.css';
}

function my_theme_styles() {
    $themeVersion = wp_get_theme()->get('Version');

    // Enqueue our style.css with our own version
    wp_enqueue_style('child-theme-style', get_stylesheet_directory_uri() . '/style.css',
        array(), $themeVersion);
}

// Filter get_stylesheet_uri() to return the parent theme's stylesheet
add_filter('stylesheet_uri', 'use_parent_theme_stylesheet');

// Enqueue this theme's scripts and styles (after parent theme)
add_action('wp_enqueue_scripts', 'my_theme_styles', 20);

這個想法是簡單地篩選父主題中的 get_stylesheet_uri()的呼叫,以返回它自己的樣式表而不是子主題。然後,子主題的樣式表稍後在動作鉤 my_theme_styles 中排隊。

參考文獻

注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。