news 2026/10/30 1:04:44

TIA Portal中LAD/FBD/STL/SCL注释技巧与避坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
TIA Portal中LAD/FBD/STL/SCL注释技巧与避坑指南

1. 为什么“注释代码”这件小事值得单独拿出来讲

在STEP 7(TIA Portal)里写程序,注释代码这件事看起来简单到不值一提——不就是加两个斜杠或者括号吗?但真正在项目里摸爬滚打过几年的人都知道,注释代码的方式、时机和粒度,直接决定了你后期调试和交接的效率。尤其是在LAD、FBD、STL和SCL这四种语言混用的项目里,注释的写法完全不一样,稍不注意就会踩坑。

我自己带过好几个用TIA Portal V16做产线改造的项目,PLC程序里既有梯形图写的安全逻辑,也有SCL写的配方管理和数据处理,还有从老设备移植过来的STL代码。每次调试阶段需要临时屏蔽某段逻辑时,团队里总有人因为注释方式不对导致编译报错,或者更隐蔽的——注释掉了但实际还在执行。这些问题在手册里往往一笔带过,但在实际工程中会浪费大量时间。

这篇文章就是把这些年积累的注释技巧和踩过的坑整理出来。不管你是刚接触TIA Portal的新手,还是用了多年STEP 7但一直只用一种语言的老手,下面这些内容都能帮你少走弯路。我会按语言类型逐一拆解注释方法,重点讲清楚每种语言注释的底层逻辑、操作步骤、以及什么场景下该用哪种注释方式。特别是SCL语言,它的注释规则和LAD/FBD/STL差异最大,也是热搜里“sht30的scl接哪里”这类问题频繁出现的地方——很多人把传感器SCL引脚和编程语言SCL搞混,后面我也会顺带把这个概念理清楚。

2. 四种编程语言的注释机制到底差在哪

2.1 LAD和FBD:图形化语言的注释逻辑

LAD(梯形图)和FBD(功能块图)在TIA Portal里属于图形化编程语言,它们的注释方式和文本语言有本质区别。图形化语言里没有“注释掉一行代码”这种概念,因为程序本身是网络(Network)组成的图形结构。

在LAD/FBD中注释代码,实际上有两种理解:

第一种是给网络添加注释文本。这个操作很简单,选中网络后右键选择“属性”,或者直接在网络标题栏双击,就能输入注释内容。这种注释不会影响程序执行,纯粹是给读程序的人看的。我习惯在每个功能块的开头网络写清楚这段逻辑的用途、作者和修改日期,后期维护时能省很多沟通成本。

第二种是临时禁用某个网络或某段逻辑。在LAD/FBD里,你不能像文本语言那样把一段代码“括起来”注释掉。常见的做法是:

  • 选中需要禁用的网络,右键选择“禁用网络”(Disable Network)。这个操作会让该网络在编译时被跳过,但不会删除。需要恢复时再右键“启用网络”即可。
  • 如果只想禁用网络中的某一个分支或触点,可以选中该元素后按Delete删除,但这样会丢失逻辑。更稳妥的方式是在该分支上串联一个永远为假的条件,比如一个未使用的M位且保持为0,这样逻辑上等效于屏蔽。
  • 对于FBD中的某个输入引脚,可以临时断开连接线,但同样建议先记录原始连接关系。

注意:禁用网络这个操作在编译时会生成警告信息,但不会导致编译失败。如果你在团队协作中看到大量被禁用的网络,建议在提交前统一清理,否则后期很容易忘记哪些是故意禁用的、哪些是遗留的调试代码。

2.2 STL:语句表语言的注释方式

STL(语句表)是TIA Portal中比较接近底层汇编的文本语言,它的注释规则和SCL有相似之处,但细节不同。

在STL中,单行注释使用双斜杠//。比如:

// 这是一个单行注释 A "StartButton" // 读取启动按钮状态 JC START // 如果为1则跳转到START标签

