Coding is as much a matter of personal growth as it is of logic and control-flow. I keep patience, curiosity, & exuberance in the same toolbox as vim and git.
*Opinions posted are my own*
For those that want to do this kind of thing without JS overhead, there's a browser standard for this called Shadow DOM.
constshadowRoot=el.attachShadow({mode:"open"});shadowRoot.appendChild(someDom);el.querySelector('.some-scoped-class');// nullel.shadowRoot.querySelector('.some-scoped-class');// child of someDom
You can either roll your own with the bare DOM APIs as above or use a lightweight templating and component library like LitElement or Hybrids.
I'm a fan of Open Source and have a growing interest in serverless and edge computing. I'm not a big fan of spiders, but they're doing good work eating bugs. I also stream on Twitch.
But that's only if you're using web components right? Also, is the shadow DOM implemented in all the main browsers now? Last time I checked, which has been a while, it was only implemented in Chrome.
Coding is as much a matter of personal growth as it is of logic and control-flow. I keep patience, curiosity, & exuberance in the same toolbox as vim and git.
*Opinions posted are my own*
It's if you're using the web. attachShadow is a method on HTMLElement. You can attach a shadow root to any div.
So really, the caveat belongs on the library: "if you are not using the actual DOM, you will need to use JavaScript to scope your styles". If you are invested in react, for example, and you want to benefit from the new standard, you'll either have to wait until the react authors ingest the standard, or find a workaround. (I'm not an expert on react so feel free to correct me on this)
ShadowDOM is supported by all major browsers except Edge, which will get it for free in the next version, and there is a polyfill for old or unsupporting browsers.
I'm a fan of Open Source and have a growing interest in serverless and edge computing. I'm not a big fan of spiders, but they're doing good work eating bugs. I also stream on Twitch.
For those that have never heard of what you're taking about, I'm assuming the polyfill you're referring to is the Polymer Project?
Alright, so getting back to it, to be clear, I can only use scoped styles within a template element correct?And a template element can only be used within a custom element right? So getting back to my orignal question, scoped styles in the browser can only be used within a web component right?
To be clear, I'm not knocking web components, I just want to make sure my understanding is correct because even the MDN docs example for attachShadow use a web component as an example.
I'm a fan of Open Source and have a growing interest in serverless and edge computing. I'm not a big fan of spiders, but they're doing good work eating bugs. I also stream on Twitch.
In terms of React, there's no reason you can't use a web component (WC) in a React component. At the end of the day it's just a DOM element. I mean like you said, <video /> tag is a WC (in at least Chromium based browsers) and people use those in React components. So in that respect a WC is raw building block, like a <div />.
For the rest of this, I'll just leave this comment from @dan_abramov
as it's a good read and a related Tweet thread.
A few quick points from my perspective. (I work on React.)
We're not opposed to supporting web components better. The problem is that there's no single "web component community". There are multiple subcommunities. You mention "web component libraries" in the post. These libraries don't agree on a single standard so React would need to pick a side in debates like "how does server rendering work with web components". Whatever we pick will have large downstream effects, and our reluctance to support more has to do with being careful (see [1] note below) about the semantics โ not somehow being at odds with web components per se.
As I mentioned in the previous point (and you mentioned in the post), there are multiple "web component libraries". As far as I can see many of the criticisms of React would apply to such libraries as well. I don't think the way to counteract "DOM FUD" is to introduce "library FUD". If you're using a library for defining and updating your web components declaratively, you're not following a conceptually different approach from using React.
Saying "you can do everything with WCs that you can do in React" is double edged. Yes, of course, you can do anything โ because we haven't actually agreed upon any constraints. If the constraint is "you don't use a React-like library on top" I think you'll find there's plenty of things that are very hard to do with an imperative abstraction like vanilla WC APIs. We've done a few talks about what using React as a unifying abstraction lets us do (such as non-blocking rendering, or dynamically loading UI code without degrading user experience). You might want to check them out (youtube.com/watch?v=nLF0n9SACd4, youtube.com/watch?v=ByBPyMBTzM0). Of course, you can do these things if you use a library like React on top of WCs. But that negates the argument that you don't need React-like libraries for this.
To sum up: we'd be happy to support WCs better in React. We don't want to rush it, and want to make sure this support is well thought-out. Additionally, we believe there are many things that raw imperative WC APIs don't give you โ and for them something like React would be appropriate even in a WC world. Finally, there's this myth going around that once you write React code, you can't reuse it as web components. That's not true โ and as you can see from the documentation it's a few lines of code: reactjs.org/docs/web-components.ht...
Hope that makes sense, and provides some additional context!
[1]: For example, if I'm not mistaken, the semantics chosen by Preact make introducing a new standard property to DOM base element potentially a breaking change for the web. We try to avoid such problems if possible โ precisely because React did learn from MooTools and we don't want to do another mistake like what happened with Array.prototype.flatten().
Dan Abramov
@dan_abramov
Wrote a bit about React and Web Components since this topic occasionally comes up. Weโre not at odds! twitter.com/dan_abramov/stโฆ
20:41 PM - 07 Nov 2018
Dan Abramov @dan_abramov
@bendhalpern Wanted to post these points for a while but didnโt have an opportunity. Thanks for writing this! https://t.co/kSM1By718A https://t.co/Auj4NGCh23
Coding is as much a matter of personal growth as it is of logic and control-flow. I keep patience, curiosity, & exuberance in the same toolbox as vim and git.
*Opinions posted are my own*
Good questions. Nothing you're asking here comes off as a knock. It's really nice for me to see developers who might not have heard much about these powerful new standards engaging with them.
Polymer? Web Components? Polyfill?
Polymer Project is the Google team which initially proposed the new standards and shepherded them through the standards process. They also wrote and maintained the polymer library, which is a specific implementation of web components.
Five years ago, the only way to polyfill the standards was with the polymer library. Today, you can npm i -S @webcomponents/webcomponentsjs to get the polyfills - no need to include polymer.
So point No. 1: you don't need to (and even probably shouldn't) use Polymer library to make web components. Also, now that the standards are established and implemented, it's not like Google can just cancel them like inbox or hangouts.
But isn't Shadow DOM for Web Components only?
Now, Shadow DOM is only one of the four standards that we collectively refer to as "web components". It's very likely that you'll most often want to attach a shadow root to a custom element in it's constructor (or via a library that does same), but you don't have to. <input> has a shadow root. So does <video>. You don't have to use custom elements to use Shadow DOM.
It's also likely you'll want to use the template element to stamp DOM into that shadow root (or use a library that does same), since it's way faster than innerHTML, but you don't have to use template to use Shadow DOM. You can just attach a shadow root to some div then append existing DOM to it, if you want. You could also render your react app into that shadow root if you wanted. (Although, for half the ticket price, you might as well just use custom elements in such a case)
So the web components standards work well together, but don't require one another.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
For those that want to do this kind of thing without JS overhead, there's a browser standard for this called Shadow DOM.
You can either roll your own with the bare DOM APIs as above or use a lightweight templating and component library like LitElement or Hybrids.
Read all about it:
Lets Build Web Components! Part 1: The Standards
Benny Powers
But that's only if you're using web components right? Also, is the shadow DOM implemented in all the main browsers now? Last time I checked, which has been a while, it was only implemented in Chrome.
It's if you're using the web.
attachShadow
is a method onHTMLElement
. You can attach a shadow root to anydiv
.So really, the caveat belongs on the library: "if you are not using the actual DOM, you will need to use JavaScript to scope your styles". If you are invested in react, for example, and you want to benefit from the new standard, you'll either have to wait until the react authors ingest the standard, or find a workaround. (I'm not an expert on react so feel free to correct me on this)
ShadowDOM is supported by all major browsers except Edge, which will get it for free in the next version, and there is a polyfill for old or unsupporting browsers.
For those that have never heard of what you're taking about, I'm assuming the polyfill you're referring to is the Polymer Project?
Alright, so getting back to it, to be clear, I can only use scoped styles within a template element correct?And a template element can only be used within a custom element right? So getting back to my orignal question, scoped styles in the browser can only be used within a web component right?
To be clear, I'm not knocking web components, I just want to make sure my understanding is correct because even the MDN docs example for attachShadow use a web component as an example.
In terms of React, there's no reason you can't use a web component (WC) in a React component. At the end of the day it's just a DOM element. I mean like you said,
<video />
tag is a WC (in at least Chromium based browsers) and people use those in React components. So in that respect a WC is raw building block, like a<div />
.For the rest of this, I'll just leave this comment from @dan_abramov as it's a good read and a related Tweet thread.
A few quick points from my perspective. (I work on React.)
We're not opposed to supporting web components better. The problem is that there's no single "web component community". There are multiple subcommunities. You mention "web component libraries" in the post. These libraries don't agree on a single standard so React would need to pick a side in debates like "how does server rendering work with web components". Whatever we pick will have large downstream effects, and our reluctance to support more has to do with being careful (see [1] note below) about the semantics โ not somehow being at odds with web components per se.
As I mentioned in the previous point (and you mentioned in the post), there are multiple "web component libraries". As far as I can see many of the criticisms of React would apply to such libraries as well. I don't think the way to counteract "DOM FUD" is to introduce "library FUD". If you're using a library for defining and updating your web components declaratively, you're not following a conceptually different approach from using React.
Saying "you can do everything with WCs that you can do in React" is double edged. Yes, of course, you can do anything โ because we haven't actually agreed upon any constraints. If the constraint is "you don't use a React-like library on top" I think you'll find there's plenty of things that are very hard to do with an imperative abstraction like vanilla WC APIs. We've done a few talks about what using React as a unifying abstraction lets us do (such as non-blocking rendering, or dynamically loading UI code without degrading user experience). You might want to check them out (youtube.com/watch?v=nLF0n9SACd4, youtube.com/watch?v=ByBPyMBTzM0). Of course, you can do these things if you use a library like React on top of WCs. But that negates the argument that you don't need React-like libraries for this.
To sum up: we'd be happy to support WCs better in React. We don't want to rush it, and want to make sure this support is well thought-out. Additionally, we believe there are many things that raw imperative WC APIs don't give you โ and for them something like React would be appropriate even in a WC world. Finally, there's this myth going around that once you write React code, you can't reuse it as web components. That's not true โ and as you can see from the documentation it's a few lines of code: reactjs.org/docs/web-components.ht...
Hope that makes sense, and provides some additional context!
Good questions. Nothing you're asking here comes off as a knock. It's really nice for me to see developers who might not have heard much about these powerful new standards engaging with them.
Polymer? Web Components? Polyfill?
Polymer Project is the Google team which initially proposed the new standards and shepherded them through the standards process. They also wrote and maintained the polymer library, which is a specific implementation of web components.
Lets Build Web Components! Part 4: Polymer Library
Benny Powers
Five years ago, the only way to polyfill the standards was with the polymer library. Today, you can
npm i -S @webcomponents/webcomponentsjs
to get the polyfills - no need to include polymer.Lets Build Web Components! Part 2: The Polyfills
Benny Powers
So point No. 1: you don't need to (and even probably shouldn't) use Polymer library to make web components. Also, now that the standards are established and implemented, it's not like Google can just cancel them like inbox or hangouts.
But isn't Shadow DOM for Web Components only?
Now, Shadow DOM is only one of the four standards that we collectively refer to as "web components". It's very likely that you'll most often want to attach a shadow root to a custom element in it's constructor (or via a library that does same), but you don't have to.
<input>
has a shadow root. So does<video>
. You don't have to use custom elements to use Shadow DOM.It's also likely you'll want to use the
template
element to stamp DOM into that shadow root (or use a library that does same), since it's way faster thaninnerHTML
, but you don't have to usetemplate
to use Shadow DOM. You can just attach a shadow root to some div then append existing DOM to it, if you want. You could also render your react app into that shadow root if you wanted. (Although, for half the ticket price, you might as well just use custom elements in such a case)So the web components standards work well together, but don't require one another.