-->

How to let imported css have effects on elements i

2019-01-08 01:39发布

问题:

Say if I want to create a custom element using shadow dom. Some elements in the template have class names specified in the linked css file. Now I want to let the css rules have effects on the elements. But I can't achieve that because of the shadow dom style boundary.

<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<template id="blog-header">
	<header>
		<h1>DreamLine</h1>
		<nav>
			<ul>
				<li><a href="#0">Tour</a></li>
				<li><a href="#0">Blog</a></li>
				<li><a href="#0">Contact</a></li>
				<li><a href="#0">Error</a></li>
				<li><a href="#0"><i class="fa fa-search"></i>Search</a></li>
			</ul>
		</nav>
	</header>
</template>
<script type="text/javascript">
	var importDoc = document.currentScript.ownerDocument;
	var proto = Object.create(HTMLElement.prototype, {
		createdCallback: {
			value: function() {
				var t = importDoc.querySelector("#blog-header");
				var clone = document.importNode(t.content, true);
				this.createShadowRoot().appendChild(clone);
			}
		}
	});
	document.registerElement("blog-header", {prototype: proto});
</script>

You see, fa-search is a class defined in the font-awesome css file, how can I style the <i> element?

回答1:

To use an imported font (i.e. FontAwesome) in a Shadow DOM, you should:

1° Declare the Font

First, include the <link rel="stylesheet"> element in the main document. It will declare a @font-face CSS rule that will make the font available for all the text in the document.

2° Import the Stylesheet

Then, import the same file with an @import url CSS rule in the <template> node to make the .fa-* classes selectors available from the Shadow DOM :

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">

<template id="blog-header">
  <style>
    @import url("https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css")
  </style>
  <header>
    <h1>DreamLine</h1>
    //...
  </header>
</template>

var importDoc = document.currentScript.ownerDocument;
var proto = Object.create(HTMLElement.prototype, {
	createdCallback: {
		value: function() {
			var t = importDoc.querySelector("#blog-header");
			var clone = document.importNode(t.content, true);
			this.createShadowRoot().appendChild(clone);
		}
	}
});
document.registerElement("blog-header", {prototype: proto});
/* 
@font-face {
    font-family: "FontAwesome";
    src: url("https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome-webfont.woff2?v=4.5.0") format('woff2');
  }
*/
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">

<template id="blog-header">
  <style>
    @import url("https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css")
  </style>
	<header>
		<h1>DreamLine</h1>
		<nav>
			<ul>
				<li><a href="#0">Tour</a></li>
				<li><a href="#0">Blog</a></li>
				<li><a href="#0">Contact</a></li>
				<li><a href="#0">Error</a></li>
				<li><a href="#0"><i class="fa fa-search"></i>Search</a></li>
			</ul>
		</nav>
	</header>
</template>

<blog-header></blog-header>