Phiên bản @import của style.css của chủ đề gốc


28

Bối cảnh

Tôi đã xây dựng một chủ đề con dựa trên Twenty Thirteen hoạt động khá tốt. Sau khi cập nhật chủ đề gốc lên phiên bản 1.3, tôi nhận thấy hành vi lạ với kiểu dáng gây ra bởi chủ đề gốc được lưu trong bộ nhớ cache style.css.

Đây là nội dung của chủ đề con tôi style.css(bỏ qua các tiêu đề)

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

Vì vậy, chủ đề con style.csskhông làm gì khác hơn là nhập chủ đề gốc style.css.

Tôi cũng có một tệp css khác với các tùy chỉnh của chủ đề con tôi mà tôi thích như vậy trong 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);

Điều này mang lại cho tôi một url css rất đẹp như thế này: domain.com/wp-content/themes/toutprettoutbon/css/main.css?ver=1.0.1đảm bảo rằng biểu định kiểu được tải lại khi chủ đề con được cập nhật.

Bây giờ vấn đề

Tuyên bố @import url('../twentythirteen/style.css');này hoàn toàn độc lập với phiên bản của chủ đề gốc bên dưới. Trên thực tế, chủ đề gốc có thể được cập nhật mà không cần cập nhật chủ đề con nhưng trình duyệt vẫn sẽ sử dụng các phiên bản được lưu trong bộ nhớ cache cũ ../twentythirteen/style.css.

Mã có liên quan trong Twenty Thirteen bao gồm 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' );

Tôi có thể nghĩ ra một vài cách để giải quyết vấn đề này nhưng không có cách nào thực sự thỏa đáng:

  1. Cập nhật chủ đề con tôi mỗi khi chủ đề gốc được cập nhật để thay đổi chuỗi phiên bản trong style.css(ví dụ @import url('../twentythirteen/style.css?ver=NEW_VERSION');). Điều này tạo ra một liên kết không cần thiết và gây phiền nhiễu giữa phiên bản chủ đề cha mẹ và con.

  2. Trong con của tôi functions.php, 1) wp_dequeue_stylecác child theme bao gồm của style.cssvà 2) wp_enqueue_stylecác mẹ chủ đề là style.csstrực tiếp VỚI chuỗi phiên bản. Điều này làm rối loạn thứ tự của css xếp hàng trong chủ đề chính.

  3. Sử dụng style_loader_tagbộ lọc để sửa đổi <link>thẻ css được tạo style.cssvà sửa đổi đường dẫn để trỏ trực tiếp đến chủ đề gốcstyle.css CÓ chuỗi phiên bản. Có vẻ khá mơ hồ cho một nhu cầu phổ biến như vậy (bộ nhớ cache).

  4. Kết xuất chủ đề phụ huynh style.csstrong chủ đề con tôi style.css. Giống như (1) thực sự, nhưng nhanh hơn một chút.

  5. Làm cho chủ đề con tôi style.csstrở thành một liên kết đến chủ đề gốc style.css. Điều này có vẻ khá hackish ...

Tôi đã bỏ lỡ một cái gì đó? Bất kỳ đề xuất?

chỉnh sửa

Đã thêm genericicons.cssvà biểu định ie.csskiểu trong chủ đề gốc để làm rõ lý do tại sao tôi không thể thay đổi @importcâu lệnh css thành wp_enqueue_styletrong chủ đề con. Hiện tại, với một @importtuyên bố trong chủ đề con tôi style.css, tôi có thứ tự này trong các trang được tạo:

  1. hai mươi mười ba / genericons / genericons.css -> mê hoặc chủ đề phụ huynh
  2. chủ đề con / style.css -> mê hoặc chủ đề phụ huynh, @imports hai mươi mười ba / style.css
  3. twthirteen / css / eg.css -> mê hoặc chủ đề phụ huynh
  4. chủ đề con / css / main.css -> mê hoặc chủ đề con

Nếu tôi yêu cầu cha mẹ style.csslà người phụ thuộc main.css, điều này sẽ trở thành:

  1. hai mươi mười ba / genericons / genericons.css -> mê hoặc chủ đề phụ huynh
  2. chủ đề con / style.css -> trống rỗng, bị mê hoặc bởi chủ đề phụ huynh
  3. twthirteen / css / eg.css -> mê hoặc chủ đề phụ huynh
  4. twthirteen / style.css -> mê hoặc chủ đề con là sự phụ thuộc của main.css
  5. chủ đề con / css / main.css -> mê hoặc chủ đề con

Lưu ý rằng eg.css hiện được bao gồm trước chủ đề gốc style.css. Tôi không muốn thay đổi thứ tự mê hoặc của các tệp css của chủ đề gốc bởi vì tôi không thể cho rằng điều này sẽ không gây ra vấn đề với mức độ ưu tiên của quy tắc css.


