Files
wordpress-kratos-yang/assets/css/comments.css
T
laoyang b97f265142 feat(comments): 评论区样式重做,修掉三处可读性不达标与窄屏头像溢出(3.2.20)
用无头浏览器把评论区的计算样式逐条量出来之后,确认「不好看」里有三处
是硬指标不达标,不是主观审美:

  · 时间戳 #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。
2026-10-24 12:16:30 +08:00

1193 lines
32 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*!
* 评论区样式
* Yongquan Yang <yangyq.net>
*
* ── 3.2.20:为什么又改了一次 ────────────────────────────────
* 3.2.18 重写解决的是**结构**问题(float 撑破、嵌套没缩进、
* 头像基线不齐)。3.2.19 解决的是**数据**问题(评论一条不显示)。
* 这一版解决的是**观感**问题 —— 用无头浏览器把计算样式量出来
* 之后,量到的三条都是硬指标不达标,不是"见仁见智":
*
* · 时间戳 #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`。
* 原因:`<ol class="yang-children">` 是 `<li>` 的**直接子元素**,
* 换成 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: 20px;
padding: 22px 24px 24px;
border-radius: var(--yq-radius-lg, 6px);
background-color: #fff;
/* 比原来的 0 1px 3px 稍微收一点:整站卡片(.widget)用的是
0 1px 2px,评论区跟着走,深浅一致才不会显得"飘" */
box-shadow: 0 1px 2px rgba(31, 35, 40, 0.08);
}
.k-main .details .post-2 .comments {
box-shadow: none;
}
.comments-head {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 12px;
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: 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.16s var(--yq-ease), border-color 0.16s var(--yq-ease),
color 0.16s var(--yq-ease);
}
.comments-jump-form:hover {
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: 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;
}
/*--------------------------------------------------------------
2. 评论列表
--------------------------------------------------------------*/
.yang-comment-list,
.yang-children {
margin: 0;
padding: 0;
list-style: none;
}
.yang-comment-list {
margin-top: 2px;
}
/* 顶层评论之间用**看得见**的分隔线。
* 原来是 #f5f6f8 —— 对白底几乎零差(正文区宽度 780px 的一条线,
* 差值小于 4 级灰阶,人眼在普通屏幕上抓不到),
* 于是四条评论糊成一坨。现在提到 #eaedf2,是"能看见但不抢戏"的程度。
* 跨层之间不加线,交给缩进和引导线表达 —— 两套信号不要打架。 */
.yang-comment-list > .yang-comment {
border-bottom: 1px solid var(--yq-line, #eaedf2);
}
.yang-comment-list > .yang-comment:last-child {
border-bottom: 0;
}
/*--------------------------------------------------------------
3. 单条评论
--------------------------------------------------------------*/
/* 单条评论的布局:头像列 + 主体列
*
* ⚠️ 这里**必须是 grid,不能是 flex**。
* 原因:wp_list_comments 输出的是
* <li class="yang-comment">
* <div class="yang-comment-avatar">…</div>
* <div class="yang-comment-main">…</div>
* <ol class="yang-children">…子评论…</ol> ← 也是 li 的直接子元素
* </li>
* 若 li 用 display:flex,那个 <ol> 就成了**第三个 flex 项**,
* 被排到主体右边的同一行里 —— 表现为"子评论跑到父评论右侧"、
* 父评论正文被挤成一条、页面出现横向溢出。这是真实渲染量出来的,
* 光看代码几乎想不到(flex 项的位置不体现在 li 自己的属性上)。
*
* grid 用两列:第 1 列 auto(由头像定宽),第 2 列 minmax(0,1fr)
* (minmax 的下界 0 是关键,否则长英文/长 URL 会把列撑宽)。
* 子评论用 grid-column: 1 / -1 独占下一整行。 */
.yang-comment {
display: grid;
grid-template-columns: auto minmax(0, 1fr);
column-gap: 13px;
align-items: start;
padding: 18px 0;
list-style: none;
/* 从通知邮件/后台点进来时会带 #comment-123 锚点,
这里不做布局级高亮(会挤动内容),只给正文区一个色块,
详见第 5 节末尾的 :target 规则。 */
}
/* 子评论容器独占整行,排在头像与主体下方 */
.yang-comment > .yang-children {
grid-column: 1 / -1;
}
/* 头像列:固定宽度,不参与伸缩 —— 否则长评论把它挤扁。
* (grid 里 flex 属性无效,留着只是无害的历史残留,已删除。) */
.yang-comment-avatar {
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: 0;
border-radius: 50%;
object-fit: cover;
background-color: #f2f4f7;
box-shadow: 0 0 0 1px rgba(31, 35, 40, 0.07), 0 1px 2px rgba(31, 35, 40, 0.06);
}
/* 没有头像时的首字占位 */
.yang-comment-avatar-ph {
display: flex;
align-items: center;
justify-content: center;
width: 42px;
height: 42px;
border-radius: 50%;
background-color: #eef2f7;
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 {
min-width: 0; /* 关键:让内部的 text-overflow / 换行能生效 */
}
.yang-comment-head {
display: flex;
align-items: baseline;
flex-wrap: wrap;
gap: 6px;
margin-bottom: 5px;
}
.yang-comment-author {
color: #1f2328;
font-weight: 600;
font-style: normal;
font-size: 14.5px;
line-height: 1.5;
/* 超长昵称截断,别把时间挤到下一行去 */
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.yang-comment-author a {
color: inherit;
text-decoration: none;
transition: color 0.16s var(--yq-ease);
}
.yang-comment-author a:hover {
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: 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 8px;
border-radius: 999px;
background-color: var(--yq-primary-soft, #eaf6ff);
color: var(--yq-primary-dark, #0089db);
font-size: 11.5px;
font-weight: 500;
line-height: 1.6;
letter-spacing: 0.01em;
}
.yang-comment-badge.is-pending {
background-color: #fff5e0;
color: #96601a;
}
/* 待审核的整条评论淡化,一眼区分。
* 0.72 太狠 —— 配上本来就淡的时间,整条几乎消失。收到 0.85。 */
.yang-comment.is-pending .yang-comment-content {
opacity: 0.85;
}
/* 评论正文 */
.yang-comment-content {
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;
}
.yang-comment-content > p:first-child {
margin-top: 0;
}
.yang-comment-content > p:last-child {
margin-bottom: 0;
}
.yang-comment-content p {
margin: 0 0 10px;
}
/* @某人 的提及高亮(由 comment_add_at 过滤器插入的 <span>) */
.yang-comment-content > span:first-child {
color: var(--yq-primary-dark, #0089db);
font-weight: 500;
}
/* 评论里的图片:限制最大宽度,别撑破容器 */
.yang-comment-content img {
max-width: 100%;
height: auto;
}
/* 引用块 */
.yang-comment-content blockquote {
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: #f2f4f7;
color: #c7254e;
font-size: 13px;
}
.yang-comment-content pre {
overflow-x: auto;
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;
}
/* 表情图片与正文基线对齐 */
.yang-comment-content img.wp-smiley {
display: inline-block;
margin: 0 1px;
width: auto;
max-height: 1.4em;
vertical-align: text-bottom;
}
/*--------------------------------------------------------------
4. 操作按钮
--------------------------------------------------------------*/
.yang-comment-actions {
display: flex;
align-items: center;
gap: 6px;
/* 正文下留一点呼吸;按钮自带内边距,这里就得收一点 */
margin-top: 5px;
margin-left: -9px; /* 抵消按钮的 padding-left,让图标与正文左边缘对齐 */
}
/* 「回复」「编辑」:**第二处硬指标修复**。
* 原来是 #8a9099(对比度 3.22)且没有任何边距,
* 在正文下面像一行灰字,不像按钮。
* 现在:颜色提到 #5b6470(6.0),加内边距形成可点区域,
* hover 时出现浅蓝底 —— 三重信号告诉人"这是能点的"。 */
.yang-comment-reply,
.yang-comment-edit {
padding: 3px 9px;
border: 0;
border-radius: var(--yq-radius, 4px);
background: none;
color: var(--yq-text-2, #5b6470);
font-size: 13px;
font-weight: 500;
line-height: 1.6;
text-decoration: none;
cursor: pointer;
transition: color 0.16s var(--yq-ease), background-color 0.16s var(--yq-ease);
}
.yang-comment-reply:hover,
.yang-comment-edit:hover {
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: 4px;
font-size: 12px;
/* 图标跟文字同色,不要一个深一个浅 */
color: inherit;
}
/* 已进入"回复这条"状态时,按钮藏起来(由 JS 加 class) */
.yang-comment-reply.is-hidden {
visibility: hidden;
}
/*--------------------------------------------------------------
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: 4px;
padding-left: 18px;
border-left: 2px solid var(--yq-guide, #dbe6f2);
}
.yang-children > .yang-comment {
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-ph {
width: 34px;
}
.yang-children .yang-children .yang-comment-avatar img,
.yang-children .yang-children .yang-comment-avatar-img {
width: 34px;
height: 34px;
}
.yang-children .yang-children .yang-comment-avatar-ph {
height: 34px;
font-size: 14px;
}
/* 第三层以后不再继续缩进 —— 否则窄屏上正文只剩一条竖线。
* 引导线也去掉:三条竖线叠在一起会变成"表格"观感。 */
.yang-children .yang-children .yang-children {
padding-left: 8px;
border-left-color: #e6edf5;
}
/* 新提交的评论:淡入 + 短暂底色,让用户看到自己刚发的那条 */
@keyframes yang-comment-in {
from {
opacity: 0;
transform: translateY(-4px);
}
to {
opacity: 1;
transform: none;
}
}
.yang-comment.is-new {
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;
}
/*--------------------------------------------------------------
6. 加载更多
--------------------------------------------------------------*/
.comments-more {
padding: 18px 0 2px;
text-align: center;
}
.comments-more[hidden] {
display: none;
}
.comments-more-btn {
padding: 9px 28px;
border: 1px solid #dbe3ec;
border-radius: 999px;
background-color: #fff;
color: var(--yq-text-2, #5b6470);
font-size: 13.5px;
font-weight: 500;
cursor: pointer;
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: 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.55;
cursor: default;
}
/*--------------------------------------------------------------
7. 评论表单
--------------------------------------------------------------*/
.comment-respond {
margin-top: 24px;
padding-top: 22px;
border-top: 1px solid var(--yq-line, #eaedf2);
}
/* 表单被"搬"进某条评论时,去掉那条顶部分隔线,视觉上更连贯 */
.yang-children > #respond {
margin-top: 10px;
padding-top: 14px;
border-top: 1px dashed #e3e9f1;
}
.comment-reply-title {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 10px;
margin: 0 0 15px;
color: #1f2328;
font-weight: 600;
font-size: 16px;
line-height: 1.5;
}
.comment-cancel-reply {
padding: 3px 11px;
border: 1px solid #e2e7ee;
border-radius: 999px;
background-color: #f7f8fa;
color: var(--yq-text-2, #5b6470);
font-weight: 400;
font-size: 12.5px;
cursor: pointer;
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] {
display: none;
}
.comment-cancel-reply:hover {
border-color: #f0b4b4;
background-color: #fff5f5;
color: #d9534f;
}
/* 「正在回复 @某人」提示条 */
.comment-reply-hint {
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.65;
}
.comment-reply-hint[hidden] {
display: none;
}
/* 昵称/邮箱/网址:三列,窄屏自动堆叠 */
.comment-info {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-bottom: 12px;
}
.comment-field {
position: relative;
flex: 1 1 180px;
min-width: 0;
}
.comment-field-icon {
position: absolute;
left: 11px;
top: 50%;
transform: translateY(-50%);
color: #a8b0bb;
font-size: 14px;
line-height: 1;
pointer-events: none;
}
/* 输入框:3px → 4px 圆角,内边距加 1px。
* 单看差距很小,但三个输入框并排时,"够不够松"决定整体是否廉价。 */
.comment-input {
display: block;
width: 100%;
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.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: 34px;
}
/* 占位符:原来复用了 #a4abb5(对比度 2.32)。
* 占位符承载的是「这里该填什么」这层信息,不是纯装饰,
* 所以跟时间戳一起提到 --yq-text-3。
* 注意仍要比已输入的文字(#2b3038)弱一档,否则分不清"填了没有"。 */
.comment-input::placeholder {
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: var(--yq-primary, #00a2ff);
background-color: #fff;
/* 3px 的柔和外环,比原来的 0.1 稍微实一点,
在高亮背景(护眼黄等)下也能看清焦点在哪 */
box-shadow: 0 0 0 3px rgba(0, 162, 255, 0.14);
}
.comment-input:disabled,
.comment-input[readonly] {
background-color: #f6f7f9;
color: var(--yq-text-3, #6b7280);
}
/* textarea 容器 */
.comment-textarea {
position: relative;
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: 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: 136px;
padding: 12px 14px;
border: 0;
border-radius: 0;
background: none;
resize: vertical;
box-shadow: none;
}
.comment-textarea .comment-input:focus {
box-shadow: none;
background: none;
}
/* 工具条 */
.comment-bar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
padding: 8px 11px;
border-top: 1px solid #edf0f4;
border-radius: 0 0 var(--yq-radius, 4px) var(--yq-radius, 4px);
background-color: #fafbfc;
}
.comment-bar-left,
.comment-bar-right {
display: flex;
align-items: center;
gap: 8px;
}
.comment-bar-left {
position: relative;
}
.comment-smile-btn {
padding: 4px 8px;
border: 0;
border-radius: var(--yq-radius, 4px);
background: none;
color: var(--yq-text-3, #6b7280);
font-size: 17px;
line-height: 1;
cursor: pointer;
transition: color 0.16s var(--yq-ease), background-color 0.16s var(--yq-ease);
}
.comment-smile-btn:hover {
background-color: var(--yq-primary-soft, #eaf6ff);
color: var(--yq-primary-dark, #0089db);
}
/* 表情面板:3 行 8 列 */
.comment-smile-panel {
position: absolute;
bottom: calc(100% + 8px);
left: 0;
z-index: 20;
display: flex;
flex-wrap: wrap;
width: 264px;
padding: 9px;
border: 1px solid #e2e7ee;
border-radius: var(--yq-radius-lg, 6px);
background-color: #fff;
box-shadow: 0 6px 20px rgba(31, 35, 40, 0.12);
}
.comment-smile-panel[hidden] {
display: none;
}
.comment-smile-panel a {
float: none;
display: block;
margin: 2px;
padding: 3px;
width: 28px;
height: 28px;
border: 1px solid transparent;
border-radius: var(--yq-radius, 4px);
background-color: #f7f8fa;
transition: background-color 0.12s var(--yq-ease), border-color 0.12s var(--yq-ease);
}
.comment-smile-panel a:hover {
border-color: #b9dcff;
background-color: #eaf4ff;
}
.comment-smile-panel img {
display: block;
width: 20px;
height: 20px;
}
/* 状态提示 */
.comment-status {
color: var(--yq-text-3, #6b7280);
font-size: 12.5px;
line-height: 1.6;
transition: color 0.16s var(--yq-ease);
}
.comment-status.is-ok {
color: #2f8a3e;
}
.comment-status.is-err {
color: #cf3b36;
}
/* 提交按钮 */
.comment-submit {
padding: 9px 24px;
border: 0;
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.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: 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.6;
box-shadow: none;
transform: none;
cursor: default;
}
/* honeypot:移出视口而不是 display:none(display:none 的字段部分爬虫不填) */
.comment-hp {
position: absolute;
left: -9999px;
width: 1px;
height: 1px;
overflow: hidden;
}
/* 只需登录才能评论的提示 */
.comments-login-required {
margin: 0;
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: var(--yq-primary-dark, #0089db);
text-decoration: none;
}
.comments-login-required a:hover {
text-decoration: underline;
}
/*--------------------------------------------------------------
8. 无障碍:屏幕阅读器专用文本
--------------------------------------------------------------*/
.k-main .details .comments .sr-only {
position: absolute;
overflow: hidden;
clip: rect(0, 0, 0, 0);
width: 1px;
height: 1px;
padding: 0;
border: 0;
margin: -1px;
white-space: nowrap;
}
/*--------------------------------------------------------------
9. 响应式
--------------------------------------------------------------*/
@media screen and (max-width: 768px) {
.k-main .details .comments {
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: 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,
.yang-comment-avatar-ph {
width: 36px;
}
.yang-comment-avatar img,
.yang-comment-avatar-img,
.yang-comment-avatar-ph {
height: 36px;
}
.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: 12px;
margin-top: 3px;
}
.yang-children .yang-children {
padding-left: 9px;
}
.yang-children .yang-children .yang-children {
padding-left: 0;
border-left: 0;
}
.comment-info {
flex-direction: column;
gap: 8px;
}
.comment-field {
flex: 1 1 auto;
}
.comment-bar {
flex-wrap: wrap;
gap: 8px;
}
.comment-bar-right {
flex: 1 1 100%;
justify-content: space-between;
}
.comment-status {
flex: 1 1 auto;
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,
.yang-comment-avatar-ph {
width: 32px;
}
.yang-comment-avatar img,
.yang-comment-avatar-img,
.yang-comment-avatar-ph {
height: 32px;
}
/* ⚠️ 必须一并覆盖深层头像。
上面的基础规则里有 `.yang-children .yang-children .yang-comment-avatar
{ width: 34px }`,它选择器特异性 (0,3,0) 高于这里的 `.yang-comment-avatar`
(0,1,0) —— 媒体查询**不增加**特异性。所以只写这一条的话,窄屏下
深层头像仍是 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;
}
.comment-smile-panel {
width: 216px;
}
}
/* 尊重"减少动效"偏好:动画全部关掉,但保留视觉状态(颜色、阴影) */
@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. 打印:评论不需要按钮
--------------------------------------------------------------*/
@media print {
.comments-jump-form,
.yang-comment-actions,
.comments-more,
.comment-respond {
display: none !important;
}
.k-main .details .comments {
box-shadow: none;
}
.yang-comment-content {
color: #000;
}
}