【问题标题】:Load child theme CSS after Woocommerce CSS在 Woocommerce CSS 之后加载子主题 CSS
【发布时间】:2018-09-10 14:17:35
【问题描述】:

我试图避免使用 !important 来覆盖 WooCommerce 样式。现在我已经将 WooCommerce 样式排入队列并尝试在我的子模板之后将它们排入队列,但似乎没有任何效果。

// Dequeue Woocommerce Style
add_filter( 'woocommerce_enqueue_styles', '__return_empty_array' );

// Dequeue Parent themes
function understrap_remove_scripts() {
    wp_dequeue_style( 'understrap-styles' );
    wp_deregister_style( 'understrap-styles' );

    wp_dequeue_script( 'understrap-scripts' );
    wp_deregister_script( 'understrap-scripts' );

    // Removes the parent themes stylesheet and scripts from inc/enqueue.php
}

add_action( 'wp_enqueue_scripts', 'understrap_remove_scripts', 20 );

add_action( 'wp_enqueue_scripts', 'theme_enqueue_styles' );
function theme_enqueue_styles() {

    // Get the theme data
    $the_theme = wp_get_theme();
    wp_enqueue_style( 'child-understrap-styles', get_stylesheet_directory_uri() . '/css/child-theme.min.css', array(), $the_theme->get( 'Version' ) );
    wp_enqueue_script( 'jquery');
    wp_enqueue_script( 'popper-scripts', get_template_directory_uri() . '/js/popper.min.js', array(), false);
    wp_enqueue_script( 'child-understrap-scripts', get_stylesheet_directory_uri() . '/js/child-theme.min.js', array(), $the_theme->get( 'Version' ), true );
    if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
        wp_enqueue_script( 'comment-reply' );
    }
}

add_action( 'wp_enqueue_scripts', 'woocommerce_theme_styles' );
function woocommerce_theme_styles() {
    wp_enqueue_style('woocommerce_smallscreen', plugins_url() .'/woocommerce/assets/css/woocommerce-smallscreen.css');
    wp_enqueue_style('woocommerce_css', plugins_url() .'/woocommerce/assets/css/woocommerce.css');
    wp_enqueue_style('woocommerce_layout', plugins_url() .'/woocommerce/assets/css/woocommerce-layout.css');
}

这是网络的实时版本:http://ufctrashtalk.com

我做错了什么?

谢谢!!

【问题讨论】:

  • 为了覆盖你的css必须在休息之后加载。
  • 您似乎将它们出列,将您的孩子 css 排队,然后将它们排队。我不知道wordpress。但是我会删除 dequeueing 和 juste queue your child 主题,而不需要 woocomerce enqueueing。
  • 我不想让所有 woocommerce 样式出列,因为我需要大部分 CSS。我只想覆盖某些部分而不使用!important。谢谢!
  • 不要让任何一个出队。只需在 woocomerce 之后添加您的。这样,您的 ccs 应该在 woocomerce 之后加载并覆盖您在文件中指定的规则。
  • 即使您在 woocommerce 之前将样式排入队列,您仍然应该能够在不使用 !important 的情况下覆盖 woocommerce 样式。假设 woocommerce 样式“.wc_checkout 按钮”,并且您想要覆盖其样式,您可以更具体地指定您的 css 目标,它将通过定位 .wc_checkout .any-div-class button 来覆盖 woocommerce 样式

标签: php css wordpress woocommerce


【解决方案1】:

您在问题中提到您正在尝试覆盖一些 WooCommerce css 规则,但您刚刚使用这行代码从加载中删除了所有 WooCommerce 样式表:

add_filter( 'woocommerce_enqueue_styles', '__return_empty_array' );

如果要将它们保留在页面中,请删除上面提供的代码行。

实现目标的两种方法 - 在 WooCommerce 默认样式表之后加载样式表。首先,你不需要这部分代码:

add_action( 'wp_enqueue_scripts', 'woocommerce_theme_styles' );
function woocommerce_theme_styles() {
  wp_enqueue_style('woocommerce_smallscreen', plugins_url() .'/woocommerce/assets/css/woocommerce-smallscreen.css');
  wp_enqueue_style('woocommerce_css', plugins_url() .'/woocommerce/assets/css/woocommerce.css');
  wp_enqueue_style('woocommerce_layout', plugins_url() .'/woocommerce/assets/css/woocommerce-layout.css');
}

即使默认情况下,如果您删除上述功能,WooCommerce 也会在主题文件之前加载它的文件。它来自 WordPress 功能。首先加载所有插件,然后才加载主题。