5
Không bao giờ sử dụng @import, thay vào đó hãy đặt biểu định kiểu của chủ đề gốc làm phụ thuộc của biểu định kiểu của riêng bạn .
fuxia

Tôi biết đó không phải là cách tiếp cận tốt nhất nhưng nó được đề xuất ở đây: codex.wordpress.org/Child_Theme
bernie

Ngoài ra, làm những gì bạn đề nghị không khắc phục vấn đề của tôi. Chủ đề gốc style.csssẽ không được bao gồm tại cùng một nơi như bây giờ. Phụ huynh bao gồm các tệp css khác phải nằm giữa css của nó style.cssvà chủ đề con tôi.
bernie

3
Hãy bỏ qua codex hoàn toàn. Nó chứa đầy thông tin sai lệch. Sử dụng tham số phụ thuộc sẽ bao gồm các bảng định kiểu theo đúng thứ tự.
fuxia

Xin vui lòng xem chỉnh sửa của tôi.
bernie

Câu trả lời:


19

Bạn không phải sử dụng @import. Tốt nhất là không nên. Sử dụng một cách tiếp cận có lẽ là tốt hơn tất cả xung quanh.

Đây là phần có liên quan của mã thứ mười hai:

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' );

Đây là những gì bạn làm trong mã của bạn:

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' );

Nếu main.css của bạn phải xuất hiện sau style.css của cha mẹ, thì bạn chỉ cần làm cho nó phụ thuộc vào điều đó.

Bây giờ, nếu bạn cũng có B.css ở trẻ, thì bạn sẽ thiết lập các phụ thuộc tương ứng:

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' );

Làm cho các phụ thuộc mà bạn xác định cho từng mục thực sự phản ánh những gì các phụ thuộc đó thực sự là gì. Nếu main.css phải đến sau B.css, thì nó phụ thuộc vào nó. Nếu B.css phải đến sau style.css của cha mẹ, thì B phụ thuộc vào điều đó. Hệ thống enqueue sẽ sắp xếp nó cho bạn.

Và nếu bạn không thực sự sử dụng style.css của trẻ em cho bất cứ điều gì, thì bạn hoàn toàn không cần phải chinh phục nó . Nó có thể chỉ là một trình giữ chỗ để giữ thông tin tiêu đề của chủ đề của bạn. Không sử dụng nó? Đừng tải nó.

Ngoài ra, chính xác những gì bạn đang làm là rất phụ thuộc vào đặt hàng ở đây? CSS không quan tâm đến thứ tự tải trong hầu hết các tình huống. CSS phụ thuộc nhiều hơn vào tính đặc hiệu của các bộ chọn. Nếu bạn muốn ghi đè lên một cái gì đó, bạn làm cho bộ chọn của bạn cho nó cụ thể hơn. Nó có thể đến trước, hoặc cuối cùng, hoặc bất cứ điều gì ở giữa, bộ chọn cụ thể hơn luôn luôn thắng.

Chỉnh sửa

Đọc bình luận của bạn và nhìn kỹ hơn vào mã, tôi thấy lỗi ở đâu. Mã mười hai mười ba đang ghi lại "get_stylesheet_uri ()", trong trường hợp chủ đề con, sẽ là tệp style.css của chủ đề con bạn, không phải tệp của cha mẹ. Đó là lý do tại sao @import hoạt động và giữ nguyên thứ tự (một lần nữa, không quan trọng nhiều như bạn nghĩ).

Trong trường hợp đó, nếu bạn không muốn sử dụng nhập khẩu, tôi sẽ khuyên bạn nên liệt kê trực tiếp style.css của cha mẹ. Thích như vậy:

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

Mã trong hàm.php của chủ đề con chạy trước, vì vậy wp_enqueue_scripts của riêng bạn sẽ chạy trước và điều này sẽ làm nổi bật style.css của chủ đề phụ, mà chủ đề gốc không tự thực hiện (vì thực sự nó đang mê hoặc style.css của con bạn). Bằng cách không làm cho nó phụ thuộc vào bất cứ điều gì, giống như cha mẹ, sau đó nó chỉ đơn giản được đưa vào đầu ra một cách chính xác. Lưu ý rằng thứ tự của tệp này và genericons.css không quan trọng, vì "kiểu thứ hai mươi" ban đầu không có genericons.css như một phụ thuộc được liệt kê.

Style.css của con bạn sẽ tải, và thành thật mà nói, đây là nơi bạn nên đặt các thay đổi của mình cho chủ đề con chứ không phải vào một main.css riêng biệt. Không có gì ngăn cản bạn đưa các thay đổi của mình vào đó, nhưng không có lý do thực sự để có thêm một tệp css.


