Files
wordpress-kratos-yang/assets/css/comments.css
T
laoyang 78fce2d87d 3.2.23 评论区:引导线和输入框聚焦统一成主色
用户对 3.2.22 的反馈:
「这蓝色有点奇怪啊,应该用主题颜色,就是评论的那个按钮背景色。
  把评论回复左侧那个竖着的小蓝条,改成这个颜色,下面输入框被选中的
  时候,周边的颜色,也变成这个颜色。」

1. 引导线 #cfe6fb → var(--yq-primary)
   浅蓝和「发布评论」按钮的背景色(#00a2ff)不是一个蓝,
   页面上两蓝并存反而显乱。改成引用主色变量,以后改主色线自动跟。

2. 输入框聚焦变主色 —— 顺带翻出一个藏了三版的老问题
   实测发现正文输入框聚焦后边框仍是灰色:kratos.css 里
     .k-main .details .comments .comment-respond .comment-textarea
       { border: 1px solid #eee; ... }
   特异性 0,6,0,把 comments.css 的静态边框(0,1,0)、hover 变深
   (0,2,0)、focus 变主色(0,2,0)全部压死。也就是说 3.2.20 重做
   以来,正文框的边框色、圆角、浅底、悬停变色、聚焦变色**全部
   从未真正上线**,用户看到的一直是基础主题的 #eee / 3px / 灰底,
   聚焦时只有一圈很淡的外环是主色的。

   修法:textarea 的静态 / hover / focus 三态都改用同样的
   0,6,0 选择器收编(本表依赖 kratos 后加载,每条稳定压过)。
   不去改 kratos.css —— 那是基础主题,改它等于放弃覆盖层架构。

   姓名/邮箱/网址那排 input 不受影响(kratos.css 没对它们写边框),
   聚焦本来就是主色。

3. 新增线上判据并先证明它能红
   ④ 引导线颜色 = 主色(动态取 .comment-submit 背景色做参照,
      不写死 RGB,主色一改判据自动跟);
   ⑧ 真实点击姓名框与正文框、等 0.16s 过渡结束后量边框色。
   部署前在 3.2.22 线上跑:④⑧ 正确变红、几何项依旧全绿——
   判据有效,不是空转。

只改样式表与版本号,评论的取数、分页、回复、加载更多逻辑未动。
2026-10-24 20:49:41 +08:00

1300 lines
40 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; /* 同层细分隔 */
/* 嵌套引导线:直接用主色(「发布评论」按钮的背景色)。
* 3.2.22 之前用浅蓝 #cfe6fb,用户反馈"这蓝色有点奇怪,应该用主题颜色"——
* 浅蓝和主色按钮不是一个蓝,两蓝并存反而显乱,索性同色。
* 引用 --yq-primary 而不是再写一个色值:以后改主色,线自动跟。 */
--yq-guide: var(--yq-primary, #00a2ff);
--yq-bg-soft: #f7f9fb;
--yq-bg-input: #fcfcfd;
--yq-radius: 4px;
--yq-radius-lg: 6px;
/* 子回复的缩进量(见第 5 节的推导)。
* 公式:头像宽 + 列间距
* 桌面 42+13 = 55 / ≤768 36+10 = 46 / ≤400 32+10 = 42。
*
* ⚠️ 3.2.22 起**不再减引导线宽**。上一版引导线是容器的 border-left,
* 而 padding-left 从边框内侧算起,所以那个 2px 必须扣掉;
* 现在引导线改成绝对定位的伪元素、完全不占布局,扣掉反而会让
* 子回复整体左移 2px。缩进从此就是纯粹的「父正文左边缘距父 li 多远」。
*
* 存在变量里是因为它必须和头像宽度、列间距**同时**在断点里改,
* 分散写三处迟早漏一处(上一版就是这么漏掉 img 宽度的)。 */
--yq-indent: 55px;
--yq-indent-deep: 30px;
/* 引导线的宽度。单独抽出来是给两处用:伪元素的 width,
* 以及"线要贴在正文左边缘的左侧"这个位移量(见第 5 节)。
* 改成 2px 以外还要同时看 --yq-indent 的定义,别只改一处。 */
--yq-guide-w: 2px;
/* 统一动效曲线:进出都用同一条,避免"有的滑有的弹" */
--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;
}
/* 标题:不加任何装饰。
* 曾经在左侧加过一条主色竖条 —— 用户明确要求去掉:标题本身字重足够,
* 竖条只是多余的视觉噪音,而且它逼着标题让出 12px 左内边距,
* 让「评论」两个字和下方评论正文的左边缘对不齐。 */
.comments-head .title {
margin: 0;
color: #1f2328;
font-weight: 600;
font-size: 19px;
line-height: 1.4;
letter-spacing: -0.005em;
}
/* 「写下你的评论」:原来用 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)
* ② 引导线(::before 绝对定位的竖线)
* ③ 头像尺寸(42 → 34)
*
* ── 缩进值是怎么算出来的(别随手改)────────────────────────────
* 目标:**子回复那一块的左边缘,正好落在父评论正文的左边缘上**。
*
* 父评论一行是 `[头像 42][列间距 13][正文…]`,所以父正文左边缘
* 距父 li 左边缘 42 + 13 = 55px。`ol.yang-children` 是父 li 的
* 直接子元素、从父 li 左边缘起算,所以
*
* padding-left = 头像宽 + 列间距 = 42 + 13 = 55px
*
* 就精确对齐了,不是"接近"。768 / 400 两个断点头像与列间距都变小,
* 这个值必须跟着换(46 / 42),否则窄屏上子回复会突出去。
*
* ── 引导线为什么改成伪元素(3.2.22)──────────────────────────
* 原来它写在容器的 border-left 上,于是只能贴在**父 li 的左边缘** ——
* 也就是父头像那一列。但子回复整块已经右移到父正文的位置了,
* 线却还留在最左边,中间空出 55px,看起来像"线和内容脱节了"。
*
* 用户明确要求:**线也要跟着右移,和上面评论的正文对齐**。
* border 做不到(它只能贴在盒子的外沿),所以改用绝对定位的伪元素,
* 位置由 --yq-indent 决定 —— 断点里改缩进,线会自动跟着走,不会脱节。
*
* 线的定位取 `left: calc(indent - 线宽)`,让线的**右边缘**与正文左边缘
* 重合,于是线完全落在头像左侧、不压头像(头像有一圈 1px 描边,压上去会脏)。
* 视觉上就是"一条竖线紧贴正文左边缘",这也正是用户要的对齐。
*
* ⚠️ 缩进仍然只能用 padding-left,**不能用 margin-left**:
* `_diag318_children_geo.js` 判据 A 要求 `ol.yang-children` 的
* 左偏移(相对父 li)≤4px、判据 B 要求宽度 ≥ 父宽 90%。
* margin-left 会同时破坏这两条,padding-left 不会。
* (伪元素是绝对定位、不参与布局,所以加它不影响这两条判据。)
*
* 引导线用主题主色的浅色版 #cfe6fb(和「写下你的评论」按钮的描边
* 同一个色)—— 原来是灰蓝 #dbe6f2,用户要求改成主题自带的浅蓝。 */
.yang-children {
position: relative;
margin-top: 4px;
padding-left: var(--yq-indent, 55px);
}
/* 竖线本体。不占布局,所以不会像 border 那样把内容再推 2px。
* top/bottom 撑满整块,等价于原来 border-left 的长度。
* pointer-events: none —— 它压在 padding 区域上,别让它拦住点击。 */
.yang-children::before {
content: "";
position: absolute;
top: 0;
bottom: 0;
left: calc(var(--yq-indent, 55px) - var(--yq-guide-w, 2px));
width: var(--yq-guide-w, 2px);
background-color: var(--yq-guide, #cfe6fb);
pointer-events: none;
}
.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;
}
/* 第三层起改用更小的缩进(--yq-indent-deep),并去掉引导线。
*
* 为什么必须减小:padding-left 是**逐层累加**的。第一层 55px 对齐好看,
* 但到第三层就是 55×3 = 165px —— 390px 屏上正文只剩 100 多像素,
* 长文会被切成竖条。所以从第三层起换成 30px,三层累计 55+55+30 = 140px,
* 仍然呈现递进,但不再失控。
*
* 引导线也去掉:三条竖线平行叠在一起会变成"表格"观感,反而更难读。
* 3.2.22 起线是伪元素,所以这里要 **content: none** 把它整个关掉,
* 而不是像以前那样改 border-left-color —— 伪元素没有"透明色"的需求,
* 直接不生成更干净(也不会残留一个不可见的绝对定位盒)。
*
* ⚠️ 这里**必须显式设 padding-left**,不能只关掉线 ——
* 否则它会继承上一层的 55px,与"减小"的意图正好相反。
*
* 注:去掉 border 后,这里的 30px 变成"纯粹的偏移量"。
* 上一版因为 border 占 2px,实际偏移是 32px;差这 2px 对第三层
* 的观感没有影响,且方向是略微更宽松,不去追平。 */
.yang-children .yang-children .yang-children {
padding-left: var(--yq-indent-deep, 30px);
}
.yang-children .yang-children .yang-children::before {
content: none;
}
/* 新提交的评论:淡入 + 短暂底色,让用户看到自己刚发的那条 */
@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: var(--yq-primary-soft, #eaf6ff);
}
/* 从通知/后台带 #comment-123 跳过来时,高亮那一条。
*
* ── 这就是「有些回复下面有黄色背景、有些没有」的原因 ──────────
* 底色是暖黄 #fffbe8。它只在**链接里带了该条评论的锚点**时出现
* (:target 伪类),所以:
* · 从评论通知邮件点进来 → URL 末尾有 #comment-1234 → 那一条是黄的;
* · 自己正常打开文章 → 没有任何锚点 → 一条都不黄。
* 于是同一个页面上"有的黄有的不黄",看起来像随机。
*
* ── 3.2.21 曾改成浅蓝,3.2.22 按用户要求改回黄色 ───────────────
* 3.2.21 的考虑是"全站只有待审核用暖色,这里再用黄会混淆"。
* 但用户明确指出:**这就是为了突出显示锚点,还是用黄色**。
* 这个判断是对的 —— 锚点高亮是一次性的、需要"跳出来"的提示,
* 浅蓝和引导线、按钮描边同色系,反而被当成背景噪音忽略掉;
* 暖黄在一个全蓝的页面里立刻能看见。
*
* 与 is-new 的分工因此变得清楚:
* · :target → 暖黄(一次性,指路)
* · is-new → 浅蓝(即时反馈,我刚发的)
* 两者不再撞色,同页出现也能分辨。 */
.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 容器。
*
* 🔴 三态(静态 / hover / focus)都必须带
* `.k-main .details .comments .comment-respond` 前缀 —— 不是为了好看,
* 是为了**特异性**。kratos.css 里有
* .k-main .details .comments .comment-respond .comment-textarea
* { border: 1px solid #eee; border-radius: 3px; background: 灰 }
* 特异性 0,6,0。我们下面不带前缀的三条只有 0,1,0 / 0,2,0,
* **一条都赢不了** —— 也就是说 3.2.20 重做以来,正文框的
* 边框色(#dfe4ec)、圆角(4px)、浅底(#fcfcfd)、hover 变深、
* focus 变主色,**全部从未真正上线**,用户看到的一直是
* kratos.css 的 #eee / 3px / 灰底,focus 时只有那圈外环是我们的。
* 3.2.23 用户指出"输入框选中时周边颜色不对",才把这个老问题翻出来。
*
* 修法:同选择器(0,6,0)+ 三态伪类(各再 +0,1,0),且本表
* 依赖 kratos 后加载 —— 每条都稳定压过基础主题。 */
.k-main .details .comments .comment-respond .comment-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);
}
.k-main .details .comments .comment-respond .comment-textarea:hover:not(:focus-within),
.comment-textarea:hover:not(:focus-within) {
border-color: #cdd6e2;
}
/* focus:边框与外环都是主色(「发布评论」按钮的背景色)——
* 3.2.23 用户要求:"输入框被选中的时候,周边的颜色,也变成这个颜色"。 */
.k-main .details .comments .comment-respond .comment-textarea:focus-within,
.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;
}
/* 缩进量必须和下面的头像宽度、列间距同步改:
* 头像 36 + 列间距 10 = 46(3.2.22 起不再扣引导线宽,理由见变量定义处);
* 深层要更省空间,取 26。写在这里(.comments 上)是因为变量
* 定义在 .comments 作用域,媒体查询里重新赋值就能让所有后代取到新值 ——
* 引导线的位置是 `calc(indent - 线宽)`,所以它自动跟着走,不用另写一遍。 */
.comments {
--yq-indent: 46px;
--yq-indent-deep: 26px;
}
.comments-head {
flex-wrap: wrap;
gap: 8px;
padding-bottom: 13px;
}
.comments-head .title {
font-size: 17px;
}
.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;
}
/* 窄屏的缩进值改在 `.comments` 的变量里统一设(见本节开头),
这里不再单独写 .yang-children 的 padding-left —— 上一版就是在
两个地方分别写死,改一处忘一处,深层的 9px/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) {
/* 同样要同步缩进:头像 32 + 列间距 10 = 42;深层取 22。 */
.comments {
--yq-indent: 42px;
--yq-indent-deep: 22px;
}
/* 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;
}
}