# Design Document: Global UI Optimization ## Overview 本设计文档描述 Argon WordPress 主题的全局 UI 优化方案,参考 Apple Human Interface Guidelines 和 Material Design 3 设计规范。优化重点包括:按钮样式现代化、设置面板重构、分享按钮动画增强、评论展开动画优化,以及新增多种设计风格选项。 ## Architecture ### 设计系统架构 ``` ┌─────────────────────────────────────────────────────────────┐ │ CSS Variables Layer │ │ (动画时长、缓动函数、颜色、圆角、阴影等设计令牌) │ ├─────────────────────────────────────────────────────────────┤ │ Base Components Layer │ │ (按钮、卡片、输入框等基础组件样式) │ ├─────────────────────────────────────────────────────────────┤ │ Feature Components Layer │ │ (设置面板、分享按钮、评论切换等功能组件) │ ├─────────────────────────────────────────────────────────────┤ │ Theme Variants Layer │ │ (玻璃拟态、新拟态、Material 3 等主题变体) │ └─────────────────────────────────────────────────────────────┘ ``` ### 文件结构 ``` style.css # 主样式文件(修改) argontheme.js # 主脚本文件(修改) functions.php # 主函数文件(修改 - 添加邮件模板函数) settings.php # 设置页面(修改 - 添加邮件模板设置) template-parts/ └── post-actions.php # 文章操作按钮模板(修改) email-templates/ └── base.php # 邮件基础模板(新增) └── comment-notify.php # 评论通知模板(新增) └── reply-notify.php # 回复通知模板(新增) ``` ## Components and Interfaces ### 1. 动画系统 CSS 变量 ```css :root { /* 动画时长 */ --animation-fast: 150ms; --animation-normal: 250ms; --animation-slow: 400ms; --animation-slower: 600ms; /* 缓动函数 - Material 3 标准 */ --ease-standard: cubic-bezier(0.2, 0, 0, 1); --ease-standard-decelerate: cubic-bezier(0, 0, 0, 1); --ease-standard-accelerate: cubic-bezier(0.3, 0, 1, 1); --ease-emphasized: cubic-bezier(0.2, 0, 0, 1); --ease-emphasized-decelerate: cubic-bezier(0.05, 0.7, 0.1, 1); --ease-emphasized-accelerate: cubic-bezier(0.3, 0, 0.8, 0.15); /* 弹性缓动 */ --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1); --ease-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55); /* 状态层透明度 - Material 3 */ --state-hover-opacity: 0.08; --state-focus-opacity: 0.12; --state-pressed-opacity: 0.12; --state-dragged-opacity: 0.16; } ``` ### 2. 按钮组件设计 #### 主要按钮 (Filled Button) ```css .btn-primary { background-color: var(--themecolor); border: none; border-radius: var(--card-radius); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); transition: background-color var(--animation-fast) var(--ease-standard), box-shadow var(--animation-fast) var(--ease-standard), transform var(--animation-fast) var(--ease-standard); position: relative; overflow: hidden; } .btn-primary:hover { background-color: var(--themecolor-dark); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15); } .btn-primary:active { background-color: var(--themecolor-dark2); transform: scale(0.98); } ``` #### 涟漪效果 (Ripple Effect) ```css .btn-ripple { position: relative; overflow: hidden; } .btn-ripple::after { content: ''; position: absolute; width: 100%; height: 100%; top: 0; left: 0; pointer-events: none; background-image: radial-gradient(circle, rgba(255,255,255,0.3) 10%, transparent 10.01%); background-repeat: no-repeat; background-position: 50%; transform: scale(10, 10); opacity: 0; transition: transform var(--animation-slow), opacity var(--animation-normal); } .btn-ripple:active::after { transform: scale(0, 0); opacity: 1; transition: 0s; } ``` ### 3. 设置面板设计 #### 面板容器 ```css #fabtn_blog_settings_popup { background: var(--color-foreground); border-radius: 16px; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12), 0 2px 8px rgba(0, 0, 0, 0.08); padding: 16px 20px; backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); } ``` #### 分组卡片布局 设计决策:使用分组卡片将相关设置项组织在一起,提升视觉层次和可读性。 ```css .settings-group { background: var(--color-background); border-radius: 12px; padding: 12px 16px; margin-bottom: 12px; } .settings-group-title { font-size: 12px; font-weight: 600; color: var(--color-text-light); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 8px; } .settings-item { display: flex; justify-content: space-between; align-items: center; padding: 8px 0; } .settings-item + .settings-item { border-top: 1px solid var(--color-border-light); } ``` #### 分段控件 (Segmented Control) ```css .segmented-control { display: inline-flex; background: var(--color-widgets-disabled); border-radius: 10px; padding: 3px; gap: 2px; } .segmented-control-item { padding: 6px 14px; border-radius: 8px; border: none; background: transparent; color: var(--color-text-deeper); font-size: 13px; font-weight: 500; cursor: pointer; transition: all var(--animation-fast) var(--ease-standard); } .segmented-control-item.active { background: var(--themecolor); color: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15); } ``` ### 4. 分享按钮动画设计 #### 容器样式 ```css #share_container { position: relative; display: inline-flex; align-items: center; } #share { display: flex; gap: 6px; position: absolute; right: 0; top: 50%; transform: translateY(-50%); opacity: 0; pointer-events: none; } #share > a { opacity: 0; transform: scale(0.8) translateX(10px); } ``` #### 展开动画 ```css #share_container.opened #share { opacity: 1; pointer-events: auto; } #share_container.opened #share > a { opacity: 1; transform: scale(1) translateX(0); transition: opacity var(--animation-normal) var(--ease-emphasized-decelerate), transform var(--animation-normal) var(--ease-spring); } /* 错落动画延迟 */ #share_container.opened #share > a:nth-child(1) { transition-delay: 0ms; } #share_container.opened #share > a:nth-child(2) { transition-delay: 30ms; } #share_container.opened #share > a:nth-child(3) { transition-delay: 60ms; } #share_container.opened #share > a:nth-child(4) { transition-delay: 90ms; } #share_container.opened #share > a:nth-child(5) { transition-delay: 120ms; } #share_container.opened #share > a:nth-child(6) { transition-delay: 150ms; } #share_container.opened #share > a:nth-child(7) { transition-delay: 180ms; } #share_container.opened #share > a:nth-child(8) { transition-delay: 210ms; } ``` #### 主按钮变换 ```css #share_show { transition: transform var(--animation-normal) var(--ease-standard), opacity var(--animation-normal) var(--ease-standard); } #share_container.opened #share_show { transform: rotate(45deg) scale(0.9); opacity: 0.7; } ``` #### 点击外部收起逻辑 设计决策:使用事件委托监听 document 点击事件,判断点击目标是否在分享容器外部。 ```javascript // 点击外部收起分享面板 document.addEventListener('click', function(e) { const shareContainer = document.getElementById('share_container'); if (shareContainer && shareContainer.classList.contains('opened')) { // 检查点击目标是否在分享容器外部 if (!shareContainer.contains(e.target)) { shareContainer.classList.remove('opened'); } } }); ``` ### 5. 评论展开动画设计 #### 评论区容器 ```css #comments, #post_comment { transition: max-height var(--animation-slow) var(--ease-emphasized), opacity var(--animation-normal) var(--ease-standard), margin var(--animation-slow) var(--ease-standard), padding var(--animation-slow) var(--ease-standard); overflow: hidden; will-change: max-height, opacity; } #comments.comments-collapsed, #post_comment.comments-collapsed { max-height: 0 !important; opacity: 0; margin-top: 0 !important; margin-bottom: 0 !important; padding-top: 0 !important; padding-bottom: 0 !important; border: none !important; } #comments:not(.comments-collapsed), #post_comment:not(.comments-collapsed) { max-height: 9999px; opacity: 1; } ``` #### 切换按钮图标动画 ```css #comments_toggle .btn-inner--icon i { transition: transform var(--animation-normal) var(--ease-spring); } #comments_toggle.expanded .btn-inner--icon i { transform: rotate(180deg); } ``` #### 折叠反向动画 设计决策:折叠动画使用与展开相同的过渡属性,CSS transition 会自动处理反向动画。通过调整缓动函数实现自然的收起效果。 ```css /* 折叠状态 - 使用 accelerate 缓动使收起更自然 */ #comments.comments-collapsed, #post_comment.comments-collapsed { transition: max-height var(--animation-slow) var(--ease-emphasized-accelerate), opacity var(--animation-fast) var(--ease-standard-accelerate), margin var(--animation-slow) var(--ease-standard), padding var(--animation-slow) var(--ease-standard); } ``` ### 6. 主题变体设计 #### 悬停效果增强 设计决策:为所有可交互元素添加统一的悬停效果,使用微妙的缩放和阴影变化提升交互反馈。 ```css /* 通用悬停效果 */ .card:hover, .btn:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.06); transition: transform var(--animation-fast) var(--ease-standard), box-shadow var(--animation-fast) var(--ease-standard); } /* 可点击元素的微缩放效果 */ .clickable:hover { transform: scale(1.02); } .clickable:active { transform: scale(0.98); } ``` #### 玻璃拟态 (Glassmorphism) ```css html.style-glass .card, html.style-glass #fabtn_blog_settings_popup { background: rgba(255, 255, 255, 0.7); backdrop-filter: blur(20px) saturate(180%); -webkit-backdrop-filter: blur(20px) saturate(180%); border: 1px solid rgba(255, 255, 255, 0.3); } html.darkmode.style-glass .card, html.darkmode.style-glass #fabtn_blog_settings_popup { background: rgba(66, 66, 66, 0.7); border: 1px solid rgba(255, 255, 255, 0.1); } ``` #### 新拟态 (Neumorphism) ```css html.style-neumorphism .card { background: var(--color-background); box-shadow: 8px 8px 16px rgba(0, 0, 0, 0.1), -8px -8px 16px rgba(255, 255, 255, 0.8); border: none; } html.darkmode.style-neumorphism .card { box-shadow: 8px 8px 16px rgba(0, 0, 0, 0.3), -8px -8px 16px rgba(255, 255, 255, 0.05); } ``` #### Material 3 动态色彩系统 设计决策:实现 Material 3 的动态色彩系统,根据主题色自动生成协调的色彩方案。使用 CSS 变量和 HSL 色彩空间实现动态计算。 ```css :root { /* Material 3 色彩角色 - 基于主题色动态生成 */ --md-primary: var(--themecolor); --md-on-primary: #ffffff; --md-primary-container: var(--themecolor-light); --md-on-primary-container: var(--themecolor-dark2); /* 表面色彩 */ --md-surface: var(--color-background); --md-surface-variant: var(--color-foreground); --md-on-surface: var(--color-text); --md-on-surface-variant: var(--color-text-light); /* 轮廓色彩 */ --md-outline: var(--color-border); --md-outline-variant: var(--color-border-light); } /* Material 3 风格组件 */ html.style-material3 .card { background: var(--md-surface); border-radius: 16px; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); } html.style-material3 .btn-primary { background: var(--md-primary); color: var(--md-on-primary); border-radius: 20px; font-weight: 500; letter-spacing: 0.1px; } html.style-material3 .btn-primary:hover { box-shadow: 0 2px 4px rgba(0, 0, 0, 0.14), 0 3px 4px rgba(0, 0, 0, 0.12); } ``` ```javascript // Material 3 动态色彩生成函数 function generateMaterial3Colors(primaryColor) { // 将主题色转换为 HSL const hsl = hexToHSL(primaryColor); return { primary: primaryColor, primaryContainer: hslToHex(hsl.h, Math.max(hsl.s - 20, 0), Math.min(hsl.l + 30, 95)), onPrimary: hsl.l > 50 ? '#000000' : '#ffffff', onPrimaryContainer: hslToHex(hsl.h, hsl.s, Math.max(hsl.l - 40, 10)) }; } ``` ## Data Models ### 设置存储结构 ```javascript // localStorage 存储的设置项 { 'Argon_UI_Style': 'default' | 'glass' | 'neumorphism' | 'material3', 'Argon_Animation_Reduced': 'true' | 'false', 'Argon_Use_Serif': 'true' | 'false', 'Argon_Use_Big_Shadow': 'true' | 'false', 'Argon_Filter': 'off' | 'sunset' | 'darkness' | 'grayscale' } ``` ### 邮件模板设置结构 ```php // WordPress 选项存储的邮件模板设置 [ 'argon_email_theme_color' => '#5e72e4', // 主题色 'argon_email_logo_url' => '', // Logo 图片 URL 'argon_email_blog_name' => get_bloginfo('name'), // 博客名称 'argon_email_footer_text' => '', // 页脚版权信息 'argon_email_social_links' => [ // 社交链接 'twitter' => '', 'github' => '', 'weibo' => '' ] ] ``` ### 7. 邮件模板系统设计 #### 设计决策 - 使用内联 CSS 确保邮件客户端兼容性(邮件客户端不支持外部样式表) - 采用表格布局保证跨客户端一致性(Outlook 等客户端对 div 布局支持有限) - 提供简洁的后台设置界面,仅暴露必要的自定义选项 #### 模板基础结构 ```html
{{#if logo_url}} {{blog_name}} {{else}}

{{blog_name}}

{{/if}}
{{content}}
{{#if social_links}}

{{#each social_links}} {{this.name}} {{/each}}

{{/if}}

{{footer_text}}

``` #### 评论通知邮件内容模板 ```html

您的文章收到了新评论

{{commenter_name}} 在《{{post_title}}》中发表了评论:

{{comment_content}}

查看评论 ``` #### 评论回复通知邮件内容模板 ```html

您的评论收到了回复

您在《{{post_title}}》的评论:

{{original_comment}}

{{replier_name}} 回复了您:

{{reply_content}}

查看回复 ``` #### 后台设置界面 ```php // 邮件模板设置区域 - 添加到 settings.php function argon_email_settings_section() { // 主题色选择器 add_settings_field('argon_email_theme_color', '邮件主题色', ...); // Logo 上传 add_settings_field('argon_email_logo_url', '邮件 Logo', ...); // 博客名称(默认使用站点名称) add_settings_field('argon_email_blog_name', '邮件显示名称', ...); // 页脚文本 add_settings_field('argon_email_footer_text', '页脚版权信息', ...); // 社交链接 add_settings_field('argon_email_social_links', '社交链接', ...); // 预览按钮 add_settings_field('argon_email_preview', '邮件预览', ...); } ``` #### 邮件预览功能 ```javascript // AJAX 预览邮件 function previewEmail(type) { fetch(ajaxurl, { method: 'POST', body: new URLSearchParams({ action: 'argon_preview_email', type: type, // 'comment' | 'reply' nonce: argon_email_nonce }) }) .then(res => res.text()) .then(html => { // 在模态框中显示预览 openPreviewModal(html); }); } ``` #### PHP 邮件发送函数 ```php /** * 发送统一格式的邮件 * @param string $to 收件人 * @param string $subject 主题 * @param string $content 内容 HTML * @param string $type 邮件类型 */ function argon_send_email($to, $subject, $content, $type = 'general') { $template = argon_get_email_template(); $settings = argon_get_email_settings(); // 替换模板变量 $html = str_replace([ '{{theme_color}}', '{{logo_url}}', '{{blog_name}}', '{{footer_text}}', '{{content}}' ], [ $settings['theme_color'], $settings['logo_url'], $settings['blog_name'], $settings['footer_text'], $content ], $template); // 设置邮件头 $headers = [ 'Content-Type: text/html; charset=UTF-8', 'From: ' . $settings['blog_name'] . ' <' . get_option('admin_email') . '>' ]; return wp_mail($to, $subject, $html, $headers); } ``` ## Correctness Properties *A property is a characteristic or behavior that should hold true across all valid executions of a system—essentially, a formal statement about what the system should do. Properties serve as the bridge between human-readable specifications and machine-verifiable correctness guarantees.* ### Property 1: 按钮使用纯色背景 *For any* 主要按钮元素(.btn-primary, #share .btn, #comments_toggle),其 background 属性应该使用纯色(var(--themecolor) 或具体颜色值),而不包含 gradient 关键字。 **Validates: Requirements 1.1, 3.6** ### Property 2: 组件使用主题色 CSS 变量 *For any* 使用主题色的组件(按钮、选中状态、链接等),其颜色相关属性应该使用 var(--themecolor) 或其派生变量(--themecolor-dark, --themecolor-light 等),而非硬编码的颜色值。 **Validates: Requirements 1.4, 2.3** ### Property 3: 动画系统 CSS 变量定义 *For any* 动画相关的 CSS 变量,:root 选择器中应该定义 --animation-fast, --animation-normal, --animation-slow 时长变量,以及 --ease-standard, --ease-emphasized, --ease-spring 等缓动函数变量。 **Validates: Requirements 5.1, 5.2** ### Property 4: 分享按钮错落动画延迟 *For any* 分享按钮容器中的子元素(#share > a),每个元素应该有递增的 transition-delay 值,形成错落有致的动画效果。 **Validates: Requirements 3.2** ### Property 5: 评论区过渡动画属性 *For any* 评论区容器(#comments, #post_comment),其 transition 属性应该包含 max-height 和 opacity,并使用 CSS 变量定义的动画时长。 **Validates: Requirements 4.1, 4.2, 4.4** ### Property 6: GPU 加速动画属性 *For any* 交互动画(悬停、点击、展开/收起),应该主要使用 transform 和 opacity 属性进行动画,而非 width, height, top, left 等触发重排的属性。 **Validates: Requirements 5.3** ### Property 7: 样式切换过渡动画 *For any* 主要容器元素(.card, #fabtn_blog_settings_popup),应该定义 transition 属性覆盖 background-color 和 box-shadow 的变化,以支持样式切换时的平滑过渡。 **Validates: Requirements 6.4** ### Property 8: 点击外部收起分享面板 *For any* 处于展开状态的分享面板,当用户点击分享容器外部区域时,分享面板应该收起(移除 .opened 类)。 **Validates: Requirements 3.5** ### Property 9: 悬停效果使用 transform 和 box-shadow *For any* 可交互元素(.card, .btn)的悬停状态,应该使用 transform(如 translateY 或 scale)和 box-shadow 属性实现视觉反馈,而非改变元素尺寸或位置属性。 **Validates: Requirements 5.5** ### Property 10: Material 3 色彩变量定义 *For any* 启用 Material 3 样式的页面,:root 选择器中应该定义 --md-primary, --md-surface, --md-on-primary 等 Material 3 色彩角色变量。 **Validates: Requirements 6.3** ### Property 11: 邮件模板统一结构 *For any* 发送的邮件(评论通知、回复通知等),其 HTML 结构应该包含页眉(logo/博客名)、内容区、页脚(版权信息)三个区域,且使用相同的基础模板。 **Validates: Requirements 7.1** ### Property 12: 邮件模板主题色应用 *For any* 邮件模板中的主题色元素(按钮背景、链接颜色、边框强调色),应该使用后台设置的 argon_email_theme_color 值,而非硬编码颜色。 **Validates: Requirements 7.2** ### Property 13: 邮件模板内联样式 *For any* 邮件模板的 HTML 输出,所有样式应该以内联方式(style 属性)应用,不依赖外部 CSS 文件或 `