子比主题开发文档
使用指南Codestar Framework主题扩展在线部署AI 功能推荐插件赞助打赏

主题样式、背景与模式切换

梳理子比主题全局主题色、背景图、页面背景、布局宽度、导航页脚颜色、日夜间模式和前台样式扩展边界。

模块边界

子比主题的全局视觉配置不是一组散落 CSS,而是“后台配置字段 + wp_head 动态 CSS + body 模式 class + 前端切换脚本”的组合。开发时要先判断需求属于哪一层:

层级负责内容典型入口
主题后台配置全局主题色、背景图、布局宽度、圆角、导航页脚颜色、日夜间模式inc/options/admin-options.php
页面独立配置页面最大宽度、页面背景、页面内容样式inc/options/metabox-options.php
动态 CSS 输出CSS 变量、全局背景、页面背景、暗黑模式变量、导航页脚变量inc/functions/zib-head.php
模式判断读取默认模式、用户 Cookie、时间自动切换、body classinc/functions/zib-theme.php
前端切换点击 .toggle-theme,切换 body class、Cookie、图片和代码高亮主题js/main.js

因此不要把“改主题色”理解为只改一个 CSS 文件。主题色、背景、暗黑模式、图片资源、代码高亮和编辑器预览都会被这套链路影响。

核心文件

文件作用
inc/options/admin-options.php注册全局布局、主题模式、背景、主题色、圆角、导航颜色、页脚颜色
inc/options/metabox-options.php注册页面独立宽度和页面背景
inc/functions/zib-head.php输出 meta theme-color、CSS 变量、页面背景和全局背景
inc/functions/zib-theme.php判断当前模式、输出 body class、按模式筛选图片、给 TinyMCE 加模式 class
inc/functions/zib-header.php在 PC 导航和移动菜单输出主题切换按钮
inc/functions/zib-footer.php右侧浮动按钮可输出主题切换入口,并按模式选择代码高亮主题
js/main.js处理 .toggle-theme 点击、View Transition 动画、Cookie 和资源切换

后台配置字段

常见全局视觉字段如下:

配置项作用
layout_max_width默认页面布局最大宽度,后台最小值 1200
theme_mode默认主题风格,支持 white-themedark-themetime-auto
theme_mode_button主题切换按钮显示位置,默认 PC 顶部导航和移动菜单
theme_img_bg全局日间背景图和背景色
dark_theme_img_bg全局夜间背景图和背景色
theme_skin_custom自定义全局主题高亮色
theme_skin预置主题高亮色,只有自定义色为空时生效
dark_theme_skin_custom夜间模式单独主题高亮色
close_backdrop全局关闭背景高斯模糊
theme_main_radius页面卡片圆角尺寸
header_theme_custom是否启用自定义导航栏颜色
header_theme_bg_custom / header_theme_bg导航栏自定义背景色或预置背景
header_theme_color_custom导航栏文字颜色
footer_theme_custom是否启用自定义页脚颜色
footer_theme_bg_custom / footer_theme_bg页脚自定义背景色或预置背景
footer_theme_color_custom页脚文字颜色

页面独立配置由 inc/options/metabox-options.php 注册:

页面 Meta作用
layout_max_width当前页面最大宽度,0 表示跟随全局
layout_bg.img_white当前页面日间背景
layout_bg.img_dark当前页面夜间背景

页面背景优先级高于全局背景。只要页面配置里有背景相关值,zib_head_css_layout_bg() 会先输出页面背景并直接返回,不再继续输出全局背景。

CSS 变量输出

zib_head_css() 会把主题设置转成 CSS 变量写到页面 head:

function zib_head_css()
{
    $styles = '';

    $color = '';
    if (_pz('theme_skin')) {
        $color = _pz('theme_skin');
    }

    if (_pz('theme_skin_custom')) {
        $color = substr(_pz('theme_skin_custom'), 1);
    }

    $var   = '';
    $color = $color ?: 'f04494';
    $var .= '--theme-color:#' . $color . ';';
    $var .= '--focus-shadow-color:' . hex_to_rgba('#' . $color, '.4') . ';';
    $var .= '--focus-color-opacity1:' . hex_to_rgba('#' . $color, '.1') . ';';
    $var .= '--focus-color-opacity05:' . hex_to_rgba('#' . $color, '.05') . ';';
    $var .= '--focus-color-opacity3:' . hex_to_rgba('#' . $color, '.3') . ';';
    $var .= '--focus-color-opacity6:' . hex_to_rgba('#' . $color, '.6') . ';';

    $styles .= 'body{' . $var . '}';

    if ($styles) {
        echo '<style>' . $styles . '</style>';
    }
}

