People still seem wary of making use of web components because they are new, some of the standards are still in flux and there is yet to be a solid set of best practices discovered. Because of this I thought it best to address some of the issues head on and offer some solutions.
I think that a lot of people see web components as mostly unsupported and not ready for “prime time”. Let’s look at the facts.
Looking at the table above we can see that Chrome and Opera have full support for all four specifications that make up the web component standard. But of course the other browsers take a little while to catch up.
The good news is that because the recommended way to write web components today is using ES2015 which gives you modules, classes and template strings there is really no need for Templates and HTML Imports when it comes to web components. That’s 50% of the standard we don’t need to worry about anymore.
This then leaves us with Custom Elements and Shadow DOM. More good news then, custom elements is entirely solved by the webcomponentsjs pollyfill. This pollyfill also partly solves the Shadow DOM API for us too, meaning that we can happily write web components which use the Shadow DOM and they will work on all the latest browsers, as shown below.
But because the Shadow DOM is such a fundamental part of browser implementation the pollyfill’s cannot make everything work. This means that you won’t get encapsulated styles and other goodies until the browsers natively support it. Don’t be disheartened though, shadow DOM support is already in the nightly build for Safari and under a flag for Firefox which usually means it isn’t far off!
This means that right now while you are building web components you need to be aware of scope and style bleed for the browsers which don’t yet support the shadow DOM. This might mean prefixing your component classes to make them more unique and ensuring your not trying to style native elements from within your components.
The Shadow DOM has single-handedly solved many problems for us but it has also created a few new challenges that we must overcome. Because the Shadow DOM gives our components complete encapsulation it is more difficult to share styles between components and also allow the users to theme your component to fit nicely into their project.
You could of course just bake the same styles into the template of each component which requires them, this way the component is totally self reliant and easy to move around. But adding duplicate styles into the document isn’t exactly performant so for this we are going to need to find a solution — of which there are a few. Some solutions are available now and some better solutions are coming.
Injecting style sheets
One potential solution is to allow your component to take a list of file paths to style sheets that it should load within its Shadow DOM. These can then be provided on a per project basis when needed. The problem with this solution though is that you lose some of the encapsulation benefits as the user can inject anything within the style sheet and potentially destroy your beautiful component.
Styling considerations at design time
Another solution is to think about what part of your component you would want the user to be able to change when they use it and provide this capability via component attributes. This could be something along the lines of allowing the user to provide a primary and secondary colour to your component of which it then uses to build its CSS styles dynamically.
CSS variables offer a new way to style your components. They will allow component authors to basically expose certain parts of their styles as variables which can be overwritten by the component users.
From the above table you can see that we are still waiting on IE and Edge support which means you wont be able to use this method if you have to support those platforms.
This method of styling though is probably the best to date, lets look at a simple example.
The above example shows a simple web component which has a paragraph of text within its shadow DOM. The style used states that the colour of the p tag should be dictated by the variable — p-color or if the variable is present default to purple. To then overwrite the default of purple from outside of the shadow DOM we can simply do the following.
By setting the variable to red, the web component will use this colour as opposed to its default.
This means that the component author can still have complete control over what can be styled by the user but it is much easier to add flexibility than having to use attributes.
Another challenge with web components is managing dependencies. A web component is supposed to be a self contained, encapsulated entity that can easily be reused across different projects. For every dependency that you introduce into your component the more friction you potentially add for your users.
Obviously though you don’t want to reinvent the wheel so ultimately you are going to need to add dependencies to your components. It is going to be important to try and strike the correct balance with this and try and only include dependencies when totally necessary to keep your components as reusable and lightweight as possible.
For the times where dependencies are needed (which in the real world will be often) we have tools such as NPM to help us. If we distribute our components with NPM or similar we have the capability of specifying the dependencies and allowing the tools to abstract the hassle from our users. These tools will automatically download and install the required dependencies alongside our components.
All of these problems already have solutions. If you know of any better solutions for either of these problems please get in touch on Twitter (@RevillWeb) I’d love to hear your thoughts.
These solutions mean that we can already make use of the web components standard and get most of the benefits. The more people that do this the quicker we will have a set of tried and tested best practices.