STL不支持块注释(即不能像C语言那样用/* */括起多行)。如果你需要注释掉一整段STL代码,只能逐行加//,或者使用编辑器提供的“注释选中行”功能。在TIA Portal的STL编辑器里,选中多行后按Ctrl + K可以批量添加注释符号,按Ctrl + Shift + K可以取消注释。这个快捷键在LAD/FBD的文本注释框里也能用,但在图形网络中无效。

STL里还有一个特殊之处:跳转标签和注释的关系。如果你注释掉了一行包含跳转目标的代码,但跳转指令还在,编译会报错。比如:

JC OVER // 跳转到OVER标签 // OVER: // 如果这行被注释掉,上面的跳转就会找不到目标

这种情况下,要么把跳转指令也注释掉,要么保留标签行不注释。我个人的习惯是,在STL里做临时屏蔽时,优先注释掉跳转指令本身,而不是目标标签。

2.3 SCL:结构化控制语言的注释规则

SCL(Structured Control Language)是TIA Portal中类似Pascal的高级语言,它的注释规则和C语言系比较接近,支持两种注释方式:

  • 单行注释:使用双斜杠//,从该符号到行尾的内容都会被忽略。
  • 块注释:使用(*和*)括起来,可以跨多行。注意,SCL不支持/* */这种C风格注释,只能用(* *)。

举个例子:

// 这是单行注释 (* 这是块注释 可以跨多行 适合临时屏蔽大段代码 *) IF "StartButton" THEN "Motor" := TRUE; // 启动电机 (* "Alarm" := TRUE; // 这行被块注释屏蔽了 "Indicator" := FALSE; *) END_IF;

这里有个容易踩的坑:块注释不能嵌套。也就是说,你不能在一个(* *)里面再写一个(* *),编译器会认为第一个*)就结束了注释,后面的内容会被当作代码解析,大概率报错。如果你需要注释掉一段已经包含块注释的代码,只能改用逐行//的方式。

另外,SCL的块注释在TIA Portal的某些版本里对中文支持不太好。如果你在(* *)里写了中文,偶尔会出现编译警告或乱码。我的经验是,块注释里尽量用英文或拼音,单行注释//对中文的支持更稳定。

2.4 四种语言注释方式对比速查

语言单行注释块注释批量注释快捷键临时禁用网络/逻辑
LAD不支持不支持无右键禁用网络
FBD不支持不支持无右键禁用网络
STL//不支持Ctrl + K逐行注释或跳转屏蔽
SCL//(* *)Ctrl + K块注释或逐行注释

这张表建议截图保存,在项目现场调试时能快速查阅。特别是LAD/FBD和文本语言混用的时候,很多人会习惯性地在LAD里找//,结果发现根本没有输入注释的地方。

3. 在TIA Portal里实际操作:从选中到注释的完整流程

3.1 LAD/FBD中禁用网络的具体步骤

假设你有一段LAD程序,其中某个网络负责控制一台电机的启停,现在调试阶段需要临时屏蔽这段逻辑。操作步骤如下:

  1. 在项目树中打开对应的FC或FB块,切换到LAD视图。
  2. 在程序编辑区找到目标网络,单击网络左侧的灰色边框区域,选中整个网络。选中后网络边框会变成蓝色。
  3. 右键点击选中的网络,在弹出的上下文菜单中选择“禁用网络”。如果你用的是TIA Portal V16,这个选项可能在“编译”子菜单下,不同版本位置略有差异。
  4. 禁用后,网络标题栏会出现一个灰色的“已禁用”标记,网络内的逻辑颜色会变暗。
  5. 需要恢复时,重复上述步骤,选择“启用网络”。

这里有个细节:禁用网络后,该网络内的所有逻辑都不会被编译和执行,但网络内的变量声明和符号引用仍然会被检查。也就是说,如果你禁用了一个网络,但该网络里用到了一个已经被删除的变量,编译时仍然会报错。这一点和文本语言的注释不同——注释掉的内容完全不会被编译器看到。

