Vaadin 14中Grid与ComboBox样式表现差异的原因咨询
核心差异:Shadow DOM中内容的渲染机制不同
同样使用TemplateRenderer,Grid和ComboBox的样式表现差异,本质是自定义内容在Shadow DOM中的位置与分发方式不同:
1. Grid的模板内容属于light DOM,全局CSS可直接作用
Vaadin Grid通过TemplateRenderer生成的<div class="foobar">是页面主DOM树的light DOM内容,仅通过slot分发到vaadin-grid-cell-content的Shadow DOM内部。
Shadow DOM的规则是:全局CSS可以作用于通过slot分发进来的light DOM元素,因此你用普通@CssImport导入的.foobar样式能直接生效,无需指定themeFor。
你可以通过浏览器开发者工具验证:查看Grid单元格的DOM结构,会发现<div class="foobar">属于主DOM树,只是被slot插入到Grid的Shadow DOM单元格中。
2. ComboBox的模板内容位于Shadow DOM内部,需注入样式才能生效
ComboBox下拉项(vaadin-combo-box-item)的模板内容,是直接渲染在该组件的Shadow DOM内部,不属于页面主DOM树的light DOM。
Shadow DOM的样式隔离机制会阻止全局CSS穿透到内部,因此普通@CssImport的样式无法作用于此。而指定themeFor="vaadin-combo-box-item"后,Vaadin会将你的CSS文件注入到vaadin-combo-box-item组件的Shadow DOM内部,.foobar样式就能匹配到内部元素了。
关于Grid是否需要themeFor的补充
你的Grid写法没有问题。如果要修改Grid自身Shadow DOM内部的默认元素样式(比如单元格边框、表头字体),才需要用themeFor="vaadin-grid-cell-content"这类指定目标组件的导入方式;但你是给自定义的light DOM内容加样式,全局CSS已经足够覆盖。
内容的提问来源于stack exchange,提问作者res1

