Search code examples
twitter-bootstrapweb-componenthtml5-templatehtml-imports

Using Bootstrap With The Template Tag


I've been learning the vanilla version of web components and have run into a snag. When trying to use the grid from bootstrap inside of a template tag, specifically the container class, it does not apply any bootstrap styling to it.

//Template File
<template>

  <top-bar>
    <div class="container">
      <h1>Hello World</h1>
    </div>
  </top-bar>

</template>

<script>
  var el = document.querySelectorAll('top-bar');
  if(el != null) {
    //Custom Elements
    document.registerElement('top-bar');
    //Import Elements
    for(var i = 0; i < el.length; i++) {
      var shadow = el[i].createShadowRoot();
      var template = document.querySelector('#topbar').import.querySelector('template');
      var clone = document.importNode(template.content, true);
      shadow.appendChild(clone);
    }
  }
</script>

The general Bootstrap stylings (fonts, style resets etc.) are being applied correctly and no console errors are coming up.

//Index File
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Web Components</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
  <link rel="import" href="topbar.html" id="topbar">
</head>
<body>

  <top-bar></top-bar>

</body>
<script src="http://code.jquery.com/jquery-2.1.4.min.js">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</html>

I've attempted to put the link and script files for bootstrap in the template file (but outside of the template tags as link tags will not get rendered in a template tag). Bootstrap will load as if I were calling it on the index page, but the container still will not inherit any styles from Bootstrap.

Any help you can provide is greatly appreciated!


Solution

  • Shadow DOM stops the CSS propagation. Don't use Shadow DOM if you want natural CSS propagation.

    var shadow = el[i] //.createShadowRoot();  //will work
    

    PS:

    1°) Your use of <template> is wrong: don't get nested <top-bar> tags.

    2°) Your use of registerElement is pointless. Give a prototype to your new element.

    A correct implementation of topbar.html for Custom Element and Template, with no Shadow DOM would be:

    <template>
        <div class="container">
            <h1>Hello World</h1>
        </div>
    </template>
    
    <script>
    
    //Import Elements
    var template = document.querySelector('#topbar').import.querySelector('template');
    
    //Custom Elements
    var topBar = Object.create( HTMLElement.prototype )
    
    topBar.createdCallback = function ()
    {
        var shadow = this //.createShadowRoot()
        var clone = document.importNode( template.content, true );
        shadow.appendChild( clone );
    }
    
    document.registerElement( 'top-bar', { prototype: topBar } );
    
    </script>