/*! * 评论区样式 * Yongquan Yang * * ── 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`。 * 原因:`
    ` 是 `
  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; /* 同层细分隔 */ /* 嵌套引导线:直接用主色(「发布评论」按钮的背景色)。 * 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 输出的是 *
  2. *
    …
    *
    …
    *
      …子评论…
    ← 也是 li 的直接子元素 *
  3. * 若 li 用 display:flex,那个
      就成了**第三个 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 过滤器插入的 ) */ .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; } /* 3.2.25 所见即所得编辑区:顶替原 textarea 的可视位置。 * 边框 / 底色 / 聚焦态都挂在 .comment-textarea 容器上(focus-within), * 编辑区本体只管排版 —— 整框仍是"一个编辑器"的观感。 */ .k-main .details .comments .comment-respond .comment-textarea .comment-editor, .comment-textarea .comment-editor { min-height: 136px; max-height: 420px; overflow-y: auto; padding: 12px 14px; border: 0; background: none; color: #2b3038; font-family: inherit; font-size: 14px; line-height: 1.5; word-break: break-word; outline: none; cursor: text; -webkit-appearance: none; } .comment-editor:focus { outline: none; } /* 占位符:编辑区为空时显示(:empty 由 input 监听保真空) */ .comment-editor:empty::before { content: attr(data-placeholder); color: var(--yq-text-3, #6b7280); pointer-events: none; } /* 编辑区里的表情图:跟正文字号走,基线对齐 */ .comment-editor .yang-editor-emoji { height: 1.25em; vertical-align: -0.25em; margin: 0 1px; } /* 工具条:加粗 / 斜体 / 字体颜色 / 表情。 * * 位于输入框上方,与 textarea 同在 .comment-textarea 这个带边框的 * 容器里 —— 工具条铺满容器顶部,输入框一聚焦整框(含工具条) * 一起亮主色描边,视觉上是"一个编辑器",而不是两条孤立的横条。 * 面板(色板 / 表情)从按钮**下方**弹出:按钮在容器顶部, * 向上弹会飘到表单外面盖住上文,向下弹只盖住自己的输入区。 */ .comment-toolbar { display: flex; align-items: center; gap: 2px; padding: 5px 9px; border-bottom: 1px solid #edf0f4; border-radius: var(--yq-radius, 4px) var(--yq-radius, 4px) 0 0; background-color: #fafbfc; } /* 面板的定位父级:每个带面板的按钮各包一层 */ .comment-tool-group { position: relative; display: flex; align-items: center; } /* 按钮组之间的细分隔线 */ .comment-toolbar-sep { align-self: center; width: 1px; height: 16px; margin: 0 5px; background-color: #e2e7ee; } .comment-tool-btn { display: inline-flex; align-items: center; justify-content: center; min-width: 30px; height: 30px; padding: 0 7px; border: 0; border-radius: var(--yq-radius, 4px); background: none; color: var(--yq-text-2, #4b5563); font-size: 14px; line-height: 1; cursor: pointer; transition: color 0.16s var(--yq-ease), background-color 0.16s var(--yq-ease); } .comment-tool-btn:hover { background-color: var(--yq-primary-soft, #eaf6ff); color: var(--yq-primary-dark, #0089db); } .comment-tool-btn:focus-visible { outline: 2px solid var(--yq-primary, #00a2ff); outline-offset: 1px; } /* 字形:B 用粗体、I 用衬线斜体,一眼能认出对应排版效果 */ .comment-tool-glyph { display: inline-block; font-family: inherit; font-size: 14.5px; line-height: 1; } .comment-tool-glyph-bold { font-weight: 700; } .comment-tool-glyph-italic { font-family: Georgia, "Times New Roman", serif; font-style: italic; font-weight: 600; } /* 颜色按钮:字母 A 底下压一条渐变色条,点开是色板 */ .comment-tool-glyph-color { position: relative; font-weight: 600; } .comment-tool-glyph-color::after { content: ""; position: absolute; left: 1px; right: 1px; bottom: -3px; height: 3px; border-radius: 2px; background: linear-gradient(90deg, #e74c3c 0%, #f1c40f 30%, #2ecc71 55%, #00a2ff 80%, #9b59b6 100%); } /* 色板:8 个圆点,从按钮下方弹出 */ .comment-color-panel { position: absolute; top: calc(100% + 6px); left: 0; z-index: 21; display: flex; flex-wrap: wrap; gap: 6px; width: 164px; padding: 10px; 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-color-panel[hidden] { display: none; } .comment-color-swatch { width: 20px; height: 20px; padding: 0; border: 1px solid rgba(0, 0, 0, 0.08); border-radius: 50%; cursor: pointer; transition: transform 0.12s var(--yq-ease), box-shadow 0.12s var(--yq-ease); } .comment-color-swatch:hover { transform: scale(1.18); box-shadow: 0 0 0 2px #fff, 0 0 0 3.5px var(--yq-primary, #00a2ff); } .comment-color-swatch:focus-visible { outline: 2px solid var(--yq-primary, #00a2ff); outline-offset: 1px; } /* 底栏:表情移进工具条后只剩状态提示 + 提交按钮 */ .comment-bar { display: flex; align-items: center; justify-content: flex-end; 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-right { display: flex; align-items: center; gap: 8px; } /* 表情按钮:并入工具条后尺寸与其它工具按钮一致(原 4px 8px 小药丸) */ .comment-smile-btn { min-width: 30px; height: 30px; padding: 0 7px; font-size: 16px; } .comment-smile-btn:hover { background-color: var(--yq-primary-soft, #eaf6ff); color: var(--yq-primary-dark, #0089db); } /* 表情面板:按钮在容器顶部,改为**向下**弹出(原 bottom 定位作废) */ .comment-smile-panel { position: absolute; top: calc(100% + 6px); 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; } }