常用变量:

变量用途
--theme-color主题高亮色
--focus-shadow-color聚焦阴影颜色
--focus-color-opacity05 / 1 / 3 / 6主题色不同透明度
--main-radius全局圆角
--posts-card-scale卡片列表缩略图比例
--posts-list-scale列表模式缩略图比例
--single-cover-scale文章封面比例
--mian-max-width页面最大宽度,主题源码里变量名就是 mian
--header-bg / --header-color导航栏背景和文字
--footer-bg / --footer-color页脚背景和文字

扩展样式时优先使用这些变量。不要把按钮、卡片、弹窗、导航和用户中心写死成固定颜色,否则日间、夜间和用户自定义主题色会断开。

主题色优先级

全局主题色的读取顺序:

  1. theme_skin 预置色。
  2. theme_skin_custom 自定义色覆盖预置色。
  3. 都为空时使用默认 f04494

夜间模式如果配置了 dark_theme_skin_custom,会额外输出:

body.dark-theme{
    --theme-color:#...;
    --focus-shadow-color:...;
    --focus-color-opacity1:...;
}

这意味着扩展组件应该写成:

.docs-action {
  color: var(--focus-color);
  background: var(--focus-color-opacity1);
  box-shadow: 0 0 0 3px var(--focus-shadow-color);
}

不要写成:

.docs-action {
  color: #f04494;
}

固定色只适合品牌 Logo、支付平台图标、状态色等确实不应跟随主题色变化的元素。

布局宽度

全局宽度来自 _pz('layout_max_width', 1200),页面可以通过 Meta 覆盖:

function zib_get_page_max_width()
{
    $max_width = _pz('layout_max_width', 1200);
    if (is_page()) {
        global $post;
        $post_id     = $post->ID ?? 0;
        $p_max_width = (int) zib_get_post_meta($post_id, 'layout_max_width', 0);
        if ($p_max_width && $p_max_width > 1200) {
            $max_width = $p_max_width;
        }
    }

    if ($max_width < 1200) {
        $max_width = 1200;
    }

    return apply_filters('page_max_width', $max_width . 'px');
}

自定义页面需要更宽时,用过滤器处理明确页面,不要全局覆盖容器:

function zib_docs_custom_dashboard_width($width)
{
    if (!is_page_template('pages/custom-dashboard.php')) {
        return $width;
    }

    return '1480px';
}
add_filter('page_max_width', 'zib_docs_custom_dashboard_width');

主题会把结果输出到 --mian-max-width。扩展 CSS 时要使用主题现有容器和变量,而不是重新写一个全站 .container { max-width: ... }

全局背景与页面背景

全局背景来自:

_pz('theme_img_bg');
_pz('dark_theme_img_bg');

页面背景来自:

zib_get_post_meta($post_id, 'layout_bg', true);

zib_head_css_layout_bg() 的顺序是:

  1. 如果当前是页面,先读取页面 layout_bg
  2. 页面有日间或夜间背景时,输出页面背景。
  3. 页面背景存在时直接返回,不继续读全局背景。
  4. 页面没有背景时,才输出全局 theme_img_bgdark_theme_img_bg

字段结构保留 Codestar background 字段格式:

array(
    'background-color'      => '',
    'background-image'      => '',
    'background-position'   => 'center top',
    'background-repeat'     => 'no-repeat',
    'background-attachment' => 'fixed',
    'background-size'       => '100%',
    'background-origin'     => '',
)

扩展页面背景时不要另起一个自定义字段再单独输出 CSS。优先复用 layout_bg,这样日间、夜间、页面配置和全局回退能保持一致。

日夜间模式

当前模式由 zib_get_theme_mode() 判断:

