From 37a799b2cb44cd8df08311cb7db203f05ecb8458 Mon Sep 17 00:00:00 2001 From: Cell <1024@lruihao.cn> Date: Fri, 26 Dec 2025 14:16:59 +0800 Subject: [PATCH] refactor: use CSS variables for global colors and improve theme support (#668) --- .github/copilot-instructions.md | 8 +- assets/css/_core/_base.scss | 9 +- assets/css/_core/_breadcrumb.scss | 6 +- assets/css/_core/_header.scss | 15 +-- assets/css/_core/_root.scss | 2 + assets/css/_page/_single.scss | 3 +- assets/css/_partials/_archive/_tags.scss | 6 +- assets/css/_partials/_details.scss | 2 + assets/css/_partials/_single/_code.scss | 1 + .../_partials/_single/_fixit-decryptor.scss | 9 +- assets/css/_partials/_single/_reward.scss | 6 +- assets/css/_partials/_single/_toc.scss | 22 ++-- .../_partials/_widgets/_cookieconsent.scss | 12 +-- .../css/_partials/_widgets/_fixed-button.scss | 18 ++-- assets/css/_shortcodes/_cardlink.scss | 6 +- assets/css/_shortcodes/_tabs.scss | 100 +++++------------- assets/css/_shortcodes/_timeline.scss | 6 +- assets/css/_variables.scss | 1 + 18 files changed, 69 insertions(+), 163 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 28687d8a..3f9492a3 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -79,15 +79,11 @@ FixIt/ ### 样式组织原则 -1. **主题切换支持**: 使用数据属性选择器 +1. **主题切换支持**: 使用 CSS 变量实现主题切换 ```scss .element { - color: $global-font-color; - - [data-theme='dark'] & { - color: $global-font-color-dark; - } + color: var(#{$rootPrefix}global-font-color); } ``` diff --git a/assets/css/_core/_base.scss b/assets/css/_core/_base.scss index 91420c7e..4bec533e 100644 --- a/assets/css/_core/_base.scss +++ b/assets/css/_core/_base.scss @@ -26,14 +26,9 @@ html { } body { - background-color: $global-background-color; - color: $global-font-color; + background-color: var(#{$rootPrefix}global-background-color); + color: var(#{$rootPrefix}global-font-color); @include overflow-wrap(break-word); - - [data-theme='dark'] & { - color: $global-font-color-dark; - background-color: $global-background-color-dark; - } } iframe { diff --git a/assets/css/_core/_breadcrumb.scss b/assets/css/_core/_breadcrumb.scss index 1f509812..e7493bc1 100644 --- a/assets/css/_core/_breadcrumb.scss +++ b/assets/css/_core/_breadcrumb.scss @@ -1,7 +1,7 @@ .breadcrumb-container { padding-inline: 1rem; font-size: 0.75rem; - background-color: $global-background-color; + background-color: var(#{$rootPrefix}global-background-color); display: flex; gap: 0.5rem; @include z-index(1); @@ -18,10 +18,6 @@ padding-inline: 0.5rem; } - [data-theme='dark'] & { - background-color: $global-background-color-dark; - } - &.sticky { position: sticky; top: $header-height; diff --git a/assets/css/_core/_header.scss b/assets/css/_core/_header.scss index 2742ba30..7553be2d 100644 --- a/assets/css/_core/_header.scss +++ b/assets/css/_core/_header.scss @@ -77,11 +77,7 @@ header { .dropdown-icon { margin-left: 0.25rem; font-size: .875em; - color: $global-font-color; - - [data-theme='dark'] & { - color: $global-font-color-dark; - } + color: var(#{$rootPrefix}global-font-color); &.open::before { content: "\f078"; @@ -160,14 +156,13 @@ header { .open &, &.mobile { input { - color: $global-font-color; + color: var(#{$rootPrefix}global-font-color); background-color: $search-background-color; padding: 0 2rem 0 2rem; } [data-theme='dark'] & { input { - color: $global-font-color-dark; background-color: $search-background-color-dark; } @@ -549,11 +544,7 @@ header { .dropdown-menu { right: 0 !important; - background-color: $global-background-color; - - [data-theme='dark'] & { - background-color: $global-background-color-dark; - } + background-color: var(#{$rootPrefix}global-background-color); .suggestions { overflow-y: auto; diff --git a/assets/css/_core/_root.scss b/assets/css/_core/_root.scss index d6addc92..e462629b 100644 --- a/assets/css/_core/_root.scss +++ b/assets/css/_core/_root.scss @@ -5,6 +5,7 @@ interpolate-size: allow-keywords; // Global colors variables + #{$rootPrefix}global-background-color: #{$global-background-color}; #{$rootPrefix}global-font-color: #{$global-font-color}; #{$rootPrefix}global-font-secondary-color: #{$global-font-secondary-color}; #{$rootPrefix}global-border-color: #{$global-border-color}; @@ -45,6 +46,7 @@ // Dark theme [data-theme=dark] { + #{$rootPrefix}global-background-color: #{$global-background-color-dark}; #{$rootPrefix}global-font-color: #{$global-font-color-dark}; #{$rootPrefix}global-font-secondary-color: #{$global-font-secondary-color-dark}; #{$rootPrefix}global-border-color: #{$global-border-color-dark}; diff --git a/assets/css/_page/_single.scss b/assets/css/_page/_single.scss index 425c4251..fb8536bb 100644 --- a/assets/css/_page/_single.scss +++ b/assets/css/_page/_single.scss @@ -460,7 +460,7 @@ kbd { display: inline-block; padding: 0 0.25rem; - background-color: $global-background-color; + background-color: var(#{$rootPrefix}global-background-color); border: 1px solid $global-border-color; font-size: 0.8rem; font-family: $code-font-family; @@ -469,7 +469,6 @@ @include box-shadow(inset 0 -1px 0 $global-border-color); [data-theme='dark'] & { - background-color: $global-background-color-dark; border: 1px solid $global-border-color-dark; color: $code-color-dark; @include box-shadow(inset 0 -1px 0 $global-border-color-dark); diff --git a/assets/css/_partials/_archive/_tags.scss b/assets/css/_partials/_archive/_tags.scss index 97f0c0b8..9f3aa1ba 100644 --- a/assets/css/_partials/_archive/_tags.scss +++ b/assets/css/_partials/_archive/_tags.scss @@ -14,12 +14,8 @@ @include transform(scale(1.2)); sup { - color: $global-font-color; + color: var(#{$rootPrefix}global-font-color); @include transition(all ease-out 0.3s); - - [data-theme='dark'] & { - color: $global-font-color-dark; - } } } diff --git a/assets/css/_partials/_details.scss b/assets/css/_partials/_details.scss index 43777eab..38e34120 100644 --- a/assets/css/_partials/_details.scss +++ b/assets/css/_partials/_details.scss @@ -1,6 +1,7 @@ .details { > .details-summary { @include border-radius($global-border-radius); + @include transition(border-radius 0.2s ease 0.2s); &:hover { cursor: pointer; @@ -21,6 +22,7 @@ &.open { > .details-summary { @include border-radius($global-border-radius $global-border-radius 0 0); + @include transition(border-radius 0s); i.details-icon { @include transform(rotate(90deg)); diff --git a/assets/css/_partials/_single/_code.scss b/assets/css/_partials/_single/_code.scss index 7da9ff3e..0775680b 100644 --- a/assets/css/_partials/_single/_code.scss +++ b/assets/css/_partials/_single/_code.scss @@ -259,6 +259,7 @@ pre { $code-background-color 100% ); @include z-index(0, 1); + @include border-radius(0 0 $global-border-radius $global-border-radius); [data-theme='dark'] & { background: linear-gradient( diff --git a/assets/css/_partials/_single/_fixit-decryptor.scss b/assets/css/_partials/_single/_fixit-decryptor.scss index 0f503a02..f91e7b55 100644 --- a/assets/css/_partials/_single/_fixit-decryptor.scss +++ b/assets/css/_partials/_single/_fixit-decryptor.scss @@ -13,7 +13,7 @@ display: none; box-sizing: border-box; outline: none; - color: $global-font-color; + color: var(#{$rootPrefix}global-font-color); border: 1px solid darken($global-border-color, 15%); border-radius: $global-border-radius; @include transition(all 0.1s ease-out); @@ -33,7 +33,6 @@ } [data-theme='dark'] & { - color: $global-font-color-dark; border-color: lighten($global-border-color-dark, 15%); box-shadow: 0px 0px 5px 0px lighten($global-border-color-dark, 15%); } @@ -44,11 +43,7 @@ height: 3rem; padding-left: 1rem; padding-right: 1rem; - background-color: $global-background-color; - - [data-theme='dark'] & { - background-color: $global-background-color-dark; - } + background-color: var(#{$rootPrefix}global-background-color); } .fixit-decryptor-btn, diff --git a/assets/css/_partials/_single/_reward.scss b/assets/css/_partials/_single/_reward.scss index 457bea74..d44c7071 100644 --- a/assets/css/_partials/_single/_reward.scss +++ b/assets/css/_partials/_single/_reward.scss @@ -49,13 +49,12 @@ left: 50%; transform: translate(-50%, -50%); padding: 1rem; - background-color: $global-background-color; + background-color: var(#{$rootPrefix}global-background-color); @include z-index(2); @include border-radius($global-border-radius); @include box-shadow(0 0 1.5rem 0 rgba(0, 0, 0, 0.2)); [data-theme='dark'] & { - background-color: $global-background-color-dark; @include box-shadow(0 0 1.5rem 0 rgba(255, 255, 255, 0.2)); } } @@ -70,7 +69,7 @@ border: 2px solid lighten($reward-color, 10%); border-radius: $global-border-radius; padding: 0.6rem 1rem; - background-color: $global-background-color; + background-color: var(#{$rootPrefix}global-background-color); vertical-align: text-top; line-height: 1rem; @include transition(all 0.3s ease-out); @@ -91,7 +90,6 @@ [data-theme='dark'] & { color: $reward-color; border-color: lighten($reward-color, 5%); - background-color: $global-background-color-dark; } } } diff --git a/assets/css/_partials/_single/_toc.scss b/assets/css/_partials/_single/_toc.scss index a15006c9..199aeb2d 100644 --- a/assets/css/_partials/_single/_toc.scss +++ b/assets/css/_partials/_single/_toc.scss @@ -196,15 +196,11 @@ justify-content: space-between; line-height: 2em; padding: 0 0.75em; - background: darken($code-background-color, 3%); - - [data-theme='dark'] & { - background: darken($code-background-color-dark, 6%); - } + background-color: var(#{$rootPrefix}code-header-background-color); } .toc-content { - background-color: $code-background-color; + background-color: var(#{$rootPrefix}code-block-background-color); > nav { > ul { @@ -232,18 +228,14 @@ } } } - - [data-theme='dark'] & { - background-color: $code-background-color-dark; - } } - &.open { + &:not(.open) { .toc-title { - background: darken($code-background-color, 6%); + #{$rootPrefix}code-header-background-color: #{darken($code-background-color, 6%)}; [data-theme='dark'] & { - background: darken($code-background-color-dark, 3%); + #{$rootPrefix}code-header-background-color: #{darken($code-background-color-dark, 6%)}; } } } @@ -257,13 +249,14 @@ opacity 0.2s 0.4s; opacity: 0; translate: 100vw 0; - width: MIN(calc(100% - 4rem), 500px); + width: MIN(calc(100% - 4rem), 460px); height: 100%; max-width: 100%; max-height: 100%; margin-right: 0; border: none; border-left: 1px solid var(#{$rootPrefix}global-border-color); + background-color: var(#{$rootPrefix}global-background-color); .toc { max-width: 100%; @@ -286,6 +279,7 @@ } &::backdrop { + background-color: rgba(0, 0, 0, 0.4); transition: display 0.5s allow-discrete, overlay 0.5s allow-discrete, diff --git a/assets/css/_partials/_widgets/_cookieconsent.scss b/assets/css/_partials/_widgets/_cookieconsent.scss index c15c7133..58ad5802 100644 --- a/assets/css/_partials/_widgets/_cookieconsent.scss +++ b/assets/css/_partials/_widgets/_cookieconsent.scss @@ -1,18 +1,14 @@ .cc-window.cc-banner { .cc-btn { - color: $global-font-color; + color: var(#{$rootPrefix}global-font-color); + background-color: var(#{$rootPrefix}global-background-color); &:hover, &:focus { background-color: #ccc; - } - [data-theme='dark'] & { - color: $global-font-color; - - &:hover, - &:focus { - background-color: #fff; + [data-theme='dark'] & { + background-color: #444; } } } diff --git a/assets/css/_partials/_widgets/_fixed-button.scss b/assets/css/_partials/_widgets/_fixed-button.scss index 2b8dcb68..081b1792 100644 --- a/assets/css/_partials/_widgets/_fixed-button.scss +++ b/assets/css/_partials/_widgets/_fixed-button.scss @@ -12,6 +12,7 @@ font-size: 1rem; line-height: 1.5rem; padding: 0.5rem 0.625rem; + // TODO color: darken($global-font-secondary-color, 10%); background-color: $header-background-color; @include border-radius(1.25rem); @@ -19,9 +20,14 @@ @include blur; @extend .print-d-none; + [data-theme='dark'] & { + color: $global-font-secondary-color-dark; + background-color: $header-background-color-dark; + } + &:hover, &:active { - color: $global-font-color; + color: var(#{$rootPrefix}global-font-color); cursor: pointer; } @@ -30,16 +36,6 @@ &:hover { outline: none; } - - [data-theme='dark'] & { - color: $global-font-secondary-color-dark; - background-color: $header-background-color-dark; - - &:hover, - &:active { - color: $global-font-color-dark; - } - } } .back-to-top { diff --git a/assets/css/_shortcodes/_cardlink.scss b/assets/css/_shortcodes/_cardlink.scss index 6b987370..48863858 100644 --- a/assets/css/_shortcodes/_cardlink.scss +++ b/assets/css/_shortcodes/_cardlink.scss @@ -53,7 +53,7 @@ font-size: 1rem; font-weight: 500; line-height: 1.25; - color: $global-font-color; + color: var(#{$rootPrefix}global-font-color); } &meta { @@ -105,9 +105,5 @@ &content { background-color: rgba(61, 62, 65, 0.88); } - - &title { - color: $global-font-color-dark; - } } } diff --git a/assets/css/_shortcodes/_tabs.scss b/assets/css/_shortcodes/_tabs.scss index 3b764882..cf274b5e 100644 --- a/assets/css/_shortcodes/_tabs.scss +++ b/assets/css/_shortcodes/_tabs.scss @@ -3,11 +3,11 @@ // ======================================== @mixin tab-button-size($padding-inline: 1.25rem, $padding-block: 0.75rem) { - @if $padding-inline !=0 { + @if $padding-inline != 0 { padding-inline: $padding-inline; } - @if $padding-block !=0 { + @if $padding-block != 0 { padding-block: $padding-block; } } @@ -107,22 +107,14 @@ tab-container { // Clean, minimal with bottom border // ======================================== &[type='underline'] { - &::part(tablist-tab-wrapper) { - --border-color: #{$global-border-color}; - - [data-theme='dark'] & { - --border-color: #{$global-border-color-dark}; - } - } - > .tab-button { - --border-color: transparent; + #{$rootPrefix}tab-button-border-color: transparent; @include tab-button-size(0); &[aria-selected='true'], &[aria-selected='false']:hover { color: var(#{$rootPrefix}primary); - --border-color: var(#{$rootPrefix}primary); + #{$rootPrefix}tab-button-border-color: var(#{$rootPrefix}primary); } &[aria-selected='false']:hover { @@ -154,50 +146,50 @@ tab-container { // Top placement &[placement='top'] { &::part(tablist-tab-wrapper) { - border-bottom: 2px solid var(--border-color); + border-bottom: 2px solid var(#{$rootPrefix}global-border-color); } > .tab-button { translate: 0 2px; - border-bottom: 2px solid var(--border-color); + border-bottom: 2px solid var(#{$rootPrefix}tab-button-border-color); } } // Bottom placement &[placement='bottom'] { &::part(tablist-tab-wrapper) { - border-top: 2px solid var(--border-color); + border-top: 2px solid var(#{$rootPrefix}global-border-color); } > .tab-button { translate: 0 -2px; - border-top: 2px solid var(--border-color); + border-top: 2px solid var(#{$rootPrefix}tab-button-border-color); } } // Left placement &[placement='left'] { &::part(tablist-tab-wrapper) { - border-right: 2px solid var(--border-color); + border-right: 2px solid var(#{$rootPrefix}global-border-color); } > .tab-button { text-align: right; translate: 2px 0; - border-right: 2px solid var(--border-color); + border-right: 2px solid var(#{$rootPrefix}tab-button-border-color); } } // Right placement &[placement='right'] { &::part(tablist-tab-wrapper) { - border-left: 2px solid var(--border-color); + border-left: 2px solid var(#{$rootPrefix}global-border-color); } > .tab-button { text-align: left; translate: -2px 0; - border-left: 2px solid var(--border-color); + border-left: 2px solid var(#{$rootPrefix}tab-button-border-color); } } } @@ -305,62 +297,27 @@ tab-container { &[type='card'] { gap: 0; - &::part(tablist-tab-wrapper) { - --border-color: #{$global-border-color}; - - [data-theme='dark'] & { - --border-color: #{$global-border-color-dark}; - } - } - &::part(tablist) { gap: 0.25rem; } > .tab-button { - border: 1px solid $global-border-color; - background: $code-background-color; + border: 1px solid var(#{$rootPrefix}global-border-color); + background-color: var(#{$rootPrefix}code-block-background-color); @include tab-button-size(1.5rem); - [data-theme='dark'] & { - border-color: $global-border-color-dark; - background: $code-background-color-dark; - } - - &[aria-selected='true'] { - background: $global-background-color; - color: $global-link-color; - z-index: 1; - --border-active-color: #{$global-background-color}; - - [data-theme='dark'] & { - background: $global-background-color-dark; - color: $global-link-color-dark; - --border-active-color: #{$global-background-color-dark}; - } - } - + &[aria-selected='true'], &[aria-selected='false']:hover { - background: $global-background-color; - color: $global-link-color; + background-color: var(#{$rootPrefix}global-background-color); + color: var(#{$rootPrefix}global-link-color); z-index: 1; - - [data-theme='dark'] & { - background: $global-background-color-dark; - color: $global-link-color-dark; - } } } > .tab-panel { padding: 0.75rem; - background: $global-background-color; - border: 1px solid $global-border-color; - - [data-theme='dark'] & { - background: $global-background-color-dark; - border-color: $global-border-color-dark; - } + background-color: var(#{$rootPrefix}global-background-color); + border: 1px solid var(#{$rootPrefix}global-border-color); } &[placement='top'], @@ -388,7 +345,7 @@ tab-container { // Top placement &[placement='top'] { &::part(tablist-tab-wrapper) { - border-bottom: 1px solid var(--border-color); + border-bottom: 1px solid var(#{$rootPrefix}global-border-color); } > .tab-button { @@ -396,7 +353,7 @@ tab-container { @include border-radius($global-border-radius $global-border-radius 0 0); &[aria-selected='true'] { - border-bottom-color: var(--border-active-color); + border-bottom-color: var(#{$rootPrefix}global-background-color); } } @@ -409,7 +366,7 @@ tab-container { // Bottom placement &[placement='bottom'] { &::part(tablist-tab-wrapper) { - border-top: 1px solid var(--border-color); + border-top: 1px solid var(#{$rootPrefix}global-border-color); } > .tab-button { @@ -417,7 +374,7 @@ tab-container { @include border-radius(0 0 $global-border-radius $global-border-radius); &[aria-selected='true'] { - border-top-color: var(--border-active-color); + border-top-color: var(#{$rootPrefix}global-background-color); } } @@ -430,7 +387,7 @@ tab-container { // Left placement &[placement='left'] { &::part(tablist-tab-wrapper) { - border-right: 1px solid var(--border-color); + border-right: 1px solid var(#{$rootPrefix}global-border-color); } > .tab-button { @@ -438,7 +395,7 @@ tab-container { @include border-radius($global-border-radius 0 0 $global-border-radius); &[aria-selected='true'] { - border-right-color: var(--border-active-color); + border-right-color: var(#{$rootPrefix}global-background-color); } } @@ -451,7 +408,7 @@ tab-container { // Right placement &[placement='right'] { &::part(tablist-tab-wrapper) { - border-left: 1px solid var(--border-color); + border-left: 1px solid var(#{$rootPrefix}global-border-color); } > .tab-button { @@ -459,7 +416,7 @@ tab-container { @include border-radius(0 $global-border-radius $global-border-radius 0); &[aria-selected='true'] { - border-left-color: var(--border-active-color); + border-left-color: var(#{$rootPrefix}global-background-color); } } @@ -507,11 +464,10 @@ tab-container { } &[aria-selected='true'] { - background: $global-background-color; + background-color: var(#{$rootPrefix}global-background-color); @include box-shadow(0 0.125rem 0.25rem rgba(0, 0, 0, 0.1)); [data-theme='dark'] & { - background: $global-background-color-dark; @include box-shadow(0 0.125rem 0.25rem rgba(255, 255, 255, 0.1)); } } diff --git a/assets/css/_shortcodes/_timeline.scss b/assets/css/_shortcodes/_timeline.scss index 216ddf35..b7b5c840 100644 --- a/assets/css/_shortcodes/_timeline.scss +++ b/assets/css/_shortcodes/_timeline.scss @@ -83,13 +83,9 @@ border-width: var(--timeline-width); border-style: solid; border-color: var(--timeline-circle-color); - background-color: $global-background-color; + background-color: var(#{$rootPrefix}global-background-color); color: transparent; z-index: 1; - - [data-theme='dark'] & { - background-color: $global-background-color-dark; - } } &::after { content: ''; diff --git a/assets/css/_variables.scss b/assets/css/_variables.scss index afe2b231..ac10ffa7 100644 --- a/assets/css/_variables.scss +++ b/assets/css/_variables.scss @@ -1,5 +1,6 @@ // ============================== // Variables +// TODO refactor variables // ============================== // ========== Global ========== //