实操心得:在多人协作的项目里,我建议在禁用网络的同时,在网络标题里写上禁用原因和预计恢复时间。比如“2024-03-15 临时屏蔽,等待传感器到货后恢复”。这样即使你休假了,同事也能判断这个网络该不该动。

3.2 STL中批量注释与取消注释

STL编辑器的批量注释功能比LAD/FBD方便得多。具体操作:

  1. 用鼠标拖选需要注释的多行代码,或者按住Shift键点击首尾行。
  2. 按Ctrl + K,选中的每一行开头都会加上//。
  3. 如果要取消注释,选中已注释的行,按Ctrl + Shift + K,编辑器会自动移除行首的//。

这个快捷键在TIA Portal的SCL编辑器里同样适用。但要注意,如果选中的行里已经包含单行注释,再按Ctrl + K会变成双重注释,取消时需要按两次Ctrl + Shift + K才能完全恢复。我见过有同事在调试时反复注释和取消,最后代码里残留了一堆////,虽然不影响编译,但看起来非常乱。

对于STL里的跳转标签,批量注释时要特别小心。如果标签行被注释掉了,但跳转指令还在,编译会直接报错“未找到跳转目标”。正确的做法是:

  • 先注释跳转指令行。
  • 再注释标签行。
  • 恢复时顺序相反。

3.3 SCL中块注释的边界处理

SCL的块注释(* *)在处理大段代码时非常方便,但边界情况需要留意。比如下面这段代码:

(* 这是一个块注释 IF "Condition" THEN "Output" := TRUE; END_IF; *)

如果这段注释出现在一个IF语句内部,而注释的结束位置恰好在一个语句中间,就可能出问题。比如:

IF "Start" THEN (* "Motor" := TRUE; "Valve" := TRUE; *) "Pump" := TRUE; END_IF;

这段代码是合法的,因为块注释完整地包含了两个赋值语句。但如果你这样写:

IF "Start" THEN (* "Motor" := TRUE; *) "Valve" := TRUE; (* "Pump" := TRUE; END_IF;

这里第二个块注释没有闭合,编译器会把后面的END_IF也当作注释内容,导致IF语句缺少结束标记,编译报错。所以使用块注释时,一定要确保(*和*)成对出现,并且不要跨越语句结构的边界。

我的个人习惯是:临时屏蔽少量代码用//逐行注释,屏蔽大段代码用(* *),但块注释的范围不会跨越IF...END_IF、FOR...END_FOR这类结构语句的边界。如果确实需要屏蔽整个结构,我会把结构语句也一起注释掉。

3.4 跨语言项目的注释策略

在实际项目里,一个FC块可能同时包含LAD网络和SCL程序段,或者一个FB块里既有STL写的底层逻辑,又有SCL写的数据处理。这种混合编程的情况下,注释策略需要统一规划。

我的做法是:

  • 在块头部用SCL或STL的注释方式写一个总说明,包括块的功能、作者、版本、修改记录。这个说明放在块的最前面,不参与逻辑执行。
  • 每个网络或程序段开头写简短注释,说明该段逻辑的用途。LAD/FBD用网络标题,STL/SCL用//。
  • 临时调试注释统一用//,避免块注释嵌套问题。调试完成后及时清理,不要留在最终版本里。
  • 对于需要长期保留但暂时不用的代码,用块注释(* *)包起来,并在注释开头写明“备用逻辑,勿删”。

这样做的原因是,混合编程时最容易出现的问题是:LAD网络被禁用了,但SCL里对应的变量还在被引用;或者STL里的跳转标签被注释了,但SCL里还有跳转到该标签的指令。统一的注释策略能减少这类跨语言引用错误。

4. 那些手册里不会写的注释避坑指南

4.1 注释掉代码不等于代码不执行

这是新手最容易犯的错误。在LAD/FBD里,禁用网络确实会让该网络不执行。但在STL和SCL里,注释掉代码只是让编译器忽略这些文本,如果被注释的代码里有对变量的赋值,这些赋值不会发生。听起来是废话,但实际项目中经常出现这样的情况:

// "Motor" := TRUE; // 这行被注释了 "Motor" := FALSE; // 这行还在执行

结果就是电机永远不会启动。调试时如果发现某个输出不对,第一件事就是检查是不是有注释掉的赋值语句影响了逻辑。

更隐蔽的是注释掉条件判断但保留了执行语句:

// IF "Enable" THEN "Output" := TRUE; // END_IF;

这种情况下,"Output" := TRUE;会无条件执行,因为IF和END_IF都被注释掉了。如果"Enable"本来是用来做安全联锁的,这就可能导致严重的安全问题。

注意:在安全相关程序(如F-CPU中的安全逻辑)里,绝对不要用注释的方式来临时屏蔽逻辑。安全程序有专门的禁用和旁路机制,必须按照安全手册操作。

4.2 SCL块注释里的中文和特殊字符

前面提到过,SCL的块注释(* *)对中文的支持在某些TIA Portal版本里不够稳定。我实测过V15、V16、V17三个版本,V16对中文块注释的兼容性最差,偶尔会出现编译后注释内容乱码,或者编译器把中文当成非法字符报错。

规避方法很简单:块注释里只写英文、数字和常用符号,中文注释一律用//单行注释。如果确实需要在块注释里写中文,可以在中文前后加空格,或者把块注释拆成多个单行注释。

另外,SCL里不支持/* */这种C风格注释。如果你从其他PLC平台(比如某些日系PLC)移植代码过来,习惯性地写了/* */,TIA Portal会直接报语法错误。这一点在移植项目时要特别注意。

4.3 注释与编译优化的关系

TIA Portal在编译时会自动优化代码,删除永远不会执行的逻辑。但注释掉的内容不参与编译,所以不会被优化。这意味着:

  • 如果你注释掉了一大段代码,编译后的块大小不会减小,因为注释内容仍然保存在源文件中。
  • 如果你删除了代码而不是注释,编译后的块会变小,下载到PLC的存储占用也会减少。
  • 对于存储空间紧张的PLC(比如一些紧凑型CPU),长期保留大量注释代码可能导致块无法下载。

我的建议是:调试阶段的临时注释可以保留,但在项目最终交付前,把确认不再使用的注释代码彻底删除,只保留必要的说明性注释。这样既能减小块体积,也能避免后期维护时被大段注释干扰。

4.4 常见问题速查表

问题现象可能原因解决方法
SCL编译报错“未预期的符号”块注释未闭合或嵌套检查(* *)是否成对,避免嵌套
STL跳转报错“未找到标签”标签行被注释但跳转指令还在同时注释跳转指令和标签行
LAD网络禁用后编译警告禁用的网络内有未使用的变量清理变量或恢复网络
SCL中文注释乱码块注释中的中文编码问题改用//单行注释
注释后逻辑仍执行注释范围不完整检查IF/END_IF等结构是否被完整注释
批量注释后代码混乱重复注释导致////用Ctrl+Shift+K逐次取消

这张表里的问题,我在不同项目里至少都遇到过一次。特别是“注释后逻辑仍执行”这一条,曾经在一个输送线控制项目里导致电机意外启动,排查了半天才发现是IF条件被注释了但赋值语句还在。

5. 从注释技巧延伸到SCL的常见概念混淆

5.1 编程语言SCL和硬件引脚SCL是两回事

热搜词里出现“sht30的scl接哪里”,这个问题和编程语言SCL完全无关。SHT30是一款温湿度传感器,它的SCL引脚是I2C通信的时钟线(Serial Clock Line),需要接到PLC的I2C主站时钟引脚上。而编程语言SCL是Structured Control Language的缩写,两者只是字母巧合。

在TIA Portal项目里,如果你用SCL语言写I2C通信程序来读取SHT30的数据,那么SCL语言里会涉及对SCL引脚的读写操作。但“SCL接哪里”问的是硬件接线,答案取决于你用的PLC型号和I2C模块。比如用Arduino或树莓派接SHT30,SCL通常接GPIO的I2C时钟脚;用西门子PLC接SHT30,可能需要通过CM模块或第三方网关。

这个混淆在初学者里非常普遍。我见过有人在论坛上问“SCL语言怎么接SHT30”,结果被误导去改程序里的SCL代码,实际上他需要的是硬件接线图。所以这里特别澄清一下:编程语言的SCL和硬件引脚的SCL没有任何关系,遇到问题时要先分清是软件还是硬件层面。

5.2 TIA Portal V16在注释功能上的改进

TIA Portal V16相比V15在编辑器体验上有不少改进,注释相关的包括:

  • SCL编辑器的语法高亮更准确,注释内容会显示为绿色,不容易和代码混淆。
  • 批量注释快捷键Ctrl + K在更多编辑器里生效,包括STL和SCL。
  • 禁用网络的右键菜单更直观,V16里直接显示“禁用/启用网络”,V15里藏在子菜单里。
  • 块注释的自动补全功能:输入(*后编辑器会自动提示补全*),减少未闭合错误。

如果你还在用V15或更早版本,升级到V16后这些细节能明显提升编码效率。但要注意,V16的项目文件不能直接在V15里打开,团队协作时要统一版本。

5.3 FBD注释的特殊性

FBD(功能块图)和LAD虽然都是图形化语言,但FBD的注释更麻烦一些。因为FBD的连线是逻辑流,禁用某个功能块或断开某条连线都会影响整个网络的逻辑。

在FBD里临时屏蔽逻辑,我通常用两种方法:

  • 方法一:在需要屏蔽的输入引脚上接一个常数0或FALSE。比如一个AND门的某个输入需要临时屏蔽,就把它接0,这样AND门输出恒为0,等效于屏蔽了该分支。
  • 方法二:选中整个网络后禁用网络,和LAD的操作一样。

方法一的优点是只影响单个分支,不影响网络内其他逻辑;缺点是如果忘记恢复,后期排查时容易忽略。方法二更彻底,但会影响整个网络。根据调试粒度选择合适的方法。

6. 我个人的注释习惯和项目实践

6.1 注释的粒度控制

在项目里,我遵循“三层注释”原则:

  • 块级注释:每个FC/FB/OB块头部写清楚功能、作者、创建日期、修改记录。用SCL的//或STL的//写在块最前面。
  • 网络/程序段级注释:每个LAD网络标题或SCL程序段开头写一句话说明用途。比如“电机启动条件判断”或“配方数据读取”。
  • 行级注释:只在逻辑复杂或容易误解的地方写行注释。比如一个复杂的数学运算,或者一个不常见的指令组合。

不建议每行都写注释,那样反而干扰阅读。注释的价值在于解释“为什么这么做”,而不是“这行在做什么”——后者应该由代码本身表达清楚。

6.2 调试注释的清理流程

调试阶段会产生大量临时注释和禁用网络。我的清理流程是:

  1. 调试完成后,先全局搜索//和(*,逐个确认是否还需要保留。
  2. 对于禁用的网络,逐个启用并确认逻辑正确,或者彻底删除。
  3. 对于注释掉的代码,如果确认不再使用,直接删除而不是保留注释。
  4. 最后编译整个项目,确保没有警告和错误。

这个流程看起来繁琐,但能避免很多后期问题。我见过一个项目因为调试时的禁用网络没恢复,导致正式运行时某段安全逻辑失效,幸好被操作员及时发现。

6.3 团队协作中的注释规范

如果是多人协作的项目,建议在项目开始前就约定注释规范:

  • 统一用//做单行注释,块注释只在必要时使用。
  • 禁用网络必须写明原因和预计恢复时间。
  • 注释里的日期格式统一为YYYY-MM-DD。
  • 修改他人代码时,保留原注释并追加修改说明,不要直接覆盖。

这些规范看起来是小事,但在项目交接和后期维护时能节省大量沟通成本。特别是当项目周期超过半年时,你自己都会忘记当初为什么注释掉某段代码。

6.4 一个真实的调试案例

去年做一个包装线改造项目,PLC程序里有一段SCL写的配方管理逻辑。调试时发现某个配方参数总是被覆盖,排查了半天才发现是之前同事在调试时注释掉了一行赋值语句,但注释符号//只加在了行首,而行尾还有一个分号没注释掉,导致编译器把分号当成了空语句,逻辑上虽然不执行赋值,但变量声明还在,最终影响了后续的计算。

正确的做法应该是把整行都注释掉,包括分号:

// "RecipeParam" := 100;

而不是:

// "RecipeParam" := 100;;

这个案例说明,注释代码时要注意语法完整性。虽然注释内容不参与编译,但如果注释不彻底,残留的符号可能被编译器解析成其他含义。

7. 关于注释,最后再分享几个实用技巧

7.1 用注释做代码书签

在大型项目里,我习惯用特定格式的注释做书签,方便快速定位。比如:

// TODO: 需要优化这段逻辑的性能 // FIXME: 这里的边界条件处理有问题 // NOTE: 这个参数需要根据现场情况调整

TIA Portal的任务列表(Task List)可以自动识别这些关键词,在“视图”菜单里打开“任务列表”,就能看到所有标记了TODO/FIXME/NOTE的注释位置。这个功能在调试阶段非常实用,相当于给代码加了一个待办事项清单。

7.2 注释里的变量引用要小心

如果你在注释里写了变量名,比如:

// "MotorSpeed" 需要限制在1500以内

当这个变量被重命名或删除时,注释里的变量名不会自动更新。时间长了,注释和实际代码就会不一致。我的做法是,注释里尽量用自然语言描述,而不是直接写变量名。如果必须写变量名,就在变量重命名后全局搜索注释内容,手动更新。

7.3 导出注释做文档

TIA Portal支持将块导出为SCL源文件或XML文件。导出的SCL源文件里会包含所有注释内容。如果你需要给客户或同事提供程序说明文档,可以把关键块导出为SCL,然后用文本编辑器整理注释,形成一份可读性更强的文档。这比截图LAD网络要方便得多,也更容易维护。

7.4 注释的版本管理

如果项目用Git或SVN做版本管理,注释的修改也会被记录。我建议在提交代码时,把注释的修改和代码的修改分开提交,这样版本历史更清晰。比如先提交“添加功能注释”,再提交“修改逻辑实现”。虽然多了一步操作,但后期回溯问题时能快速定位是注释变了还是代码变了。

7.5 不要过度依赖注释

最后说一个观点:注释是辅助,不是替代。好的代码应该尽量做到自解释——变量命名清晰、逻辑结构简单、函数职责单一。注释应该用来解释“为什么”,而不是“是什么”。如果你发现一段代码需要大量注释才能看懂,那可能是代码本身需要重构,而不是加更多注释。

我在实际项目里的体会是,注释写得好的程序,往往逻辑也写得清晰;注释乱七八糟的程序,逻辑通常也好不到哪去。所以,把注释当成代码质量的一部分来对待,而不是事后补的额外工作。这样坚持下来,你会发现调试和维护的效率会有明显提升。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/30 1:03:11

被忽略的工业软件:自动控制的核心与工程实践反思

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/30 1:03:05

工业机器人开源项目全解析:控制软件、GUI与STL文件复现指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/30 1:02:40

不装环境也能玩ESP32:纯浏览器在线开发与云编译指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/30 1:02:35

基于STM32的高精度嵌入式称重系统设计与工业落地

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/30 1:01:50

USB转SATA桥接芯片怎么选?ASMedia主流型号对比与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/30 1:01:20

每次滑动整个item的RecyclerView

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华