function zib_get_theme_mode()
{
    $theme_mode = _pz('theme_mode');
    if (_pz('theme_mode_button', true) && isset($_COOKIE['theme_mode'])) {
        $theme_mode = $_COOKIE['theme_mode'];
    } else {
        $time = current_time('G');
        if ('time-auto' == $theme_mode) {
            if ($time >= 20 || $time < 8) {
                $theme_mode = 'dark-theme';
            } else {
                $theme_mode = 'white-theme';
            }
        }
    }
    return apply_filters('zib_theme_mode', $theme_mode);
}

关键点:

规则说明
后台默认值theme_mode 可以是日间、夜间、早晚 8 点自动
用户优先只要启用切换按钮并存在 theme_mode Cookie,就优先使用用户选择
body class_bodyclass() 会把当前模式追加到 body class
编辑器TinyMCE 的 body class 也会追加当前模式
可过滤zib_theme_mode 可以覆盖最终模式

如果某个页面必须固定夜间模式,可以用过滤器处理:

function zib_docs_force_dark_theme($theme_mode)
{
    if (!is_page_template('pages/custom-showcase.php')) {
        return $theme_mode;
    }

    return 'dark-theme';
}
add_filter('zib_theme_mode', 'zib_docs_force_dark_theme');

这会影响 body class、meta theme-color、自适应图片和编辑器预览,比只给 body 写一个额外 class 更完整。

切换按钮与前端动画

按钮位置来自:

function zib_get_theme_mode_button_positions()
{
    return (array) apply_filters('zib_theme_mode_button_positions', (array) _pz('theme_mode_button', array('pc_nav', 'm_menu')));
}

PC 顶部导航和移动菜单会输出:

<a href="javascript:;" class="toggle-theme toggle-radius"><i class="fa fa-toggle-theme"></i></a>

js/main.js 监听 .toggle-theme。浏览器支持 View Transition API 时,主题会用点击位置做圆形扩散动画;不支持时直接切换。切换时会同步处理:

内容前端行为
body class增减 dark-theme
HTML class增减 document.documentElement.classListdark
Cookie写入 theme_mode=dark-themewhite-theme
meta theme-color切换为 #2F3135#FDFCFE
自适应图片替换 white-src / dark-src
旧式切换图片替换 switch-src
代码高亮切换 Enlighter 亮色/暗色主题 class
TinyMCE给编辑器 body 增减 dark-theme

新增主题切换入口时不要重新写 JS,输出 .toggle-theme 即可:

function zib_docs_append_theme_toggle($html, $user_id)
{
    $html .= '<a href="javascript:;" class="toggle-theme toggle-radius ml10"><i class="fa fa-toggle-theme"></i></a>';

    return $html;
}
add_filter('zib_nav_radius_button', 'zib_docs_append_theme_toggle', 30, 2);

如果只是调整按钮显示位置,优先过滤 zib_theme_mode_button_positions

function zib_docs_theme_button_positions($positions)
{
    if (is_page_template('pages/custom-fullscreen.php')) {
        return array();
    }

    return $positions;
}
add_filter('zib_theme_mode_button_positions', 'zib_docs_theme_button_positions');

自适应图片

日夜间不同图片用 zib_get_adaptive_theme_img()

function zib_get_adaptive_theme_img($white_src = '', $dark_src = '', $alt = '', $more = '', $lazy = 'auto')
{
    if (!$dark_src) {
        $dark_src = $white_src;
    }

    if (!$white_src) {
        $white_src = $dark_src;
    }

    $this_src = zib_get_theme_mode() == 'dark-theme' ? $dark_src : $white_src;
    $img      = '<img src="' . $this_src . '" white-src="' . $white_src . '" dark-src="' . $dark_src . '" alt="' . $alt . '" ' . $more . '>';

    return $img;
}

它会输出 white-srcdark-src,前端切换主题时会自动换图。适合 Logo、登录页图片、图标插画、强调背景等需要适配亮暗主题的资源。

示例:

function zib_docs_get_adaptive_logo()
{
    $white_src = _pz('logo_src');
    $dark_src  = _pz('logo_src_dark');

    return zib_get_adaptive_theme_img($white_src, $dark_src, get_bloginfo('name'), 'class="docs-logo"');
}

