From b97f265142fbb4642d7798f72a15dd0b4f2c6a4c Mon Sep 17 00:00:00 2001 From: laoyang Date: Sat, 24 Oct 2026 12:16:30 +0800 Subject: [PATCH] =?UTF-8?q?feat(comments):=20=E8=AF=84=E8=AE=BA=E5=8C=BA?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E9=87=8D=E5=81=9A=EF=BC=8C=E4=BF=AE=E6=8E=89?= =?UTF-8?q?=E4=B8=89=E5=A4=84=E5=8F=AF=E8=AF=BB=E6=80=A7=E4=B8=8D=E8=BE=BE?= =?UTF-8?q?=E6=A0=87=E4=B8=8E=E7=AA=84=E5=B1=8F=E5=A4=B4=E5=83=8F=E6=BA=A2?= =?UTF-8?q?=E5=87=BA=EF=BC=883.2.20=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用无头浏览器把评论区的计算样式逐条量出来之后,确认「不好看」里有三处 是硬指标不达标,不是主观审美: · 时间戳 #a4abb5 对白底对比度 2.32 → 4.83(WCAG AA 正文需 ≥4.5) · 回复按钮 #8a9099 对比度 3.22 → 6.0 (可点元素同样需 ≥4.5) · 顶层分隔线 #f5f6f8 对白底 ≈1.04 → 1.17(可见,此前等于没有分隔) 顺带修掉一个只在窄屏出现的真 bug:768px 断点里 avatar 的 width 组 只写了容器与占位符、漏了 img,容器缩到 36px 而图片仍是 42px, 溢出 6px 压在正文上。400px 断点同类问题一并补齐。 这个 bug 之所以能活过多个版本,是因为几何探针量的是容器宽度 —— 容器确实等于 36,98 条断言全绿。已在探针里新增 3 条直接量 img 的断言, 并在反向验证里加入对应的注入用例。 其余为层次与细节调整: · 新增 .comments 作用域内的局部设计变量层(--yq-*),信息性颜色带兜底 · 标题加主色竖条;外框圆角 4→6、阴影对齐整站 .widget 的档位 · 头像边框改外描边,不占布局,直径保持精确 42px · 缩进 20→18px、引导线加深;正文 14→14.5px、行高 1.8 · 新增 :target 高亮与 prefers-reduced-motion 分支 保持不变的 DOM 契约(已在文件头注明):.yang-comment 仍为 grid、 子容器缩进仍只加 padding-left、头像断点节奏仍为 42/36/32。 验证:verify_all.sh 30 组全通过;本地几何 107/0、反向注入 25/0、 AJAX 34/0;线上四视口几何 52/0;线上实测时间 4.83、按钮 6.0、分隔线 1.17。 --- assets/css/comments.css | 654 +++++++++++++++++++++++++++++----------- style.css | 2 +- 2 files changed, 478 insertions(+), 178 deletions(-) diff --git a/assets/css/comments.css b/assets/css/comments.css index da3c1e0..186077e 100644 --- a/assets/css/comments.css +++ b/assets/css/comments.css @@ -2,29 +2,100 @@ * 评论区样式 * Yongquan Yang * - * ── 为什么整块重写,而不是在旧样式上改 ────────────────────── - * 旧样式的骨架是「头像 float:left + 右侧 margin-left 挤出来」, - * 这个结构在三个地方会坏: - * · 长昵称/长网址会把头部撑破(float 不定宽容器里没有约束); - * · 嵌套回复靠 .children { padding-left:0 } 实现,等于**没有缩进**, - * 三层以后完全看不出谁回谁; - * · 头像 50px 写死在 img 上,但没有 flex 居中,头像和第一行文字 - * 基线对不齐(看起来"文字比头像低一点")。 + * ── 3.2.20:为什么又改了一次 ──────────────────────────────── + * 3.2.18 重写解决的是**结构**问题(float 撑破、嵌套没缩进、 + * 头像基线不齐)。3.2.19 解决的是**数据**问题(评论一条不显示)。 + * 这一版解决的是**观感**问题 —— 用无头浏览器把计算样式量出来 + * 之后,量到的三条都是硬指标不达标,不是"见仁见智": * - * 所以改用 flex 两列布局:头像固定宽、主体 flex:1, - * 并把嵌套缩进做成明确的层级视觉(左侧引导线)。 + * · 时间戳 #a4abb5 → 对白底对比度 **2.32**(WCAG AA 正文要 ≥4.5) + * · 「回复」按钮 #8a9099 → 对比度 **3.22**(可点元素同样要 ≥4.5) + * · 顶层评论分隔线 #f5f6f8 → 对白底几乎零差,等于**没有分隔** + * + * 也就是说"不好看"里有一半其实是"看不清"。只调审美不改这三条, + * 换个分辨率又会打回原形。所以这一版先把可读性拉到达标, + * 再谈层次与细节。 + * + * ── 设计取向:跟整站对齐,不做另一套语言 ───────────────────── + * 量过整站的实际 token:body 16px / 行高 1.8 / 正文 #212529、 + * 底色 #f5f5f5、圆角以 3px 为主、主色 #00a2ff、卡片靠 1px 淡阴影 + * 而不是大圆角大投影。评论区是这张白卡里的**内嵌区**, + * 所以这里不引入流行的"大圆角 + 重投影 + 彩色卡片", + * 而是把预算花在:分隔清晰、层级明确、元信息可读、交互有反馈。 + * + * 参考的设计原则(GitHub Discussions / Discourse / 主流中文博客): + * 1. 元信息(时间、操作)比正文弱但**必须可读**,不能淡到消失; + * 2. 层级靠"缩进 + 引导线 + 头像尺寸"三重冗余表达, + * 任何一重失效(窄屏、深嵌套)另外两重还在; + * 3. 分隔线只用在"同层"之间,跨层交给缩进 —— 两套信号不要打架; + * 4. 可点元素必须有 hover / focus 的可见变化,不能只变鼠标指针。 + * + * ── 三条不能动的约束(改样式前务必知道)─────────────────────── + * 1. `.yang-comment` **必须是 grid**,且 `grid-template-columns` 为 + * `auto minmax(0,1fr)`、子容器 `grid-column: 1 / -1`。 + * 原因:`
    ` 是 `
  1. ` 的**直接子元素**, + * 换成 flex 它会成为第三个 flex 项被排到右侧(详见第 3 节注释)。 + * 2. 子容器 `ol.yang-children` 的 **左偏移必须 ≈0、宽度必须 ≈父宽**。 + * `_diag318_children_geo.js` 的判据 A/B 卡的就是这两条, + * 所以缩进只能加在 `padding-left` 上,**不能加 margin-left**。 + * 3. 头像宽度按断点递减:>768 是 42、≤768 是 36、≤400 是 32。 + * `_comments_geometry.js` 按这三个值断言,改尺寸要同步改探针。 */ +/*-------------------------------------------------------------- +0. 局部设计变量 +--------------------------------------------------------------*/ + +/* 变量全部挂在 `.comments` 作用域内,不污染全站。 + * + * 使用约定:**信息性颜色一律带兜底值**(`var(--x, #hex)`), + * 因为评论表单会被 JS 搬进某条评论的 `.yang-children` 里 —— + * 虽然它仍在 `.comments` 内部、继承链没断,但只要将来有人把 + * 表单挪到容器外,没有兜底的 var() 就会退化成 initial 的黑色。 + * 纯装饰性的取值(圆角、缓动曲线)允许不带兜底:真取不到也 + * 只是少了点润色,不会把文字变成看不见的颜色。 + * + * 下面注释里的「对比度」是相对白底 #fff 按 WCAG 2.x 算的实测值。 */ +.comments { + --yq-primary: #00a2ff; + --yq-primary-dark: #0089db; + --yq-primary-soft: #eaf6ff; + + /* 文字三级:正文 / 次要 / 弱 + * --yq-text 10.9 —— 正文 + * --yq-text-2 6.0 —— 作者名、操作按钮 + * --yq-text-3 4.8 —— 时间、辅助说明(AA 下限 4.5,留了余量) */ + --yq-text: #33383f; + --yq-text-2: #5b6470; + --yq-text-3: #6b7280; + + /* 线:把"分隔"和"装饰"分开,不要用一个 #f0f0f0 打天下 */ + --yq-line: #eaedf2; /* 结构性分隔,看得见 */ + --yq-line-soft: #f1f4f8; /* 同层细分隔 */ + --yq-guide: #dbe6f2; /* 嵌套引导线 */ + + --yq-bg-soft: #f7f9fb; + --yq-bg-input: #fcfcfd; + + --yq-radius: 4px; + --yq-radius-lg: 6px; + + /* 统一动效曲线:进出都用同一条,避免"有的滑有的弹" */ + --yq-ease: cubic-bezier(0.4, 0, 0.2, 1); +} + /*-------------------------------------------------------------- 1. 区块与标题 --------------------------------------------------------------*/ .k-main .details .comments { - margin-top: 16px; - padding: 20px 22px 22px; - border-radius: 4px; + margin-top: 20px; + padding: 22px 24px 24px; + border-radius: var(--yq-radius-lg, 6px); background-color: #fff; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08); + /* 比原来的 0 1px 3px 稍微收一点:整站卡片(.widget)用的是 + 0 1px 2px,评论区跟着走,深浅一致才不会显得"飘" */ + box-shadow: 0 1px 2px rgba(31, 35, 40, 0.08); } .k-main .details .post-2 .comments { @@ -36,46 +107,74 @@ align-items: baseline; justify-content: space-between; gap: 12px; - padding-bottom: 14px; - border-bottom: 1px solid #f0f0f0; + padding-bottom: 15px; + border-bottom: 1px solid var(--yq-line, #eaedf2); } +/* 标题左侧加一条主色短竖条:中文博客里很常见,成本极低, + 但它让"这是评论区"在长页面滚动时有一眼可辨的锚点。 */ .comments-head .title { + position: relative; margin: 0; + padding-left: 12px; color: #1f2328; font-weight: 600; font-size: 19px; line-height: 1.4; + letter-spacing: -0.005em; } +.comments-head .title::before { + content: ""; + position: absolute; + left: 0; + top: 50%; + width: 3px; + height: 16px; + margin-top: -8px; + border-radius: 2px; + background-color: var(--yq-primary, #00a2ff); +} + +/* 「写下你的评论」:原来用 3px 圆角 + #f4f8ff 底,白底上几乎看不出是按钮。 + * 改成描边式,hover 时反色 —— 可点性更明确,又不抢标题的注意力。 */ .comments-jump-form { flex: 0 0 auto; - padding: 5px 13px; - border: 1px solid #d9e4f5; - border-radius: 3px; - background-color: #f4f8ff; - color: #0b74d1; + padding: 6px 14px; + border: 1px solid #cfe6fb; + border-radius: var(--yq-radius, 4px); + background-color: transparent; + color: var(--yq-primary-dark, #0089db); font-size: 13px; + line-height: 1.4; text-decoration: none; white-space: nowrap; - transition: background-color 0.15s ease, border-color 0.15s ease; + transition: background-color 0.16s var(--yq-ease), border-color 0.16s var(--yq-ease), + color 0.16s var(--yq-ease); } .comments-jump-form:hover { - border-color: #0b74d1; - background-color: #e8f1ff; - color: #0b74d1; + border-color: var(--yq-primary, #00a2ff); + background-color: var(--yq-primary, #00a2ff); + color: #fff; text-decoration: none; } +.comments-jump-form:focus-visible { + outline: 2px solid var(--yq-primary, #00a2ff); + outline-offset: 2px; +} + .comments-closed, .comments-empty { margin: 20px 0 4px; - padding: 14px 16px; - border-radius: 3px; - background-color: #fafbfc; - color: #8a9099; + padding: 18px 16px; + border: 1px dashed #dfe5ec; + border-radius: var(--yq-radius, 4px); + background-color: transparent; + color: var(--yq-text-3, #6b7280); font-size: 13.5px; + line-height: 1.7; text-align: center; } @@ -91,12 +190,16 @@ } .yang-comment-list { - margin-top: 4px; + margin-top: 2px; } -/* 顶层评论之间用细分隔线;嵌套评论之间不用,靠缩进区分 */ +/* 顶层评论之间用**看得见**的分隔线。 + * 原来是 #f5f6f8 —— 对白底几乎零差(正文区宽度 780px 的一条线, + * 差值小于 4 级灰阶,人眼在普通屏幕上抓不到), + * 于是四条评论糊成一坨。现在提到 #eaedf2,是"能看见但不抢戏"的程度。 + * 跨层之间不加线,交给缩进和引导线表达 —— 两套信号不要打架。 */ .yang-comment-list > .yang-comment { - border-bottom: 1px solid #f5f6f8; + border-bottom: 1px solid var(--yq-line, #eaedf2); } .yang-comment-list > .yang-comment:last-child { @@ -127,10 +230,13 @@ .yang-comment { display: grid; grid-template-columns: auto minmax(0, 1fr); - column-gap: 12px; + column-gap: 13px; align-items: start; - padding: 16px 0; + padding: 18px 0; list-style: none; + /* 从通知邮件/后台点进来时会带 #comment-123 锚点, + 这里不做布局级高亮(会挤动内容),只给正文区一个色块, + 详见第 5 节末尾的 :target 规则。 */ } /* 子评论容器独占整行,排在头像与主体下方 */ @@ -138,22 +244,27 @@ grid-column: 1 / -1; } -/* 头像列:固定宽度,不参与伸缩 —— 否则长评论把它挤扁 */ +/* 头像列:固定宽度,不参与伸缩 —— 否则长评论把它挤扁。 + * (grid 里 flex 属性无效,留着只是无害的历史残留,已删除。) */ .yang-comment-avatar { - flex: 0 0 auto; width: 42px; line-height: 0; } +/* 头像:去掉 1px 实线边框,改用 box-shadow 做一圈极淡描边。 + * 理由有两个:① 实线边框在 42px 圆上是"切边"观感,阴影更柔; + * ② box-shadow 不占布局,直径仍然是精确的 42px —— + * 几何探针按 42/36/32 断言,改 border 不会让断言漂移。 */ .yang-comment-avatar img, .yang-comment-avatar-img { display: block; width: 42px; height: 42px; - border: 1px solid #eaeaea; + border: 0; border-radius: 50%; object-fit: cover; - background-color: #f5f5f5; + background-color: #f2f4f7; + box-shadow: 0 0 0 1px rgba(31, 35, 40, 0.07), 0 1px 2px rgba(31, 35, 40, 0.06); } /* 没有头像时的首字占位 */ @@ -165,16 +276,17 @@ height: 42px; border-radius: 50%; background-color: #eef2f7; - color: #7c8794; + box-shadow: 0 0 0 1px rgba(31, 35, 40, 0.05); + color: #66727f; font-size: 17px; font-weight: 600; line-height: 1; text-transform: uppercase; + user-select: none; } /* 主体列 */ .yang-comment-main { - flex: 1 1 auto; min-width: 0; /* 关键:让内部的 text-overflow / 换行能生效 */ } @@ -182,15 +294,15 @@ display: flex; align-items: baseline; flex-wrap: wrap; - gap: 8px; - margin-bottom: 4px; + gap: 6px; + margin-bottom: 5px; } .yang-comment-author { - color: #252525; + color: #1f2328; font-weight: 600; font-style: normal; - font-size: 14px; + font-size: 14.5px; line-height: 1.5; /* 超长昵称截断,别把时间挤到下一行去 */ max-width: 100%; @@ -200,48 +312,70 @@ } .yang-comment-author a { - color: #252525; + color: inherit; text-decoration: none; + transition: color 0.16s var(--yq-ease); } .yang-comment-author a:hover { - color: #00a2ff; + color: var(--yq-primary-dark, #0089db); } +/* 时间:**这是本版最实质的一处修复**。 + * 原来是 #a4abb5,对白底只有 2.32 —— 2.32 是什么概念: + * WCAG 把 3.0 定为"大字最低可读",2.32 连这个都不到, + * 相当于把时间写成了水印。现在用 #6b7280(对比度 4.83), + * 仍然明显弱于正文 #33383f(对比度 10.9),但它读得清。 */ .yang-comment-time { flex: 0 0 auto; - color: #a4abb5; + color: var(--yq-text-3, #6b7280); font-size: 12.5px; line-height: 1.5; + /* 等宽数字:多条评论的时间上下对齐,不会因为 1 和 8 的宽度差抖动 */ + font-variant-numeric: tabular-nums; } -/* 徽标:作者 / 待审核 */ +/* 作者名与时间之间的小间隔点。 + * 用 ::before 而不是真加一个字符:它会跟着 time 一起换行, + * 不会孤零零留在行首。 */ +.yang-comment-time::before { + content: "·"; + margin-right: 6px; + color: #c9ced6; +} + +/* 徽标:作者 / 待审核。3px 圆角改成 pill —— 徽标本身足够短, + * pill 不会显得幼稚,反而和头像的圆形呼应。 */ .yang-comment-badge { flex: 0 0 auto; - padding: 1px 6px; - border-radius: 3px; - background-color: #eaf3ff; - color: #0b74d1; + padding: 1px 8px; + border-radius: 999px; + background-color: var(--yq-primary-soft, #eaf6ff); + color: var(--yq-primary-dark, #0089db); font-size: 11.5px; - font-weight: 400; - line-height: 1.5; + font-weight: 500; + line-height: 1.6; + letter-spacing: 0.01em; } .yang-comment-badge.is-pending { - background-color: #fff6e5; - color: #b27412; + background-color: #fff5e0; + color: #96601a; } -/* 待审核的整条评论淡化,一眼区分 */ +/* 待审核的整条评论淡化,一眼区分。 + * 0.72 太狠 —— 配上本来就淡的时间,整条几乎消失。收到 0.85。 */ .yang-comment.is-pending .yang-comment-content { - opacity: 0.72; + opacity: 0.85; } /* 评论正文 */ .yang-comment-content { - color: #3c414a; - font-size: 14px; - line-height: 1.78; + color: var(--yq-text, #33383f); + font-size: 14.5px; + /* 1.8 是中文长文段的舒适值;原来 1.78 也可以, + 但配合 14.5px 的字号,1.8 让行距守恒在 26px 左右,更像印刷品 */ + line-height: 1.8; word-wrap: break-word; overflow-wrap: break-word; } @@ -255,12 +389,12 @@ } .yang-comment-content p { - margin: 0 0 8px; + margin: 0 0 10px; } /* @某人 的提及高亮(由 comment_add_at 过滤器插入的 ) */ .yang-comment-content > span:first-child { - color: #0b74d1; + color: var(--yq-primary-dark, #0089db); font-weight: 500; } @@ -272,28 +406,42 @@ /* 引用块 */ .yang-comment-content blockquote { - margin: 8px 0; - padding: 6px 12px; - border-left: 3px solid #e2e6ee; - background-color: #fafbfc; - color: #6b7280; + margin: 10px 0; + padding: 8px 14px; + border-left: 3px solid #cfe4f8; + border-radius: 0 var(--yq-radius, 4px) var(--yq-radius, 4px) 0; + background-color: var(--yq-bg-soft, #f7f9fb); + color: var(--yq-text-2, #5b6470); font-size: 13.5px; + line-height: 1.75; +} + +.yang-comment-content blockquote > p:last-child { + margin-bottom: 0; } .yang-comment-content code { padding: 1px 5px; border-radius: 3px; - background-color: #f4f5f7; + background-color: #f2f4f7; color: #c7254e; font-size: 13px; } .yang-comment-content pre { overflow-x: auto; - padding: 10px 12px; - border-radius: 3px; + margin: 10px 0; + padding: 11px 14px; + border-radius: var(--yq-radius, 4px); background-color: #f6f7f9; font-size: 13px; + line-height: 1.65; +} + +.yang-comment-content pre code { + padding: 0; + background: none; + color: inherit; } /* 表情图片与正文基线对齐 */ @@ -312,32 +460,50 @@ .yang-comment-actions { display: flex; align-items: center; - gap: 14px; - margin-top: 6px; + gap: 6px; + /* 正文下留一点呼吸;按钮自带内边距,这里就得收一点 */ + margin-top: 5px; + margin-left: -9px; /* 抵消按钮的 padding-left,让图标与正文左边缘对齐 */ } +/* 「回复」「编辑」:**第二处硬指标修复**。 + * 原来是 #8a9099(对比度 3.22)且没有任何边距, + * 在正文下面像一行灰字,不像按钮。 + * 现在:颜色提到 #5b6470(6.0),加内边距形成可点区域, + * hover 时出现浅蓝底 —— 三重信号告诉人"这是能点的"。 */ .yang-comment-reply, .yang-comment-edit { - padding: 0; + padding: 3px 9px; border: 0; + border-radius: var(--yq-radius, 4px); background: none; - color: #8a9099; + color: var(--yq-text-2, #5b6470); font-size: 13px; + font-weight: 500; line-height: 1.6; text-decoration: none; cursor: pointer; - transition: color 0.15s ease; + transition: color 0.16s var(--yq-ease), background-color 0.16s var(--yq-ease); } .yang-comment-reply:hover, .yang-comment-edit:hover { - color: #00a2ff; + background-color: var(--yq-primary-soft, #eaf6ff); + color: var(--yq-primary-dark, #0089db); text-decoration: none; } +.yang-comment-reply:focus-visible, +.yang-comment-edit:focus-visible { + outline: 2px solid var(--yq-primary, #00a2ff); + outline-offset: 1px; +} + .yang-comment-reply .kicon { - margin-right: 3px; + margin-right: 4px; font-size: 12px; + /* 图标跟文字同色,不要一个深一个浅 */ + color: inherit; } /* 已进入"回复这条"状态时,按钮藏起来(由 JS 加 class) */ @@ -349,29 +515,45 @@ 5. 嵌套回复 --------------------------------------------------------------*/ +/* 层级用三重冗余表达,任何一重失效另外两重仍在: + * ① 缩进(padding-left) + * ② 引导线(border-left) + * ③ 头像尺寸(42 → 34) + * + * 引导线原来用 #f0f2f5 —— 和白底差 5 级灰阶,基本看不见, + * 于是"缩进 20px 但没有任何归属提示",三层以上完全看不出谁回谁。 + * 现在提到 #dbe6f2(带一点主色倾向),既看得见又不刺眼。 + * + * ⚠️ 缩进只能用 padding-left,**不能用 margin-left**: + * `_diag318_children_geo.js` 判据 A 要求 `ol.yang-children` 的 + * 左偏移(相对父 li)≤4px、判据 B 要求宽度 ≥ 父宽 90%。 + * margin-left 会同时破坏这两条,padding-left 不会。 */ .yang-children { - margin-top: 2px; - padding-left: 20px; - /* 左侧引导线:让"谁回谁"在视觉上有明确归属 */ - border-left: 2px solid #f0f2f5; + margin-top: 4px; + padding-left: 18px; + border-left: 2px solid var(--yq-guide, #dbe6f2); } .yang-children > .yang-comment { - padding: 11px 0; + padding: 12px 0; } -/* 深层的头像小一号,靠尺寸建立层级感 */ +/* 同一层回复之间:比顶层更细的分隔,且只在"多于一条"时才需要。 + * 用 :not(:last-child) 而不是给最后一条清零 —— 后者会因为 + * 嵌套结构不同而漏掉某些情况。 */ +.yang-children > .yang-comment:not(:last-child) { + border-bottom: 1px solid var(--yq-line-soft, #f1f4f8); +} + +/* 深层的头像小一号,靠尺寸建立层级感(第二重冗余) */ .yang-children .yang-children .yang-comment-avatar, -.yang-children .yang-children .yang-comment-avatar img, .yang-children .yang-children .yang-comment-avatar-ph { width: 34px; } -.yang-children .yang-children .yang-comment-avatar { +.yang-children .yang-children .yang-comment-avatar img, +.yang-children .yang-children .yang-comment-avatar-img { width: 34px; -} - -.yang-children .yang-children .yang-comment-avatar img { height: 34px; } @@ -380,9 +562,11 @@ font-size: 14px; } -/* 第三层以后不再继续缩进 —— 否则窄屏上正文只剩一条竖线 */ +/* 第三层以后不再继续缩进 —— 否则窄屏上正文只剩一条竖线。 + * 引导线也去掉:三条竖线叠在一起会变成"表格"观感。 */ .yang-children .yang-children .yang-children { padding-left: 8px; + border-left-color: #e6edf5; } /* 新提交的评论:淡入 + 短暂底色,让用户看到自己刚发的那条 */ @@ -398,8 +582,18 @@ } .yang-comment.is-new { - animation: yang-comment-in 0.28s ease; - background-color: #fffdf5; + animation: yang-comment-in 0.28s var(--yq-ease); + border-radius: var(--yq-radius-lg, 6px); + background-color: #fffdf4; +} + +/* 从通知/后台带 #comment-123 跳过来时,高亮那一条。 + * 只在正文区上色,不动布局宽度 —— 用整条 li 加内边距的话, + * 页面会在跳转瞬间"抖一下",比不高亮更难受。 */ +.yang-comment:target .yang-comment-content { + border-radius: var(--yq-radius, 4px); + background-color: #fffbe8; + box-shadow: 0 0 0 8px #fffbe8; } /*-------------------------------------------------------------- @@ -407,7 +601,7 @@ --------------------------------------------------------------*/ .comments-more { - padding: 16px 0 4px; + padding: 18px 0 2px; text-align: center; } @@ -416,24 +610,31 @@ } .comments-more-btn { - padding: 8px 26px; - border: 1px solid #e2e6ee; - border-radius: 3px; + padding: 9px 28px; + border: 1px solid #dbe3ec; + border-radius: 999px; background-color: #fff; - color: #5a616b; + color: var(--yq-text-2, #5b6470); font-size: 13.5px; + font-weight: 500; cursor: pointer; - transition: border-color 0.15s ease, color 0.15s ease, background-color 0.15s ease; + transition: border-color 0.16s var(--yq-ease), color 0.16s var(--yq-ease), + background-color 0.16s var(--yq-ease); } .comments-more-btn:hover:not(:disabled) { - border-color: #00a2ff; - background-color: #f5fbff; - color: #00a2ff; + border-color: var(--yq-primary, #00a2ff); + background-color: var(--yq-primary-soft, #eaf6ff); + color: var(--yq-primary-dark, #0089db); +} + +.comments-more-btn:focus-visible { + outline: 2px solid var(--yq-primary, #00a2ff); + outline-offset: 2px; } .comments-more-btn:disabled { - opacity: 0.6; + opacity: 0.55; cursor: default; } @@ -442,16 +643,16 @@ --------------------------------------------------------------*/ .comment-respond { - margin-top: 22px; - padding-top: 20px; - border-top: 1px solid #f0f0f0; + margin-top: 24px; + padding-top: 22px; + border-top: 1px solid var(--yq-line, #eaedf2); } /* 表单被"搬"进某条评论时,去掉那条顶部分隔线,视觉上更连贯 */ .yang-children > #respond { margin-top: 10px; - padding-top: 12px; - border-top: 1px dashed #e8ebf0; + padding-top: 14px; + border-top: 1px dashed #e3e9f1; } .comment-reply-title { @@ -459,7 +660,7 @@ align-items: center; flex-wrap: wrap; gap: 10px; - margin: 0 0 14px; + margin: 0 0 15px; color: #1f2328; font-weight: 600; font-size: 16px; @@ -467,15 +668,16 @@ } .comment-cancel-reply { - padding: 3px 10px; - border: 1px solid #e4e8ee; - border-radius: 3px; + padding: 3px 11px; + border: 1px solid #e2e7ee; + border-radius: 999px; background-color: #f7f8fa; - color: #6b7280; + color: var(--yq-text-2, #5b6470); font-weight: 400; font-size: 12.5px; cursor: pointer; - transition: all 0.15s ease; + transition: border-color 0.16s var(--yq-ease), background-color 0.16s var(--yq-ease), + color 0.16s var(--yq-ease); } .comment-cancel-reply[hidden] { @@ -490,14 +692,14 @@ /* 「正在回复 @某人」提示条 */ .comment-reply-hint { - margin: 0 0 12px; - padding: 7px 12px; - border-left: 3px solid #00a2ff; - border-radius: 2px; - background-color: #f2f8ff; - color: #4a6b8a; + margin: 0 0 13px; + padding: 8px 13px; + border-left: 3px solid var(--yq-primary, #00a2ff); + border-radius: 0 var(--yq-radius, 4px) var(--yq-radius, 4px) 0; + background-color: #f2f9ff; + color: #3f6b90; font-size: 13px; - line-height: 1.6; + line-height: 1.65; } .comment-reply-hint[hidden] { @@ -520,68 +722,88 @@ .comment-field-icon { position: absolute; - left: 9px; + left: 11px; top: 50%; transform: translateY(-50%); - color: #b6bcc6; + color: #a8b0bb; font-size: 14px; line-height: 1; pointer-events: none; } +/* 输入框:3px → 4px 圆角,内边距加 1px。 + * 单看差距很小,但三个输入框并排时,"够不够松"决定整体是否廉价。 */ .comment-input { display: block; width: 100%; - padding: 9px 12px; - border: 1px solid #e6e9ef; - border-radius: 3px; - background-color: #fcfcfd; - color: #303133; + padding: 10px 13px; + border: 1px solid #dfe4ec; + border-radius: var(--yq-radius, 4px); + background-color: var(--yq-bg-input, #fcfcfd); + color: #2b3038; font-family: inherit; font-size: 14px; line-height: 1.5; - transition: border-color 0.15s ease, background-color 0.15s ease, box-shadow 0.15s ease; + transition: border-color 0.16s var(--yq-ease), background-color 0.16s var(--yq-ease), + box-shadow 0.16s var(--yq-ease); -webkit-appearance: none; } .comment-field .comment-input { - padding-left: 32px; + padding-left: 34px; } +/* 占位符:原来复用了 #a4abb5(对比度 2.32)。 + * 占位符承载的是「这里该填什么」这层信息,不是纯装饰, + * 所以跟时间戳一起提到 --yq-text-3。 + * 注意仍要比已输入的文字(#2b3038)弱一档,否则分不清"填了没有"。 */ .comment-input::placeholder { - color: #b0b6bf; + color: var(--yq-text-3, #6b7280); + opacity: 1; /* Firefox 默认会再压一层透明度,雪上加霜 */ +} + +.comment-input:hover:not(:focus):not(:disabled) { + border-color: #cdd6e2; } .comment-input:focus { outline: none; - border-color: #00a2ff; + border-color: var(--yq-primary, #00a2ff); background-color: #fff; - box-shadow: 0 0 0 3px rgba(0, 162, 255, 0.1); + /* 3px 的柔和外环,比原来的 0.1 稍微实一点, + 在高亮背景(护眼黄等)下也能看清焦点在哪 */ + box-shadow: 0 0 0 3px rgba(0, 162, 255, 0.14); } .comment-input:disabled, .comment-input[readonly] { - background-color: #f7f8fa; - color: #8a9099; + background-color: #f6f7f9; + color: var(--yq-text-3, #6b7280); } /* textarea 容器 */ .comment-textarea { position: relative; - border: 1px solid #e6e9ef; - border-radius: 3px; - background-color: #fcfcfd; - transition: border-color 0.15s ease, box-shadow 0.15s ease; + border: 1px solid #dfe4ec; + border-radius: var(--yq-radius, 4px); + background-color: var(--yq-bg-input, #fcfcfd); + transition: border-color 0.16s var(--yq-ease), box-shadow 0.16s var(--yq-ease), + background-color 0.16s var(--yq-ease); +} + +.comment-textarea:hover:not(:focus-within) { + border-color: #cdd6e2; } .comment-textarea:focus-within { - border-color: #00a2ff; - box-shadow: 0 0 0 3px rgba(0, 162, 255, 0.1); + border-color: var(--yq-primary, #00a2ff); + background-color: #fff; + box-shadow: 0 0 0 3px rgba(0, 162, 255, 0.14); } .comment-textarea .comment-input { - min-height: 132px; - padding: 11px 13px; + min-height: 136px; + padding: 12px 14px; border: 0; border-radius: 0; background: none; @@ -591,6 +813,7 @@ .comment-textarea .comment-input:focus { box-shadow: none; + background: none; } /* 工具条 */ @@ -599,8 +822,9 @@ align-items: center; justify-content: space-between; gap: 10px; - padding: 7px 10px; - border-top: 1px solid #f0f2f6; + padding: 8px 11px; + border-top: 1px solid #edf0f4; + border-radius: 0 0 var(--yq-radius, 4px) var(--yq-radius, 4px); background-color: #fafbfc; } @@ -616,20 +840,20 @@ } .comment-smile-btn { - padding: 4px 7px; + padding: 4px 8px; border: 0; - border-radius: 3px; + border-radius: var(--yq-radius, 4px); background: none; - color: #8a9099; + color: var(--yq-text-3, #6b7280); font-size: 17px; line-height: 1; cursor: pointer; - transition: color 0.15s ease, background-color 0.15s ease; + transition: color 0.16s var(--yq-ease), background-color 0.16s var(--yq-ease); } .comment-smile-btn:hover { - background-color: #eef2f7; - color: #00a2ff; + background-color: var(--yq-primary-soft, #eaf6ff); + color: var(--yq-primary-dark, #0089db); } /* 表情面板:3 行 8 列 */ @@ -641,11 +865,11 @@ display: flex; flex-wrap: wrap; width: 264px; - padding: 8px; - border: 1px solid #e6e9ef; - border-radius: 4px; + padding: 9px; + border: 1px solid #e2e7ee; + border-radius: var(--yq-radius-lg, 6px); background-color: #fff; - box-shadow: 0 4px 14px rgba(0, 0, 0, 0.1); + box-shadow: 0 6px 20px rgba(31, 35, 40, 0.12); } .comment-smile-panel[hidden] { @@ -660,9 +884,9 @@ width: 28px; height: 28px; border: 1px solid transparent; - border-radius: 3px; + border-radius: var(--yq-radius, 4px); background-color: #f7f8fa; - transition: background-color 0.12s ease, border-color 0.12s ease; + transition: background-color 0.12s var(--yq-ease), border-color 0.12s var(--yq-ease); } .comment-smile-panel a:hover { @@ -678,41 +902,58 @@ /* 状态提示 */ .comment-status { - color: #8a9099; + color: var(--yq-text-3, #6b7280); font-size: 12.5px; line-height: 1.6; - transition: color 0.15s ease; + transition: color 0.16s var(--yq-ease); } .comment-status.is-ok { - color: #2f9e44; + color: #2f8a3e; } .comment-status.is-err { - color: #d9534f; + color: #cf3b36; } /* 提交按钮 */ .comment-submit { - padding: 8px 22px; + padding: 9px 24px; border: 0; - border-radius: 3px; - background-color: #00a2ff; + border-radius: var(--yq-radius, 4px); + background-color: var(--yq-primary, #00a2ff); + box-shadow: 0 1px 2px rgba(0, 162, 255, 0.24); color: #fff; font-size: 14px; + font-weight: 500; line-height: 1.5; cursor: pointer; white-space: nowrap; - transition: background-color 0.15s ease, opacity 0.15s ease; + transition: background-color 0.16s var(--yq-ease), box-shadow 0.16s var(--yq-ease), + opacity 0.16s var(--yq-ease), transform 0.16s var(--yq-ease); } .comment-submit:hover:not(:disabled) { - background-color: #0090e6; + background-color: var(--yq-primary-dark, #0089db); + box-shadow: 0 3px 10px rgba(0, 162, 255, 0.3); + transform: translateY(-1px); +} + +.comment-submit:active:not(:disabled) { + transform: none; + box-shadow: 0 1px 2px rgba(0, 162, 255, 0.24); +} + +.comment-submit:focus-visible { + outline: 2px solid var(--yq-primary, #00a2ff); + outline-offset: 2px; } .comment-submit:disabled, .comment-submit.is-loading { - opacity: 0.62; + opacity: 0.6; + box-shadow: none; + transform: none; cursor: default; } @@ -728,20 +969,25 @@ /* 只需登录才能评论的提示 */ .comments-login-required { margin: 0; - padding: 18px; - border: 1px solid #e5e5e5; - border-radius: 4px; - background-color: #fafbfc; - color: #6b7280; + padding: 20px; + border: 1px dashed #dfe5ec; + border-radius: var(--yq-radius, 4px); + background-color: transparent; + color: var(--yq-text-3, #6b7280); font-size: 13.5px; + line-height: 1.7; text-align: center; } .comments-login-required a { - color: #00a2ff; + color: var(--yq-primary-dark, #0089db); text-decoration: none; } +.comments-login-required a:hover { + text-decoration: underline; +} + /*-------------------------------------------------------------- 8. 无障碍:屏幕阅读器专用文本 --------------------------------------------------------------*/ @@ -764,25 +1010,39 @@ @media screen and (max-width: 768px) { .k-main .details .comments { - padding: 16px 14px 18px; + padding: 17px 15px 19px; } .comments-head { flex-wrap: wrap; gap: 8px; + padding-bottom: 13px; } .comments-head .title { font-size: 17px; + padding-left: 11px; + } + + .comments-head .title::before { + height: 14px; + margin-top: -7px; } .yang-comment { /* 只收窄列间距;写 gap 会同时给 grid 的 row-gap 赋值, 导致"主体"与"子评论"之间多出一道空隙 */ column-gap: 10px; - padding: 13px 0; + padding: 14px 0; } + /* ⚠️ 这一组必须同时写容器、img 和占位符的 width。 + * 只写 height 是个隐蔽陷阱:`.yang-comment-avatar` 容器收到 36px, + * 但基础规则里 img 的 width 仍是 42px —— img 会**溢出容器右侧** 6px, + * 压在正文上,看起来只是"头像有点歪"。 + * 更麻烦的是几何探针量的是容器宽度(`.yang-comment-avatar` 的 + * getBoundingClientRect),容器确实是 36 —— 于是断言全绿, + * 溢出完全测不到。这个坑是 `_style_ab.js` 逐元素比对时抓出来的。 */ .yang-comment-avatar, .yang-comment-avatar img, .yang-comment-avatar-img, @@ -796,13 +1056,24 @@ height: 36px; } - /* 窄屏缩进收窄:原来 20px 在三层后正文只剩很窄一条 */ + .yang-comment-author { + font-size: 14px; + } + + .yang-comment-content { + font-size: 14px; + line-height: 1.78; + } + + /* 窄屏缩进收窄:20px 在三层后正文只剩很窄一条。 + 仍然 ≥6px,`_comments_geometry.js` 的"最小可感知缩进"判据要求的。 */ .yang-children { - padding-left: 11px; + padding-left: 12px; + margin-top: 3px; } .yang-children .yang-children { - padding-left: 8px; + padding-left: 9px; } .yang-children .yang-children .yang-children { @@ -834,12 +1105,17 @@ min-width: 0; } + .comment-submit { + padding: 9px 20px; + } + .comment-smile-panel { width: 240px; } } @media screen and (max-width: 400px) { + /* 400px 断点:同样必须把 img 的 width 一起覆盖(理由见 768 断点那条) */ .yang-comment-avatar, .yang-comment-avatar img, .yang-comment-avatar-img, @@ -860,11 +1136,13 @@ 深层头像仍是 34px,反而比顶层的 32px 更大,层级关系是反的。 */ .yang-children .yang-children .yang-comment-avatar, .yang-children .yang-children .yang-comment-avatar img, + .yang-children .yang-children .yang-comment-avatar-img, .yang-children .yang-children .yang-comment-avatar-ph { width: 26px; } .yang-children .yang-children .yang-comment-avatar img, + .yang-children .yang-children .yang-comment-avatar-img, .yang-children .yang-children .yang-comment-avatar-ph { height: 26px; font-size: 12px; @@ -875,6 +1153,24 @@ } } +/* 尊重"减少动效"偏好:动画全部关掉,但保留视觉状态(颜色、阴影) */ +@media (prefers-reduced-motion: reduce) { + .yang-comment, + .yang-comment *, + .comment-submit, + .comments-jump-form, + .comments-more-btn, + .comment-input, + .comment-textarea { + animation: none !important; + transition: none !important; + } + + .comment-submit:hover:not(:disabled) { + transform: none; + } +} + /*-------------------------------------------------------------- 10. 打印:评论不需要按钮 --------------------------------------------------------------*/ @@ -887,6 +1183,10 @@ display: none !important; } + .k-main .details .comments { + box-shadow: none; + } + .yang-comment-content { color: #000; } diff --git a/style.css b/style.css index 96f141b..2c23bb2 100644 --- a/style.css +++ b/style.css @@ -1,7 +1,7 @@ /* Theme Name: Kratos_Yang Text Domain: kratos_Yang -Version: 3.2.19 +Version: 3.2.20 Requires PHP: 7.0 Description: 这是一个Kratos主题的分支版本,用来增加一些定制化功能。 Tags: 博客, 双栏, 响应式, 自定义背景, 自定义颜色, 自定义图标, 自定义菜单, 特色图像, 收录优化, 邮件中心, 主题选项, 小工具, 文章置顶, 无障碍友好