微信小程序组件默认样式优先级 bug 解析
在当前版本(iOS 客户端 6.3.27,开发工具 0.10.101400)中,微信小程序在 wxss 中存在一个优先级导致的 bug。
官方文档中提到
可以使用标签选择器,控制同一类组件的样式。如:使用 input 标签选择器控制 <input/> 的默认样式
此处存在一个比较明显的 bug,小程序中的组件大部分都是有默认的样式的,例如 image 组件就存在四个默认样式,其中一个默认样式为 display: inline-block。
如果试图使用上述的标签选择器设置 image 的 display 属性,会发现并没有生效。而通过开发者工具可以查看到,设置没有生效的原因是 image 组件默认的样式优先级高于我们通过标签选择器设置的样式。
经过测试,基本上所有组件的默认样式的优先级都会高于通过标签选择器设置的样式,而 class 选择器和 id 选择器的优先级还是高于默认样式。因此,目前如果想改变组件默认的样式,不能标签选择器直接设置,而是应该给需要改变默认样式的组件赋予同样的 class,再通过此 class 来改变默认样式。
这个优先级的 bug,除了上述的所有组件默认样式的问题之外,针对某些特殊组件,如 button,还有更进一步的问题。
button 组件可以分别设置 size、type 和 plain 三种属性,从而显示不同的按钮样式。测试中发现,如果着三种属性使用了非默认值之外的值,例如 type=“primary”,除了 button 组件默认的样式之外,type 为 primary 的 button 还会有额外的两个默认样式 color: #FFFFFF 和 background-color: #1AAD19。此时如果通过 class 选择器设置 color 为其它值,会发现并没有生效。同样,通过开发者工具可以看到,type 为 primary 时的 button 的两个 “额外” 默认样式的优先级高于 class 选择器。因此在此种情况下,只能通过 id 选择器才能改变上述的两个 “额外” 默认样式。
此外,有一点值得提醒的是。实际开发(真机及模拟器)中会发现目前 wxss 中是可以使用级联选择器的,及类似
.parent .child { width: 100%; }
由此则衍生出来一个比较优雅的解决上述 bug 的方法:
修改 container 下 所有 image 组件的默认样式
.container image { display: block; }
改变 button[type=”primary”] 的 “额外” 默认样式
.container .btn { color: red; }
由此也可猜测上述 bug 出现的原因,可能是由于小程序的组件默认样式的实现过程中使用了类似标签选择器和类选择器,但没有控制好优先级导致。
但是,请注意:不要使用此方法!不要使用此方法!不要使用此方法!
官方文档中明确说明
样式表不支持级联选择器
不推荐使用官方文档中明确表明不能使用的方法。目前小程序还是处于内测阶段,此方法还能使用,只是官方的疏忽,很有可能此方法会突然无法使用。
此外根据微信小程序内测群中的消息:目前还能用级联选择器是由于还没有过滤掉级联选择器。而级联选择有可能会破坏掉基础组件的一些样式,因此后续有时间了就会加上过滤。推荐使用 BEM,同时,后续也可能会加上不会破坏基础组件的级联方法,不过此需求的优先级会低一些。