上下文

我基于二十三个十三构建了一个儿童主题,效果很好。将父主题更新到版本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 url,如下所示: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' );


我可以想到一些解决此问题的方法,但没有一个能真正令人满意的:


每次父主题为更新以更改style.css中的版本字符串(例如@import url('../twentythirteen/style.css?ver=NEW_VERSION');)。这会在父主题版本和子主题之间创建不必要的烦人链接。
在我孩子的functions.php中,1)wp_dequeue_style包含子主题的style.css和2)wp_enqueue_style父主题的style.css直接带有版本字符串。这会弄乱父主题中排队的css的顺序。对于这样的常见需求(高速缓存清除)而言,它似乎有些晦涩难懂。
将父主题的style_loader_tag转储到我的子主题的<link>中。确实与(1)相同,但速度更快。
让我的子主题的style.css成为父主题的style.css的符号链接。这似乎有点骇人听闻...

我错过了什么吗?有什么建议吗?

编辑

在父主题中添加了style.cssstyle.css样式表,以阐明为什么我不能在子主题中将style.css css语句更改为style.css。当前,在子主题的genericicons.css中带有ie.css语句,在生成的页面中有此顺序:


twentythirteen / genericons / genericons.css->由父主题排队的子元素
-theme / style.css->由父主题排队,@ importsthreethirteen / style.css
twentythirteen / css / ie.css->由父主题排队
child-theme / css / main.css ->按子主题排队

如果我将父项的@import列为对wp_enqueue_style的依赖项,则它将变为: >由父主题排队
child-theme / style.css->空,由父主题排队
twentythirteen / css / ie.css->由父主题排队
twentythirteen / style.css ->由子主题排队作为对main.css的依赖项。
child-theme / css / main.css->由子主题排队

请注意,ie.css现在包括在父项之前主题的@import。我不想更改父主题的css文件的排队顺序,因为我无法假定这不会导致css规则优先级出现问题。

评论

永远不要使用@import,而是将父主题的样式表设置为您自己样式表的依赖项。

我知道这不是最好的方法,但建议在这里使用:codex.wordpress.org/Child_Themes

此外,按照您的建议进行操作不能解决我的问题。父主题的style.css不会与现在包含在同一位置。父级包含必须位于其style.css和我的子主题的css之间的其他css文件。

请完全忽略抄本。它充满了错误的信息。使用dependency参数将以正确的顺序包含样式表。

请看我的编辑。

#1 楼

您不必使用@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更依赖于选择器的特异性。如果要覆盖某些内容,请使其选择器更具体。它可以是第一个,最后一个,或介于两者之间的任何东西,总是更胜一筹。

编辑

阅读您的注释并仔细查看代码,我知道在哪里错误就在这里。二十三个代码将“ get_stylesheet_uri()”加入队列,在子主题的情况下,它将是子主题的style.css文件,而不是父主题的文件。这就是@import起作用并保持相同顺序的原因(再次,它与您认为的无关紧要)。

在这种情况下,如果您不想使用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的顺序无关紧要,因为原始的“二十十三样式”没有将genericons.css作为列出的依赖项。

您自己孩子的style.css将会加载,说实话,这是您应该在其中对子主题进行更改的地方,而不是放在单独的main.css中。没有什么可以阻止您在其中进行更改,但是没有真正的理由要有额外的CSS文件。

评论


我完全同意@imports不是最好的方法。请参阅我的“编辑”部分,以获取更精确的信息。关于CSS的订购,我没有任何特殊需求。我只是不想修改父主题的css文件的内部顺序,而这可能会导致css规则优先级出现问题。

–伯尼
2014年10月3日,19:13

需要澄清的是,B.css(现在已更改为ie.css)不是我的子主题的一部分,但实际上是父主题的一部分。

–伯尼
2014年10月3日19:26

如果您希望样式紧随ie.css样式之后,则使自己的样式依赖于它。它的名字是“二十十三岁”。顺序完全由您声明的依赖项来管理,但是同样,对于CSS,文档中它们的实际顺序通常并不重要,因此我不确定为什么您会过多地关心它。

–奥托
2014年10月3日20:12



编辑了我的答案,以包括其他方法。

–奥托
2014年10月3日在20:29

是的,我想我对保持CSS顺序的“需求”感到很困惑。如果顺序对于父主题确实非常重要,则应在依赖项中说明。

–伯尼
2014年10月4日14:20

#2 楼

我之前的答案过于复杂,可能不尊重父主题的依赖关系链(请参见其他答案中的注释)。

这是另一个更简单的方法,应该可以更好地工作:

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中。

评论


仅作记录:1)您的代码将生成与使用旧@import版本完全相同的html,对性能完全没有影响,将有两个单独的style.css向服务器发送请求2)此答案将删除整个依赖项3)您可以在此处检查get_template_directory_uri和get_template_stylesheet_uri在做什么:core.trac.wordpress.org/browser/tags/4.8/src/wp-includes/…同样,不需要大部分代码。

–bg17aw
17年8月31日22:19

@ bg17aw使用wp_enqueue_style会根据主题的版本自动将缓存清除查询字符串添加到它生成的网址(例如?ver = 2013-07-18)。这不是通过@import语句完成的。

–伯尼
17年9月14日在18:01

#3 楼

警告

此解决方案不尊重父主题的依赖性!更改父主题的句柄名称会影响在父主题中设置的依赖项链。请参阅我的简单得多的其他答案。

原始答案

尽管Otto的答案相当不错,但我最终在我的子主题的函数中使用了它。php

function my_theme_styles() {
    global $wp_styles;
    $parentOriginalHandle = 'twentythirteen-style';
    $parentNewHandle = 'parent-style';

    // Deregister our style.css which was enqueued by the parent theme; we want
    // to control the versioning ourself.
    $parentStyleVersion = $wp_styles->registered[$parentOriginalHandle]->ver;
    $parentDeps = $wp_styles->registered[$parentOriginalHandle]->deps;
    wp_deregister_style($parentOriginalHandle);

    // Enqueue the parent theme's style.css with whatever version it used instead
    // of @import-ing it in the child theme's style.css
    wp_register_style($parentNewHandle, get_template_directory_uri() . '/style.css',
        $parentDeps, $parentStyleVersion);

    // Enqueue our style.css with our own version
    $themeVersion = wp_get_theme()->get('Version');
    wp_enqueue_style($parentOriginalHandle, get_stylesheet_directory_uri() . '/style.css',
        [$parentNewHandle], $themeVersion);
}

// Run this action action the parent theme has enqueued its styles.
add_action('wp_enqueue_scripts', 'my_theme_styles', 20);


它在控制子主题style.css的版本的同时,保持父主题的style.css顺序和版本号。

评论


令我感到困惑的是,最流行的博客软件仅需要20多行代码即可调整现有主题的CSS。我想那是工作安全。

–卡尔G
15年1月25日在21:45

我不得不将[$ parentNewHandle]更改为array($ parentNewHandle)

–卡尔G
15年1月25日在22:24

@CarlG:PHP 5.4中引入了我使用的数组语法(括号)。

–伯尼
15年1月26日在4:47

致支持者:请参阅我的其他答案,该答案可以解决此问题。

–伯尼
15年3月23日在17:21

这都是一个巨大的误解,不需要任何这些。实际上,旧的@import方法同样适用,请比较这两种方法。至于子主题对父主题的依赖性,也不需要。至少在我的测试中,子style.css总是在父项之后加载。爱被证明是错误的。

–bg17aw
17年8月31日在22:23