使用现有的 CSS 选择器将 Shadow DOM 中的样式应用到自定义元素 [英] Using existing CSS selectors to apply styles across the Shadow DOM to custom elements
问题描述
这个问题可能没有单一的直接答案,但希望能提供一些最佳实践或通用模式,以便在将现有样式框架适应新的 Web 组件开发时使用.
就我而言,我有一个组件 <custom-avatar>
,并且它的所有设置都具有独立的样式和功能,一切都很完美.
在某些用例中,应用程序显示需要堆叠头像,只是一个对角线稍微重叠,我遵循的模式是使用一个简单的组件 <div>
中,但关键方面是保留可组合性以便灵活重用,如下所示:
<custom-avatar title="first"></custom-avatar><custom-avatar title="second"></custom-avatar></custom-composite-avatar>
棘手的一点在于样式,这些样式是从 monorepo 导入的,它提供相同的 BEM-ish CSS 和组件 CSS 模块到组件库的其他风格,如 React、Vue 等.我有 avatar
和 composite-avatar
样式导入就好了,但强制预期的重叠显示是使用分层选择器定义的 .my-composite-avatar.my-composite-avatar--medium.my-avatar {}
因此,将 .my-composite-avatar
类应用于
和 .my-avatar<中的 div 包装器/code> 类应用于
内的包装器,它是自己的 Shadow DOM,父/子 CSS 选择器不好.
我怀疑这是否有灵丹妙药,但随着越来越多的人在使用现有样式系统的同时迁移到 Web 组件,这似乎将是一个相当普遍的场景.哪种方法最能确保复合组件保持可组合性,并且可以轻松适应现有选择器(或至少易于与其他开发人员交流)?这可以通过 ::host
或 ::slotted
解决,还是需要大量返工?
感谢阅读,感谢您的想法!
我建议与 CSS 属性
成为好朋友因为它们会在 CSS 选择器之后渗透到 shadowDOM 中.
-
connectedCallback()
用于为所有名为 globe<的图标生成 SVG 背景/图块的代码/em>.双引号不是必需的,但如果没有它们,您的 IDE 会抱怨 CSS 无效.
享受编码乐趣...当你开始使用 calc() 在你的 CSS 属性中...
但是您可以将CSS"提升到另一个层次.附注.
并监控 ConstructAble StyleSheets aka ConstructIble StyleSheets aka Constructed Sheets aka AdoptedStyleSheets 的未来:
图标大师
This question likely has no single direct answer, but hopefully will lead to some best practices or common patterns to use when adapting an existing styles framework to new web component development.
For my case, I have a component
<custom-avatar>
, and it's all set up properly with self-contained styles and functionality, everything is just peachy.In certain use cases, the application display needs to stack avatars, just one slightly overtop one other at a diagonal, and the pattern I'm following is using a simple component
<custom-composite-avatar>
. All this does is wrap the slotted content in a<div>
with the correct styling class, but key aspect is retaining the composability for flexible re-use, like so:<custom-composite-avatar> <custom-avatar title="first"></custom-avatar> <custom-avatar title="second"></custom-avatar> </custom-composite-avatar>
The tricky bit lies in the styles, which are imported from a monorepo that provides the same BEM-ish CSS and component CSS modules to other flavors of the component library like React, Vue, etc. I have the
avatar
andcomposite-avatar
styles imported just fine, but forcing the intended overlap display is defined with the hierarchical selector.my-composite-avatar.my-composite-avatar--medium .my-avatar {}
So with
.my-composite-avatar
class applied to the div wrapper within<custom-composite-avatar>
and the.my-avatar
class applied to the wrapper within the<custom-avatar>
and it's own Shadow DOM, that parent/child CSS selector is no good.I doubt there is a silver bullet for this, but this seems like it will be a rather common scenario as more people migrate to Web Components while using existing styling systems. What approach makes the most sense to ensure that the composite component remains composable, and adaptation of existing selectors pain-free (or at least easy to communicate to other devs)? can this be solved with
::host
or::slotted
, or will these cases require significant re-work?Thanks for reading, your ideas are appreciated!
解决方案I would advice to become good friends with CSS properties
because they trickle down into shadowDOMs following CSS selectors.- CSS Custom Properties(variables)
- and getPropertyValue
- and setProperty if you want to be brutal and make Custom Elements change the outside world.
example
I have an
<SVG-ICON>
element taking configuration from attributes OR CSS properties
with my favorite lines of code:let val = this.getAttribute(attr) || getComputedStyle(this) .getPropertyValue("--svg-icon-" + attr) .replace(/"/g, "") .trim();
Allows for your standard attribute configuration:
<svg-icon name="configuration" fill="grey"></svg-icon>
But more powerful (simplified example):
<style> body { --svg-icon-fill: "grey"; } svg-icon[selected] { --svg-icon-fill: "green"; } </style>
<svg-icon name="messages" selected></svg-icon> <svg-icon name="configuration"></svg-icon>
CSS = Custom String Scripting
It doesn't often happen, but sometimes the simplest code makes me very happy.
There is no Styling restriction!
These 2 lines allow any String you want in CSS properties:
.replace(/"/g, "") .trim();
Example
<style> [name*="globe"] { --svg-icon-tile: "rect:0,0,24,24,0,fill='blue'"; --svg-icon-stroke: white; } </style> <svg-icon name="feather-icons-globe"></svg-icon>
The
--svg-icon-tile
has nothing to do with CSS, it is read (and parsed) by the<SVG-ICON>
connectedCallback()
code to generate a SVG background/tile for all icons named globe.The double-quotes aren't required, but without them your IDE will complain about invalid CSS.
Have fun coding... you will pull some hairs when you start with calc() in your CSS properties...
But you can take 'CSS' to another level.PS.
And monitor the future of ConstructAble StyleSheets aka ConstructIble StyleSheets aka Constructed Sheets aka AdoptedStyleSheets:
iconmeister
这篇关于使用现有的 CSS 选择器将 Shadow DOM 中的样式应用到自定义元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!