From fb1fda689c38bc770e8cab7f06f0fe6050a2ba31 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 16 Sep 2026 11:51:16 +0800 Subject: [PATCH] =?UTF-8?q?fix(web):=20=E5=9B=BE=E6=A0=87=E5=B0=BA?= =?UTF-8?q?=E5=AF=B8=E8=A6=86=E7=9B=96(text-[Npx])=E5=9C=A8=E4=BB=BB?= =?UTF-8?q?=E4=BD=95=E5=9C=B0=E6=96=B9=E9=83=BD=E4=B8=8D=E7=94=9F=E6=95=88?= =?UTF-8?q?=E2=80=94=E2=80=94CSS=E5=B1=82=E7=BA=A7=E5=86=B2=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因:Material Icons的Google Fonts样式表(index.html的)自己的 .material-icons规则完全没有@layer包裹(纯普通CSS),而Tailwind v4的 每一个工具类都在@layer utilities里——CSS Cascade Layers规范规定,任 何未分层的声明,不管选择器优先级多高、样式表加载顺序多晚,永远优先于 任何分层声明。实测坐实:的计算样式恒 定是font-size:24px,不管试图覆盖成几px都没用,因为Google那条未分层 规则永远赢。这不是某一处的问题,是Icon组件全局的、此前从未被发现的 系统性bug——历史上多轮视觉审查用截图核对布局,没人具体去量过某个 图标的computed font-size。 修复:Icon.tsx改用自己的im-icon类名,不再用material-icons这个 Google样式表实际瞄准的类名,这样那条未分层规则从一开始就不会匹配到 这些元素。index.css里用@layer base原样照抄了Material Icons自己那条 规则的视觉默认值(24px/line-height:1等),套上分层之后,Tailwind自己 的@layer utilities(在Tailwind的层注册顺序里排在base之后)就能正常 覆盖它了——和每一处写`text-[Npx]`时本来就该有的效果一致。 全局仓库搜索确认material-icons这个类名只有Icon.tsx一处引用,改动范围 可控、不涉及其它代码路径。 Co-Authored-By: Claude Sonnet 5 --- web/src/app/Icon.tsx | 9 +++++++-- web/src/index.css | 30 ++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/web/src/app/Icon.tsx b/web/src/app/Icon.tsx index 298d7761..5270ce26 100644 --- a/web/src/app/Icon.tsx +++ b/web/src/app/Icon.tsx @@ -1,10 +1,15 @@ /** Thin wrapper around a Material Icons ligature glyph (font loaded in index.html). * Always `aria-hidden` -- the glyph's DOM text is the icon's internal ligature name (e.g. * "arrow_back_ios_new"), never something a screen reader should announce. An icon-only - * interactive element (button/link with no visible text) must set its own `aria-label`. */ + * interactive element (button/link with no visible text) must set its own `aria-label`. + * + * Deliberately `im-icon`, NOT Google Fonts' own `.material-icons` class -- see index.css's own + * comment on that rule for why: Google's stylesheet ships that class completely unlayered, which + * under CSS Cascade Layers always outranks Tailwind's layered utilities regardless of specificity + * or source order, silently ignoring every `text-[Npx]` size override across the whole app. */ export function Icon({ name, className = '', style }: { name: string; className?: string; style?: React.CSSProperties }) { return ( -