Import styles into a web component

What is the canonical way to import styles into a web component?

The following is the HTML element <link> is ignored in shadow tree error:

 <template> <link rel="style" href="foo.css" /> <h1>foo</h1> </template> 

I embed this with a shadow DOM using the following:

 var importDoc, navBarProto; importDoc = document.currentScript.ownerDocument; navBarProto = Object.create(HTMLElement.prototype); navBarProto.createdCallback = function() { var template, templateClone, shadow; template = importDoc.querySelector('template'); templateClone = document.importNode(template.content, true); shadow = this.createShadowRoot(); shadow.appendChild(templateClone); }; document.registerElement('my-nav-bar', { prototype: navBarProto }); 
+8
source share
5 answers

Now the direct tag <link> supported in shadow dom.

You can directly use:

 <link rel="stylesheet" href="yourcss1.css"> <link href="yourcss2.css" rel="stylesheet" type="text/css"> 

It has been approved by both whatwg and W3C .

Useful links for using css in shadow dom:

Direct css link can be used in shadow dom.

+4
source

If you need to place external styles inside the <template> , you can try

 <style> @import "../my/path/style.css"; </style> 

however, I have a feeling that it will start importing after creating the item.

+9
source

NB !!!

ANSWER TO THIS ANSWER

PLEASE CHECK Himanshu Sharma ANSWERS below

Updated answer: fooobar.com/questions/1213935 / ...

According to the polymer documentation :

Polymer allows you to include style sheets in <polymer-element> definitions, and the function is not supported due to the Shadow DOM .

This is a bit weird link, but I could not make Google direct. It seems that at the moment there are no rumors about link support inside the templates.

At the same time, if you want to use the vanilla web component, you must either insert your css with the <style> , or load and apply your css manually in javascript.

+4
source

Constructed Style Sheets

This is a new feature that allows you to create CSSStyleSheet objects. Their contents can be installed or imported from a CSS file using JavaScript and can be applied both to documents and to the shadow roots of web components. It will be available in Chrome version 73 and probably in the near future for Firefox.

There is a good article on the Google Developers site, but I will summarize it below with an example below.

Creating a style sheet

You create a new sheet by calling the constructor:

 const sheet = new CSSStyleSheet(); 

Installation and replacement style:

You can apply style by calling the replace or replaceSync .

  • replaceSync is synchronous and cannot use any external resources:
     sheet.replaceSync('.redText { color: red }'); 
  • replace is asynchronous and can accept @import that reference external resources. Note that replace returns a Promise that should be handled accordingly.
     sheet.replace('@import url("myStyle.css")') .then(sheet => { console.log('Styles loaded successfully'); }) .catch(err => { console.error('Failed to load:', err); }); 

Applying style to a document or shadow DOM

You can apply the style by setting the adoptedStyleSheets attribute of either document or the shadow DOM.

 document.adoptedStyleSheets = [sheet] 

The array in adoptedStyleSheets frozen and cannot be modified using push() , but you can combine it by combining it with its existing value:

 document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet]; 

Document Inheritance

The shadow DOM can inherit the created styles from the adoptedStyleSheets document in the same way:

 // in the custom element class: this.shadowRoot.adoptedStyleSheets = [...document.adoptedStyleSheets, myCustomSheet]; 

Please note that if this is done in the constructor, the component will only inherit the stylesheets that were accepted before its creation. Setting adoptedStyleSheets to connectedCallback will be inherited for each instance when it is connected. It is noteworthy that this will not cause FOUC .

Web Components Example

Let's create a component called x-card that wraps the text in a beautiful div style.

 // Create the component inside of an IIFE (function() { // template used for improved performance const template = document.createElement('template'); template.innerHTML = ' <div id='card'></div> '; // create the stylesheet const sheet = new CSSStyleSheet(); // set its contents by referencing a file sheet.replace('@import url("xCardStyle.css")') .then(sheet => { console.log('Styles loaded successfully'); }) .catch(err => { console.error('Failed to load:', err); }); customElements.define('x-card', class extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open' }); // apply the HTML template to the shadow DOM this.shadowRoot.appendChild( template.content.cloneNode(true) ); // apply the stylesheet to the shadow DOM this.shadowRoot.adoptedStyleSheets = [sheet]; } connectedCallback() { const card = this.shadowRoot.getElementById('card'); card.textContent = this.textContent; } }); })(); 
 <x-card>Example Text</x-card> <x-card>More Text</x-card> 

+1
source

Try the <style> element inside the <template> :

 <template> <style> h1 { color: red; font-family: sans-serif; } </style> <h1>foo</h1> </template> 
-2
source

Source: https://habr.com/ru/post/1213935/


All Articles