stylelint 规则详解:selector-pseudo-element-no-unknown —— 禁止未知伪元素选择器

发布时间:2026/9/23 21:56:27
stylelint 规则详解:selector-pseudo-element-no-unknown —— 禁止未知伪元素选择器 代码质量静态分析前端【免费下载链接】stylelintA mighty CSS linter that helps you avoid errors and enforce conventions.项目地址https://gitcode.com/gh_mirrors/st/stylelint点击查看免费下载selector-pseudo-element-no-unknown是 stylelint 内置的核心规则之一用于在样式表中拦截所有未被 CSS 规范收录的伪元素选择器如a::pseudo {}同时自动放行厂商前缀伪元素如::-moz-placeholder。本文将基于该规则在 stylelint 仓库中的官方文档 README.md 展开结合其 规则实现、已知伪元素清单 与 单元测试 三个层面的源码证据讲透它“已知/未知”的判定标准、两种配置选项的完整写法以及底层判定流程。读完你可以直接在自己的 stylelint 配置中落地该规则并能按需用ignorePseudoElements扩展自定义伪元素白名单。规则概览它检查什么、又放过什么先看官方文档给出的规则示意图a::before {} /** ↑ * This pseudo-element selector */规则的核心语义包含三条关键约定已知范围 CSS 规范全集凡是在 CSS 规范CSS Specifications中定义过的伪元素包括最新到 Editors Draft编辑器草案阶段的内容都被视为“已知”不会报错。厂商前缀一律忽略带-webkit-、-moz-、-ms-等厂商前缀的伪元素选择器不会被该规则检查原因见下文源码分析因此input::-moz-placeholder这类写法天然通过。只针对伪元素不针对伪类伪类:hover、:focus等单冒号由selector-pseudo-class-no-unknown等规则负责本规则只关心双冒号::开头的伪元素详见实现中value.slice(0, 2) ! ::的判断。此外该规则支持1 个 message 参数见 配置文档 message 说明即被判定为未知的那个伪元素本身可用于自定义报错文案。启用方式与主选项true在 stylelint 配置中开启该规则只需将主选项设为true{ selector-pseudo-element-no-unknown: true }视为问题的写法会被报错以下三种写法都会触发Unknown pseudo-element selector警告a::pseudo {}a::PSEUDO {}a::element {}注意第二个例子大小写不敏感地判定“未知”。::PSEUDO与::pseudo同样会被拒绝因为源码最终用name.toLowerCase()去查已知表而pseudo本身不在已知清单里无论怎么写大小写都通不过。不会被视为问题的写法a:before {}a::before {}::selection {}input::-moz-placeholder {}这里的判定要点a:before是单冒号的旧式伪元素写法CSS 1/2 时代合法因为不满足“双冒号”前提直接被放行a::before、::selection都在已知伪元素清单内input::-moz-placeholder带-moz-前缀命中“忽略厂商前缀”约定。可选次选项ignorePseudoElements自定义白名单当项目里使用规范之外的自定义伪元素例如 Web Components 场景时可用次选项把特定名字加入白名单{ ignorePseudoElements: [array, of, pseudo-elements, /regex/] }数组元素既可以是普通字符串精确匹配也可以是以/包裹的正则表达式字符串正则匹配。完整示例{ selector-pseudo-element-no-unknown: [ true, { ignorePseudoElements: [/^--my-/, --pseudo-element] } ] }配置后以下写法都不再报错a::--my-pseudo {}a::--my-other-pseudo {}a::--pseudo-element {}测试用例tests/index.mjs中对[pseudo, /^my-/, /foo/i]的验证进一步揭示了匹配细节a::pseudo字符串精确匹配✅ 放行a::my-pseudo正则/^my-/前缀匹配✅ 放行a::FOO-pseudo正则/foo/i大小写不敏感✅ 放行a::pSeUdO、a::PSEUDO、a::MY-other-pseudo、a::not-my-pseudo❌ 仍被拒绝——其中::MY-other-pseudo之所以被拒是因为匹配发生在去掉::前缀之后的名字MY-other-pseudo上而正则/^my-/区分大小写首字母大写 M 无法匹配小写my-。若要放行需写成/^my-/i或在正则里同时覆盖大写形式。深入源码一条未知伪元素的完整判定流程规则实现位于 index.mjs整个判定可拆成六个步骤选项校验validateOptions校验主选项与次选项ignorePseudoElements只接受字符串或正则[isString, isRegExp]且次选项可缺省optional: true。校验逻辑见 validateOptions.mjs配置不合法时会以invalidOption类型告警。快速过滤root.walkRules(mayIncludeRegexes.pseudo, ...)只遍历含冒号的规则mayIncludeRegexes.pseudo /:/见 regexes.mjs是一个性能优化——不含冒号的规则直接跳过无需进入后续解析。标准语法过滤isStandardSyntaxRule和isStandardSyntaxSelector两层把关把 SCSS/Less 插值如::#{$variable}、占位符选择器、Less mixin 等非标准语法排除在外判定细节见 isStandardSyntaxSelector.mjs。伪类分流parseSelector(...).walkPseudos(...)遍历所有伪选择器后先检查value.slice(0, 2) ! ::——单冒号的伪类直接 return 放行只有双冒号的伪元素进入下一步。白名单与厂商前缀先看optionsMatches(secondaryOptions, ignorePseudoElements, pseudoNode.value.slice(2))是否命中白名单实现见 optionsMatches.mjs再看vendor.prefix(name)是否提取到厂商前缀或pseudoElements.has(name.toLowerCase())是否命中已知表三者任一成立即放行。报告问题都不满足时调用report()用pseudoNode.sourceIndex与index value.length计算告警区间消息为Unknown pseudo-element selector ${selector}并统一追加规则名后缀(selector-pseudo-element-no-unknown)见 ruleMessages.mjs。厂商前缀“一律忽略”的实现原理为什么文档说“This rule ignores vendor-prefixed pseudo-element selectors”关键在于 vendor.mjs 中的prefix()prefix(prop) { const match prop.match(/^(-\w-)/); return match ? (match[0] || ) : ; }只要伪元素名以-xxx-开头例如-moz-placeholder、-webkit-scrollbar就会提取出前缀并直接放行。注意这意味着即使是完全不存在的厂商前缀写法如input::-moz-test也不会报错——这一点在测试用例中专门有input::-moz-test { }被接受的确证。已知伪元素清单从规范到代码判定“已知”的最终依据是 selectors.mjs 中导出的pseudoElements集合它由uniteSets合并以下几组构成分组成员说明levelOneAndTwoPseudoElementsbefore、after、first-line、first-letterCSS 1/2 时代的四个经典伪元素允许单冒号旧写法shadowTreePseudoElementspartShadow DOM 伪元素配合::part(...)使用deprecatedPseudoElementscontent、shadow已被废弃但仍被规范记录的伪元素vendorSpecificPseudoElements-moz-focus-inner、-ms-clear、-webkit-scrollbar系列等数十个各浏览器私有伪元素虽然这些会被vendor.prefix提前放行仍保留在集合中其余现代伪元素backdrop、cue、file-selector-button、grammar-error、highlight、marker、placeholder、selection、slotted、spelling-error、target-text、view-transition系列、scroll-marker系列等含编辑草案阶段的较新提案因此::selection、::marker、::placeholder、::spelling-error、::grammar-error、::search-text、::view-transition以及::scroll-marker、::picker(select)、::part(shadow-part)等都能通过测试用例中均有对应断言。边界行为与测试佐证tests/index.mjs 覆盖了不少容易被忽略的边界场景大小写容忍a:Before、a::bEfOrE、a::BEFORE等任意大小写组合都被接受查表前统一toLowerCase()复杂选择器a:hover::before、选择器列表a,\nb .foo::before正常处理未知伪元素按行定位a:hover::element的告警定位在column: 8b .foo::error定位在line: 2, column: 9非标准语法跳过使用postcss-scss自定义语法时::#{$variable}、a::#{$variable}等 SCSS 插值写法不被检查行内禁用生效/* stylelint-disable-next-line selector-pseudo-element-no-unknown */注释可精确抑制下一行的::pseudo报错一处规则多报同一选择器列表中出现多个未知伪元素时逐一出报例如 5 行代码中 3 处a::pseudo产生 3 条 warning行号列号一一对应。实际配置示例把以上内容落地到一个.stylelintrc.json{ rules: { selector-pseudo-element-no-unknown: [ true, { ignorePseudoElements: [ --my-custom-element, /^x-/i ] } ] } }此配置下::before、::selection、::-webkit-scrollbar正常通过::pseudo、::element、::PSEUDO报错::--my-custom-element与::x-foo、::X-BAR正则i标志被白名单放行。小结selector-pseudo-element-no-unknown的设计思路清晰以 CSS 规范含编辑草案为“已知”基线用vendor.prefix兜底厂商前缀用ignorePseudoElements为用户自定义伪元素留出扩展口。理解它的判定链路双冒号前提 → 标准语法过滤 → 白名单/前缀/已知表三层命中你就能准确预判任意伪元素写法的检查结果并在团队规范中放心启用它来拦截拼写错误与不存在的伪元素。若需要检查单冒号伪类可配合selector-pseudo-class-no-unknown一起使用两者覆盖完整的伪选择器检查面。赞分享代码质量静态分析前端【免费下载链接】stylelintA mighty CSS linter that helps you avoid errors and enforce conventions.项目地址https://gitcode.com/gh_mirrors/st/stylelint点击查看免费下载相关推荐Cilium Operator 的 Hive 依赖检查与 AlibabaCloud 部署配置全解析Cilium Operator 的 Hive 依赖检查与 AlibabaCloud 部署配置全解析 导读 cilium operator alibabaclou代码质量静态分析前端eslint-plugin-unicorn 规则详解no-unknown-pseudo-selectors 校验未知 CSS 伪类与伪元素eslint plugin unicorn 规则详解no unknown pseudo selectors 校验未知 CSS 伪类与伪元素 导读 no unkLint代码质量cross-en-it-roberta-sentence-transformer常见问题解答10个开发者必知的技术要点cross en it roberta sentence transformer常见问题解答10个开发者必知的技术要点 cross en it roberta代码质量静态分析前端上一篇React Native FBSDK Next用户资料获取终极指南如何安全访问用户信息下一篇7步搞定深度学习数据预处理Pandas特征工程实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考