WooCommerce 在插件处于活动状态时默认加载它们。 woocommerce.css 样式表可能不会加载,而是加载 twenty-seventeen.css,如果您网站的主题是 Twenty Seventeen

  1. 提高add_action() 的优先级:

    add_action( 'some-hook', 'some_function', 20 );
    

    这里 20 是优先级。默认为 10。增加优先级将稍后触发您的函数,这意味着您的 .css.js 文件将稍后加载到 DOM 中(毕竟 .css.js 文件,默认调用的优先级或更低)。 您的功能将是:

    //priority 20 is higer, then WooCommerce ones( 10 )
    add_action( 'wp_enqueue_scripts', 'theme_enqueue_styles', 20 );
    function theme_enqueue_styles() {
    
        // Get the theme data
        $the_theme = wp_get_theme();
        wp_enqueue_style( 'child-understrap-styles', get_stylesheet_directory_uri() . '/css/child-theme.min.css', array(), $the_theme->get( 'Version' ) );
        wp_enqueue_script( 'jquery');
        wp_enqueue_script( 'popper-scripts', get_template_directory_uri() . '/js/popper.min.js', array(), false);
        wp_enqueue_script( 'child-understrap-scripts', get_stylesheet_directory_uri() . '/js/child-theme.min.js', array(), $the_theme->get( 'Version' ), true );
        if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
            wp_enqueue_script( 'comment-reply' );
        }
    }
    

    这将在所有 woocommerce 文件之后加载您的 child-theme.min.css 文件。

  2. 为您的wp_enqueue_style() 函数使用依赖项。例如,如果您只想在 woocommerce-smallscreen.css 样式表之后加载样式表,请将其处理程序用作文件的依赖项:

     wp_enqueue_style( 'some-handler', 'some-url-of-file', array('depends-on', 'another-dependence') );
    

    所以,您可以使用woocommerce-smallscreen.css 文件的处理程序woocommerce-smallscreen

    add_action( 'wp_enqueue_scripts', 'theme_enqueue_styles' );
    function theme_enqueue_styles() {
    
        // Get the theme data
        $the_theme = wp_get_theme();
        //Here we use dependences
        wp_enqueue_style( 'child-understrap-styles', get_stylesheet_directory_uri() . '/css/child-theme.min.css', array('woocommerce-smallscreen'), $the_theme->get( 'Version' ) );
        wp_enqueue_script( 'jquery');
        wp_enqueue_script( 'popper-scripts', get_template_directory_uri() . '/js/popper.min.js', array(), false);
        wp_enqueue_script( 'child-understrap-scripts', get_stylesheet_directory_uri() . '/js/child-theme.min.js', array(), $the_theme->get( 'Version' ), true );
        if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
            wp_enqueue_script( 'comment-reply' );
        }
    }
    

    注意:如果您的样式表依赖的文件未加载(不存在,插件未激活),那么您的文件也将不会加载,因为依赖关系损坏。

因此,在一个步骤之后,您的样式表将在 WooCommerce 之后加载。但即使在它之后,您的 css 规则也不会覆盖 WooCommerce 规则,因为您使用的是较弱的规则,而 WooCommerce 使用的是最强的规则。例如:

WooCommerce:.woocommerce a.button{}

你的:.button.add_to_cart_button{}

尝试使用这个:.woocommerce a.button{},它将被覆盖。也可以查看this question

【讨论】:

  • 感谢您的回答,但它一直无法正常工作。我已经尝试了这两种解决方案,并且在我的孩子 CSS 之后加载了 WooCommerce 剧照。您可以在此处查看:ufctrashtalks.com - 如果您选中“立即购买”按钮。
  • @user3081614 不这么认为。代码经过测试并且可以工作。首先,在查看您的网站后,我注意到 woocommerce 样式表未加载。您正在使用add_filter( 'woocommerce_enqueue_styles', '__return_empty_array' );。去掉它。再试一次
  • 刚刚删除了 dequeue Woocommerce 样式,以便您可以对其进行测试。如果您从 CSS 属性中删除 !important,您将看到它将加载 WooCommerce CSS。感谢您的帮助!
  • 例如,您能否提供一些元素,如果没有!important,它不会从您的主题文件中覆盖?
  • 好的。所以你的 sass 转换为 child-theme.min.css 文件,对吧?但问题是在 woocommerce 中对目标元素使用更详细的规则,而您没有。 ex..woo span .a{something} your : .a,这不重要,你把代码放在哪里,它会被详细的规则覆盖
【解决方案2】:

不知道您为什么要取消 WooCommerce 样式的队列,但这应该可以解决您的问题:

// Dequeue Woocommerce Style
// add_filter( 'woocommerce_enqueue_styles', '__return_empty_array' );

