BWiki CSS 编写与调试指南

BWiki CSS 编写与调试指南

1. 方法选择策略

决策流程图

根据使用场景选择最合适的 CSS 实现方式:

  1. 小块安全样式 / 快速验证(需要即时生效)→ 使用 #css(内联方式,绕过 URL 缓存)
  2. 需要高级功能url() / var() / filter() / calc())→ 使用 <bstyle>(内联方式,支持完整语法)
  3. 一次性微调 → 临时使用 style="..."(后续迁移到 1 或 2)
  4. 多页面复用结构组件 → 使用 Widget(配合哨兵变量防止重复)
  5. 稳定全站规范 → 使用 Common.css / 皮肤 CSS(URL 缓存约30分钟,不宜频繁修改)

常见错误与改进方案

错误做法问题解决方案
重复粘贴 <bstyle>代码重复、难维护模板化 + 哨兵机制
大量内联 style不可搜索、难复用合并到 #css/<bstyle>
频繁改 Common.css缓存30分钟,效果慢先内联验证再合并
全站差异写 Common.css污染全局用页面/模板级样式
滥用 !important调试困难提高选择器层级

2. 四种实现方式详解

2.1 #css 解析函数(推荐默认方式)

安全性最高:经过 Sanitizer::checkCss() 安全检测,不支持被标记为”不安全”的函数和属性。采用内联注入方式,修改后刷新页面立即生效,无需等待 URL 缓存。

语法示例:

