使用现有的 CSS 选择器将 Shadow DOM 中的样式应用到自定义元素 [英] Using existing CSS selectors to apply styles across the Shadow DOM to custom elements

查看:137
本文介绍了使用现有的 CSS 选择器将 Shadow DOM 中的样式应用到自定义元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题可能没有单一的直接答案,但希望能提供一些最佳实践或通用模式,以便在将现有样式框架适应新的 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 等.我有 avatarcomposite-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 and composite-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.

    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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