不要只在 CSS 里用 display:none 切两张图片。主题已有的切换脚本会处理 white-src / dark-src,复用它能减少闪烁和重复逻辑。

导航栏与页脚颜色

导航颜色开启 header_theme_custom 后,会输出:

$styles .= '.header{--header-bg:' . $h_bg . ';--header-color:' . $h_c . ';}';

页脚颜色开启 footer_theme_custom 后,会输出:

$styles .= 'body,body.dark-theme{--footer-bg:' . $h_bg . ';--footer-color:' . $h_c . ';}';

主题对导航和页脚使用变量控制,因此扩展导航按钮、下拉菜单、页脚组件时应继承这些变量:

.docs-footer-link {
  color: var(--footer-color);
}

.docs-header-action {
  color: var(--header-color);
  background: var(--header-bg);
}

如果在导航里新增按钮,仍然优先走 zib_nav_radius_buttonzib_menu_button() 或菜单 Walker,而不是在模板里手写一套固定颜色的导航块。

自定义 CSS 的边界

主题后台有 csscodezib_head_css() 会直接追加到 head:

if (_pz('csscode')) {
    $styles .= _pz('csscode');
}

开发时尽量不要把复杂业务样式都塞进 csscode。更稳妥的方式是:

场景推荐做法
少量运营样式后台 csscode
可复用模块样式插件或子主题 enqueue 独立 CSS
只影响一个页面页面模板或页面条件下 enqueue
需要跟随主题色使用 CSS 变量
需要暗黑模式body.dark-theme 或依赖变量

页面级样式示例:

function zib_docs_enqueue_showcase_style()
{
    if (!is_page_template('pages/custom-showcase.php')) {
        return;
    }

    wp_enqueue_style(
        'zib_docs_showcase',
        get_stylesheet_directory_uri() . '/assets/showcase.css',
        array(),
        '1.0.0'
    );
}
add_action('wp_enqueue_scripts', 'zib_docs_enqueue_showcase_style');

CSS 示例:

.docs-showcase {
  border-radius: var(--main-radius);
  background: var(--main-bg-color);
  color: var(--main-color);
  border: 1px solid var(--main-border-color);
}

.docs-showcase .docs-primary {
  color: var(--focus-color);
  background: var(--focus-color-opacity1);
}

常见风险

风险说明
写死颜色会破坏主题色、夜间模式和用户自定义配色
覆盖全站容器容易影响首页、文章页、商城、论坛、用户中心和移动端布局
绕过 layout_bg页面背景、全局背景和夜间背景回退会不一致
只切 body class图片、代码高亮、meta theme-color、TinyMCE 可能不同步
背景图过大固定背景和大图会增加移动端滚动负担
导航背景和文字对比不足主题已给前景色字段,扩展时也要检查可读性
滥用 csscode配置迁移和版本维护困难,也不利于按页面加载
忽略 Cookie 优先级用户主动切换主题后,会覆盖后台默认模式

调试入口

现象优先检查
主题色不生效theme_skin_custom 是否覆盖 theme_skin,页面是否缓存旧 head
夜间主题色不变dark_theme_skin_custom 是否为空,body 是否有 dark-theme
背景图不显示页面 layout_bg 是否覆盖全局,图片 URL 是否有效,CSS 是否被缓存
页面宽度不变页面 Meta layout_max_widthpage_max_width 过滤器、--mian-max-width
切换按钮不显示theme_mode_buttonzib_theme_mode_button_positions、导航或移动菜单位置
点击切换无效.toggle-theme 是否保留,main.js 是否加载,Cookie 是否被浏览器限制
图片未跟随切换是否使用 white-src / dark-src,或 switch-src 是否正确
代码高亮主题不切换highlight_kghighlight_white_zthighlight_dark_zt、Enlighter class

参考源码

本页根据 inc/options/admin-options.phpinc/options/metabox-options.phpinc/functions/zib-head.phpinc/functions/zib-theme.phpinc/functions/zib-header.phpinc/functions/zib-footer.phpjs/main.js,以及子比主题官网公开的全局背景图和主题颜色教程蒸馏整理。

On this page