// Dequeue Parent themes
function understrap_remove_scripts() {

    // wp_enqueue_style('woocommerce_smallscreen', plugins_url() .'/woocommerce/assets/css/woocommerce-smallscreen.css');
    // wp_enqueue_style('woocommerce_css', plugins_url() .'/woocommerce/assets/css/woocommerce.css');
    // wp_enqueue_style('woocommerce_layout', plugins_url() .'/woocommerce/assets/css/woocommerce-layout.css');

     // Removes the parent themes stylesheet and scripts from inc/enqueue.php
    wp_dequeue_style( 'understrap-styles' );
    wp_deregister_style( 'understrap-styles' );

    wp_dequeue_script( 'understrap-scripts' );
    wp_deregister_script( 'understrap-scripts' );

    // Get the theme data
    $the_theme = wp_get_theme();
    wp_enqueue_style( 'child-understrap-styles', get_stylesheet_directory_uri() . '/css/child-theme.min.css', array(), $the_theme->get( 'Version' ) );
    wp_enqueue_script( 'jquery');
    wp_enqueue_script( 'popper-scripts', get_template_directory_uri() . '/js/popper.min.js', array(), false);
    wp_enqueue_script( 'child-understrap-scripts', get_stylesheet_directory_uri() . '/js/child-theme.min.js', array(), $the_theme->get( 'Version' ), true );
    if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
        wp_enqueue_script( 'comment-reply' );
    }
}
add_action( 'wp_enqueue_scripts', 'ufctrashtalk_scripts' );

如果它不能解决问题,请取消注释功能,除非你有理由,否则我怀疑这是必要的。

【讨论】:

    【解决方案3】:

    要控制 .css 文件的加载顺序,您只需指定 wp_enqueue_style() 的 $deps 参数

    wp_enqueue_style( string $handle, string $src = '', array $deps = array(), string|bool|null $ver = false, string $media = 'all' )
    

    WordPress 用于创建要使用的 .css 文件的有序列表的算法非常简单,只有 46 行。

      /**
       * Determines dependencies.
       *
       * Recursively builds an array of items to process taking
       * dependencies into account. Does NOT catch infinite loops.
       *
       * @since 2.1.0
       * @since 2.6.0 Moved from `WP_Scripts`.
       * @since 2.8.0 Added the `$group` parameter.
       *
       * @param mixed     $handles   Item handle and argument (string) or item handles and arguments (array of strings).
       * @param bool      $recursion Internal flag that function is calling itself.
       * @param int|false $group     Group level: (int) level, (false) no groups.
       * @return bool True on success, false on failure.
       */
      public function all_deps( $handles, $recursion = false, $group = false ) {
        if ( !$handles = (array) $handles )
          return false;
    
        foreach ( $handles as $handle ) {
          $handle_parts = explode('?', $handle);
          $handle = $handle_parts[0];
          $queued = in_array($handle, $this->to_do, true);
    
          if ( in_array($handle, $this->done, true) ) // Already done
            continue;
    
          $moved     = $this->set_group( $handle, $recursion, $group );
          $new_group = $this->groups[ $handle ];
    
          if ( $queued && !$moved ) // already queued and in the right group
            continue;
    
          $keep_going = true;
          if ( !isset($this->registered[$handle]) )
            $keep_going = false; // Item doesn't exist.
          elseif ( $this->registered[$handle]->deps && array_diff($this->registered[$handle]->deps, array_keys($this->registered)) )
            $keep_going = false; // Item requires dependencies that don't exist.
          elseif ( $this->registered[$handle]->deps && !$this->all_deps( $this->registered[$handle]->deps, true, $new_group ) )
            $keep_going = false; // Item requires dependencies that don't exist.
    
          if ( ! $keep_going ) { // Either item or its dependencies don't exist.
            if ( $recursion )
              return false; // Abort this branch.
            else
              continue; // We're at the top level. Move on to the next one.
          }
    
          if ( $queued ) // Already grabbed it and its dependencies.
            continue;
    
          if ( isset($handle_parts[1]) )
            $this->args[$handle] = $handle_parts[1];
    
          $this->to_do[] = $handle;
        }
    
        return true;
      }
    

    删除所有错误检查这将简化为

      public function all_deps( $handles, $recursion = false, $group = false ) {
        foreach ( $handles as $handle ) {
          $this->registered[$handle]->deps && !$this->all_deps( $this->registered[$handle]->deps, true, $new_group ) )
          $this->to_do[] = $handle;
        }
      }
    

    有序列表是数组$this->to_do[]。要理解这一点,请注意 all_deps() 是一个递归函数并首先处理依赖关系

    $this->all_deps( $this->registered[$handle]->deps, true, $new_group )
    

    只有在处理完依赖项后,它才会将项目添加到 $this->to_do[]

    $this->to_do[] = $handle;
    

    因此,.css 文件入队的顺序不如依赖关系重要,您只需要依赖关系即可实现所需的 .css 文件相对顺序。

    作为最后的手段,您可以在 WordPress 使用过滤器“print_styles_array”发送 .css 文件之前修改此 $this->to_do[] 数组。

    add_filter( 'print_styles_array', function( $todo) {
        error_log( print_r( $todo, true ) );
        return $todo;
    } );
    

    这里我只使用它来转储 $this-to_do[] 数组,但您可以在返回之前对其进行修改。

    【讨论】:

      猜你喜欢
      • 2017-06-15
      • 2017-06-22
      • 2013-05-01
      • 2016-09-18
      • 2017-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-22
      相关资源
      最近更新 更多