Category: WordPress

  • WordPress主題開發筆記:動態修改 Bootstrap 按鈕顏色

    當你在 WordPress 主題中使用 Bootstrap 並希望透過自訂器(Customizer)讓使用者即時調整語意顏色(如 $primary)時,你可能會遇到一個令人困惑的問題:Bootstrap 的按鈕樣式是以 SASS 編譯後的固定值呈現,無法在透過使用bootstrap提供的CSS variables動態修改。

    這篇文章將深入探討這個問題的根源,以及如何用 PHP 解決它,讓 Bootstrap 的 .btn-primary.btn-danger 等語意化按鈕能夠根據使用者設定即時更新。

    問題:Bootstrap 的 SASS 編譯限制

    Bootstrap 使用 SASS 編譯語意化按鈕樣式,像這段程式碼:

    _button.scss

    @each $color, $value in $theme-colors { {
      .btn-#{$color} {
        ...
        @include button-variant($value, $value);
      }
    }
    

    button-variant這個Mixin會將 $theme-colors 中的每個顏色編譯成固定的 CSS,例如.btn-primary

    compiled.css

    .btn-primary {
        --bs-btn-color: #fff;
        --bs-btn-bg: #0d6efd;
        --bs-btn-border-color: #0d6efd;
        --bs-btn-hover-color: #fff;
        --bs-btn-hover-bg: rgb(11.05, 93.5, 215.05);
        --bs-btn-hover-border-color: rgb(10.4, 88, 202.4);
        --bs-btn-focus-shadow-rgb: 49, 132, 253;
        --bs-btn-active-color: #fff;
        --bs-btn-active-bg: rgb(10.4, 88, 202.4);
        --bs-btn-active-border-color: rgb(9.75, 82.5, 189.75);
        --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
        --bs-btn-disabled-color: #fff;
        --bs-btn-disabled-bg: #0d6efd;
        --bs-btn-disabled-border-color: #0d6efd;
    }

    這些值在編譯後就「定型」了,無法透過 WordPress 的 get_theme_mod() 或 CSS 變數在前端動態修改。

    原因:SASS 無法處理 CSS 變數

    你可能會想:「那我把 $primary 改成 var(--bs-primary) 不就好了?」但 SASS會報錯:

    Code

    Error: $color2: var(--bs-primary) is not a color.
    

    因為 button-variant 使用的色碼算法需要實際的色碼來進行運算(例如 shade-color()mix()),而 var(--bs-primary) 只是字串,無法參與這些函式。

    解決方案:用 PHP 動態產生 CSS覆蓋Boostrap CSS

    我們可以在 WordPress 中使用 PHP 根據 get_theme_mod() 的值動態產生 CSS,並透過 wp_add_inline_style() 注入到 Bootstrap 的樣式表中。

    步驟如下:

    1. 在 Customizer 中註冊每個語意化顏色設定,例如 theme_color_primary
    2. functions.php 中撰寫一個函式,根據這些設定值計算 hover、active、disabled 狀態的顏色。
    3. 使用 wp_add_inline_style() 將產生的 CSS 注入到 Bootstrap 的樣式表。

    範例輸出:

    css

    .btn-primary {
      --bs-btn-bg: #ff5722;
      --bs-btn-border-color: #ff5722;
      --bs-btn-color: #fff;
      --bs-btn-hover-bg: #e64a19;
      --bs-btn-hover-border-color: #e64a19;
      --bs-btn-hover-color: #fff;
      --bs-btn-active-bg: #d84315;
      --bs-btn-active-border-color: #d84315;
      --bs-btn-active-color: #fff;
      --bs-btn-disabled-bg: #ff5722;
      --bs-btn-disabled-border-color: #ff5722;
      --bs-btn-disabled-color: #fff;
    }
    

    這些 CSS 變數會覆蓋 Bootstrap 原本的樣式,讓按鈕顏色能夠根據使用者設定即時更新。

    有相同問題的 class 包括:

    .btn-#{$color}
    .btn-outline-#{$color}
    .link-#{$color}

    注意事項:Bootstrap 未來可能變更 SASS 函式

    目前我們使用 PHP 模擬 Bootstrap 的 button-variant SASS mixin,並根據 WordPress 自訂器的設定值動態產生 CSS。這種做法雖然有效,但本質上是一種 繞道(workaround)

    值得注意的是,Bootstrap 的 SASS 結構與函式(例如 shade-color()color-contrast()mix())在未來版本中可能會有所調整。

    因此,如果 Bootstrap 更新了這些函式的邏輯或變數命名,你的 PHP 生成函式可能需要同步更新,以確保樣式輸出仍然正確。

    希望未來的改進

    理想情況下,Bootstrap 能在未來版本中提供更完整的 CSS 變數支援,讓我們不必透過 PHP 模擬 SASS 的邏輯,而是直接在前端以 CSS 變數覆蓋樣式。這將大幅簡化 WordPress 主題的自訂流程,並提升相容性與維護性。