Tôi hoàn toàn đồng ý rằng đó @importkhông phải là cách tốt nhất để đi. Vui lòng xem phần "chỉnh sửa" của tôi để biết thêm thông tin chính xác. Tôi không có bất kỳ nhu cầu cụ thể nào về việc đặt hàng css. Tôi chỉ đơn giản là không muốn sửa đổi thứ tự nội bộ của các tệp css của chủ đề gốc có thể gây ra sự cố với ưu tiên quy tắc css.
bernie

Để làm rõ, B.css (hiện đã đổi thành eg.css trong câu hỏi) không phải là một phần của chủ đề con tôi, mà thực sự là một phần của chủ đề chính.
bernie

2
Nếu bạn muốn phong cách của bạn đến sau phong cách eg.css, thì hãy tạo phong cách của riêng bạn phụ thuộc vào nó. Tên của nó là "hai mươi mười hai". Thứ tự hoàn toàn được quản lý bởi những gì phụ thuộc mà bạn khai báo, nhưng một lần nữa, với CSS, thứ tự thực tế của chúng trong tài liệu thường không quan trọng, vì vậy tôi không chắc tại sao bạn lại quan tâm đến nó quá nhiều.
Otto

2
Chỉnh sửa câu trả lời của tôi để bao gồm một cách tiếp cận khác.
Otto

Vâng tôi đoán tôi đã mang đi với "nhu cầu" để giữ trật tự css. Nếu thứ tự thực sự quan trọng đối với chủ đề chính, thì nó phải được nêu trong phần phụ thuộc.
bernie

9

Câu trả lời trước của tôi quá phức tạp và có khả năng không tôn trọng chuỗi phụ thuộc của chủ đề phụ huynh (xem ghi chú trong câu trả lời khác).

Đây là một cách đơn giản hơn nhiều nên hoạt động tốt hơn nhiều:

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);

Ý tưởng là chỉ cần lọc cuộc gọi đến get_stylesheet_uri()trong chủ đề gốc để trả về biểu định kiểu riêng của nó thay vì chủ đề con. Bản định kiểu của chủ đề con sau đó sẽ được ghi lại trong hook hành động my_theme_styles.


Chỉ dành cho bản ghi: 1) Mã của bạn sẽ tạo chính xác html giống như sử dụng @importphiên bản cũ , hoàn toàn không ảnh hưởng đến hiệu suất, sẽ có hai yêu cầu style.css riêng cho máy chủ 2) Câu trả lời này giảm toàn bộ điều phụ thuộc cùng nhau ... 3) Bạn có thể kiểm tra những gì get_template_directory_uriget_template_stylesheet_uriđang làm ở đây: core.trac.wordpress.org/browser/tags/4.8/src/wp-includes/ , Một lần nữa, không cần phần lớn mã đó.
bg17aw

1
@ bg17aw bằng cách sử dụng wp_enqueue_styletự động thêm chuỗi truy vấn phá bộ đệm vào url mà nó tạo (ví dụ ?ver=2013-07-18) dựa trên phiên bản của chủ đề. Điều này không được thực hiện bởi một @importtuyên bố.
bernie

2

cảnh báo

Giải pháp này không tôn trọng sự phụ thuộc của chủ đề phụ huynh ! Thay đổi tên xử lý của chủ đề gốc ảnh hưởng đến chuỗi phụ thuộc được đặt trong chủ đề gốc. Xem câu trả lời đơn giản hơn nhiều của tôi .

câu trả lời gốc

Mặc dù câu trả lời của Otto khá hay, tôi đã kết thúc câu hỏi này trong các chức năng của chủ đề con tôi.

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);

Nó duy trì số style.cssthứ tự và số phiên bản của chủ đề phụ trong khi kiểm soát phiên bản của chủ đề con style.css.


5
Tôi suy nghĩ rằng phần mềm blog phổ biến nhất đòi hỏi hơn 20 dòng mã chỉ để điều chỉnh CSS của một chủ đề hiện có. Tôi đoán đó là bảo mật công việc.
Carl G

Tôi phải đổi [$parentNewHandle]thànharray($parentNewHandle)
Carl G

@CarlG: cú pháp mảng tôi đã sử dụng (ngoặc) được giới thiệu trong PHP 5.4.
bernie

Tovoters: vui lòng xem câu trả lời khác của tôi để giải quyết vấn đề với câu hỏi này.
bernie

Đó là một sự hiểu lầm rất lớn, không cần điều đó. Trong thực tế, @importphương pháp cũ hoạt động tốt như vậy, xin vui lòng so sánh cả hai phương pháp. Đối với sự phụ thuộc của chủ đề con vào chủ đề gốc, cũng không cần điều đó. Con style.cssluôn được tải sau khi cha mẹ, ít nhất là từ các bài kiểm tra của tôi. Yêu để được chứng minh là sai.
bg17aw
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.