{{#css: .my-box { padding:8px; background:#f6f6f6; }}}
{{#css: 模板:MyStyles/main.css}}

处理流程:

  1. 检查参数是否为存在的页面标题 → 如果是,按页面原始内容(action=raw)加载
  2. 如果以 / 开头 → 按服务器相对路径加载
  3. 否则视为内联 CSS 代码 → 安全检测 → Base64 编码 → 注入到 <head> 中的 data:text/css

受限功能(会被替换为 /* insecure input */):

  • url()var()filter()calc()image()expression()
  • 特殊前缀属性(如 -o-link) 需要这些功能时请使用 <bstyle>

适用场景:轻量级、局部样式、无需 CSS 变量;快速验证,避开全局30分钟缓存

2.2 <bstyle>(功能完整的块级样式)

完整语法支持:支持 CSS 变量、背景图片、calc() 计算等高级功能。同样是内联方式,更新即时生效,但需要自行控制安全性和代码体积。

语法示例:

<bstyle>/*<pre>*/
.hero-section {
  --primary-color: #3b82f6;
  background: url(https://example.com/bg.jpg) center/cover no-repeat;
  color: var(--primary-color);
}
/*</pre>*/</bstyle>

重要提示:必须保留 /*<pre>*/ ... /*</pre>*/ 注释包装,避免解析器插入 P 标签或破坏代码缩进。

2.3 内联 style 属性(仅限临时实验使用)

示例:

<div style="border:1px solid #ccc; padding:6px; font-size:90%">提示内容</div>

使用风险:样式代码分散,难以检索和维护 → 建议最终迁移到集中管理的样式表中

2.4 Widget 扩展(结构复用 + 样式封装)

调用方式:

{{#widget:CustomInfobox}}

Widget 内部结构示例:

<div class="infobox-template">
  <style>
    .infobox-template {
      background: #f8f9fa;
      border-left: 4px solid #3b82f6;
      padding: 16px;
      margin: 16px 0;
    }
  </style>
  说明文本内容
</div>

适用场景:信息卡片、标签集合、交互式容器等可复用组件。需要管理员权限创建和维护。


3. 模板 CSS 去重机制

问题背景

当同一模板在页面中被多次调用时,会导致 CSS 样式重复注入,造成:

  • 代码体积膨胀:相同的样式被多次加载
  • 覆盖链混乱:重复的样式可能相互干扰
  • 性能低下:内联重复样式不受缓存合并优化

统一解决方案:变量哨兵机制

使用变量作为标志位,确保样式只注入一次:

#css 方式去重:

{{#if:{{#varexists:CSS:MyTemplate}} ||
  {{#vardefine:CSS:MyTemplate|1}}
  {{#css:
    .my-template-styles {
      /* 样式定义 */
    }
  }}
}}

<bstyle> 方式等价实现:

{{#if:{{#varexists:模板样式CSS}} ||
  {{#vardefine:模板样式CSS|1}}
  <bstyle>/*<pre>*/
  /* 组件独占样式 */
  /*</pre>*/</bstyle>
}}

命名规范建议

  • 变量命名:使用 CSS:模板名 格式,避免命名冲突
  • 单一职责:一个模板对应一个哨兵变量
  • 清晰标识:变量名应明确标识对应的模板和样式用途

4. CSS 优先级与加载顺序

级联层次(从低到高)

  1. 核心样式(MediaWiki Core)
  2. 扩展样式(Bootstrap、BWiki平台样式等)
  3. 站点公共样式MediaWiki:Common.css
  4. 皮肤样式MediaWiki:Vector.css
  5. 页面级样式#css / <bstyle>
  6. 标签内联样式style="..."

策略建议

  • 保持”越局部越后置”:局部样式应该放在更后的位置
  • 减少 !important 使用:优先通过提高选择器特异性来解决问题
  • 实验优先内联:先使用局部内联方式验证,稳定后再合并到全局(需要考虑缓存等待时间)

5. 调试标准流程

系统化调试步骤

步骤目标操作预期结果
0. 缓存检查确认文件版本无效时用 ?action=purge刷新后生效
1. 元素定位锁定目标元素右键检查或 F12选中 DOM 节点
2. 选择器验证确认匹配hover CSS 规则元素高亮命中
3. 覆盖分析确定覆盖关系看 Styles 面板划线找到更高规则
4. 临时验证验证思路DevTools 改值期望效果出现
5. 修改归档固化修改写回模板/片段命名一致
6. 缓存清理确保更新?action=purge新内容显示

快速问题诊断:五类常见根因

当样式”没有生效”时,优先检查以下五类原因:

  1. URL 缓存未过期:全局样式有约30分钟缓存
  2. 加载失败:样式文件或资源加载错误
  3. 语法被过滤:使用了被安全机制拦截的语法
  4. 选择器未命中:选择器无法匹配目标元素
  5. 被其他规则覆盖:被更高特异性或后置的规则覆盖

6. 常见问题与解决方案

现象原因解决方案
Common.css 无变化URL 缓存未过期等待或用内联验证
CSS 被注释掉触发安全过滤<bstyle> 或移除禁用指令
<bstyle> 含 HTML缺失 /*<pre>*/ 注释补充注释包装
样式顺序混乱模板重复注入使用哨兵去重
移动端错位无响应式断点@media 查询
样式不生效特异性低/被覆盖增加父级限定
滥用 !important层次设计差重构结构

7. 最佳实践指南

7.1 命名规范(语义化 + 作用域 + 角色)

推荐命名示例:

  • infobox-character(信息框-角色)
  • card--featured(卡片-特色样式)
  • btn-primary(按钮-主要样式)

避免的命名:

  • contentheaderbox1(过于通用,缺乏语义)

7.2 与 Bootstrap 3.7 协同工作

充分利用现有能力:

  • 栅格系统:.row + .col-md-*
  • 按钮组件:.btn 及相关变体
  • 辅助工具类:.text-center.mt-3

扩展策略:不要直接覆盖核心类

/* 正确:使用前缀容器限定作用域 */
.my-widget .btn { border-width: 2px; }
.my-layout .col-md-6 { padding: 20px; }
 
/* 响应式适配 */
@media (max-width: 768px) {
  .my-card { margin-bottom: 12px; }
}

7.3 性能优化要点

  • 选择器深度:避免超过3层的深层选择器,酌情重构
  • 避免通配符:不要使用 * 选择器,影响性能
  • 变量管理:CSS 变量集中在 <bstyle> 或全局样式表中
  • 去重机制:使用哨兵变量防止重复注入
  • 迭代策略:实验阶段使用内联方式,稳定后合并到全局(减少缓存等待)

7.4 可访问性(A11y)考虑

/* 类链接样式 */
.link-like {
  color: #0a63c9;
  text-decoration: underline;
}
.link-like:focus {
  outline: 2px solid #0a63c9;
  outline-offset: 2px;
}
 
/* 视觉隐藏但保持可访问性 */
.is-hidden-visually {
  position: absolute;
  clip: rect(1px, 1px, 1px, 1px);
  width: 1px;
  height: 1px;
  overflow: hidden;
}

7.5 CSS 变量集中管理

/* 在根元素或全局样式中定义变量 */
:root {
  --color-accent: #3b82f6;
  --radius-sm: 4px;
}
 
/* 使用变量保持一致性 */
.panel {
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-accent);
}

8. 反模式与改进方案

反模式问题替代方案
CSS 写业务逻辑不稳定、难维护用语义 class 表示状态
复制粘贴 <bstyle>维护困难模板 + 哨兵去重
全局覆盖核心类破坏其他模块父容器限定作用域
滥用绝对定位响应式失效用 Flex/Grid 布局
透明图片占位过时技术min-height/空容器

9. 学习资源与工具推荐

精选学习资源

资源分类链接简介
MDN CSS 指南https://developer.mozilla.org/zh-CN/docs/Web/CSS全面参考文档
CSS 选择器https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Selectors选择器语法详解
CSS 变量https://developer.mozilla.org/zh-CN/docs/Web/CSS/Using_CSS_custom_properties变量使用指南
Flexboxhttps://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Flexible_Box_Layout弹性布局教程
Gridhttps://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Grid_Layout网格布局系统
响应式设计https://developer.mozilla.org/zh-CN/docs/Learn/CSS/CSS_layout/Responsive_Design响应式原理实践
BEM 方法论http://getbem.com/命名方法论
CSS 性能https://developer.mozilla.org/zh-CN/docs/Web/Performance/CSS性能最佳实践
W3C 验证器https://jigsaw.w3.org/css-validator/代码验证工具
CodePenhttps://codepen.io/在线编辑平台
CSS-Trickshttps://css-tricks.com/技巧教程网站
Stack Overflowhttps://stackoverflow.com/questions/tagged/css技术问答社区

10. 缓存机制速览

类型形态缓存时间用途
Common.css/皮肤CSSURL 资源~30min全站规范
#css 代码块内联即时小块/快速验证
<bstyle>内联即时完整语法组件
模板 raw CSSURL 资源~30min复用低改动样式
Widget <style>内联即时结构+样式复用

附录:常用代码片段

轻量卡片样式

{{#css:
.card-lite {
  background: #fff;
  border: 1px solid #e3e5e8;
  padding: 12px;
  border-radius: 4px;
}
}}

CSS 变量定义和使用

<bstyle>/*<pre>*/
:root {
  --accent-color: #3b82f6;
}
.accent-text {
  color: var(--accent-color);
}
/*</pre>*/</bstyle>

调试辅助样式

/* 突出显示待检查区块 */
.debug-outline * {
  outline: 1px dashed rgba(0, 0, 0, 0.25);
}

总结

遵循系统化的 CSS 开发流程:

  1. 根据缓存特性选择合适的方式
  2. 使用内联方式进行快速验证
  3. 通过模板化和哨兵机制实现去重
  4. 稳定后再合并到全局样式
  5. 控制选择器特异性和性能
  6. 采用统一的命名规范
  7. 建立可观测的调试流程

最终目标:实现稳定、可维护、可迭代的 CSS 架构。

每一次修改都应遵循:明确意图 → 局部验证 → 归档整合 → 预估缓存影响