<p dir="auto">As part of emulating shadow DOM, we have to implement a solution for <em>loading</em> CSS inside of components.</p>
<h4 dir="auto">Embedding style rules directly into the component template is undesirable</h4>
<ul dir="auto">
<li>Makes templates harder to read</li>
<li>Makes it much harder to use CSS pre-processors (sass, less)</li>
<li>Would lead to duplicating "common" styles</li>
</ul>
<h4 dir="auto">Problems</h4>
<ul dir="auto">
<li>The <code class="notranslate">&lt;link&gt;</code> element (the normal way of loading CSS) <a href="http://www.w3.org/TR/shadow-dom/#inert-html-elements" rel="nofollow">is inert in shadow DOM</a>.</li>
<li>CSS <code class="notranslate">@import</code> is generally <a href="https://developers.google.com/web/fundamentals/performance/critical-rendering-path/page-speed-rules-and-recommendations?hl=en" rel="nofollow">frowned</a> <a href="https://developer.yahoo.com/performance/rules.html#csslink" rel="nofollow">upon</a> <a href="https://www.modern.ie/en-us/performance/css-web-performance-optimizations" rel="nofollow">for</a> <a href="http://www.stevesouders.com/blog/2009/04/09/dont-use-import/" rel="nofollow">performance</a> <a href="http://stackoverflow.com/questions/1022695/difference-between-import-and-link-in-css" rel="nofollow">reasons</a>.</li>
</ul>
<h4 dir="auto">Opportunity</h4>
<p dir="auto">Since Angular will control how styles are actually rendered for a component (because of shadow DOM emulation), we can extend There are other ideathe process to give component authors more power.</p>
<h3 dir="auto">Proposal</h3>
<p dir="auto">Angular core implements a directive to include a style file via URL. For discussion's sake, let's call this <code class="notranslate">&lt;ng-style&gt;</code> (it will probably end up being something like <code class="notranslate">&lt;style&gt;</code> or <code class="notranslate">&lt;link&gt;</code>, though):</p>
<div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;!-- fancy-button.html --&gt; 
&lt;ng-style src=&quot;../my/style/file.css&quot;&gt;
&lt;button class=&quot;super-fancy&quot;&gt;...&lt;/button&gt;"><pre class="notranslate"><span class="pl-c">&lt;!-- fancy-button.html --&gt;</span> 
<span class="pl-kos">&lt;</span><span class="pl-ent">ng-style</span> <span class="pl-c1">src</span>="<span class="pl-s">../my/style/file.css</span>"<span class="pl-kos">&gt;</span>
<span class="pl-kos">&lt;</span><span class="pl-ent">button</span> <span class="pl-c1">class</span>="<span class="pl-s">super-fancy</span>"<span class="pl-kos">&gt;</span>...<span class="pl-kos">&lt;/</span><span class="pl-ent">button</span><span class="pl-kos">&gt;</span></pre></div>
<p dir="auto">When <code class="notranslate">ng-style</code> is used in a Component with native shadow DOM, the output <code class="notranslate">&lt;style&gt;</code> element is rendered inside of the shadow DOM for each component. When using emulated shadow DOM, one common<code class="notranslate">&lt;style&gt;</code> element is added to the document head for all component instances.</p>
<p dir="auto"><code class="notranslate">ng-style</code> can also be used to provide component authors a means through which to apply some arbitrary transformation to the embedded style. This could look vaguely something like:</p>
<div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;!-- fancy-button.html --&gt; 
&lt;ng-style src=&quot;../my/style/file.css&quot; transform=&quot;MaterialThemeTransformer&quot;&gt;
&lt;button class=&quot;super-fancy&quot;&gt;...&lt;/button&gt;"><pre class="notranslate"><span class="pl-c">&lt;!-- fancy-button.html --&gt;</span> 
<span class="pl-kos">&lt;</span><span class="pl-ent">ng-style</span> <span class="pl-c1">src</span>="<span class="pl-s">../my/style/file.css</span>" <span class="pl-c1">transform</span>="<span class="pl-s">MaterialThemeTransformer</span>"<span class="pl-kos">&gt;</span>
<span class="pl-kos">&lt;</span><span class="pl-ent">button</span> <span class="pl-c1">class</span>="<span class="pl-s">super-fancy</span>"<span class="pl-kos">&gt;</span>...<span class="pl-kos">&lt;/</span><span class="pl-ent">button</span><span class="pl-kos">&gt;</span></pre></div>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="class MaterialThemeTransformer {
  transform(input: string): string {
    // do some transformation
  }
}"><pre class="notranslate"><span class="pl-k">class</span> <span class="pl-v">MaterialThemeTransformer</span> <span class="pl-kos">{</span>
  <span class="pl-en">transform</span><span class="pl-kos">(</span><span class="pl-s1">input</span>: <span class="pl-s1">string</span><span class="pl-kos">)</span>: <span class="pl-s1">string</span> <span class="pl-kos">{</span>
    <span class="pl-c">// do some transformation</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">This is purposefully hand-waving a lot of details, but I just want to get the idea across. The main use-case I have in mind for this is creating style rules that are defined in terms of some theme (e.g, <code class="notranslate">background-color: {{primaryColor}}</code>)</p>
<p dir="auto">This would let people do whatever arbitrary transformation on the incoming rules, including applying sass or less on the fly (if you wanted to do that for some reason). If CSS shimming is enabled, that process would occur after any user-defined transformations. The CSS shim itself could potentially just be another transform.</p>
<h4 dir="auto">Other notes</h4>
<p dir="auto">It's possible that this mechanism doesn't have to be so tightly coupled to styles, and could instead just be a part of how interceptors/transforms work for all http requests, depending on how http support looks when it's built.</p>
<p dir="auto">So having to use <code class="notranslate">ngOnIinit</code>, <code class="notranslate">ngOnChange</code> etc etc is a required changed so I think it should appear on breaking changes.</p>
<p dir="auto">Cheers.</p>