I'm using the Bulma css library from an external CDN and I'm attempting to build a navbar web component. For some reason the text for my menu items is showing up as Times New Roman instead of sans-serif. It should be inheriting the default font-family from Bulma, but appears to be using browser defaults.
Do I need to be appending each child item to the shadowRoot in order to inherit Burma's text stying, or something similar to that?
Here is the html (index.html):
<!DOCTYPE html>
<html lang="en">
<head>
<title>hello</title>
<meta charset="utf-8">
</head>
<body>
<my-element></my-element>
<script src="./js/index.js" type="module"></script>
</body>
</html>
Here is my main javascript file (index.js):
import { MyElement } from './components/header.js';
if(!customElements.get('my-element')){
customElements.define('my-element', MyElement)
}
Here is my web component code (header.js):
export class MyElement extends HTMLElement {
constructor() {
super()
let count = Math.floor(Math.round() * 10) + 1
let items = ["Home", "Config", "Admin"]
let that = this
let id = Math.random()
this.id = id
// and use it in the constructor after creating the shadow DOM
this.attachShadow({ mode: 'open' })
this.shadowRoot.innerHTML = `<link rel=stylesheet href='https://cdn.jsdelivr.net/npm/bulma@0.9.2/css/bulma.min.css'>`
// main header element
let header = document.createElement('nav')
header.classList.add('navbar')
header.id = 'header'
header.role = 'navigation'
// brand container
let brand = document.createElement('div')
brand.classList.add('navbar-brand')
let brandImg = document.createElement('img')
brandImg.src = 'https://www.zilliondesigns.com/images/how-to/swoosh-concepts-02.png'
brandImg.width = '100'
// menu container
let menu = document.createElement('div')
menu.classList = 'navbar-menu'
menu.id = 'navbarexample'
let menuLeft = document.createElement('div')
menuLeft.classList = 'navbar-start'
// menu items
items.forEach(item => {
let child = document.createElement('a')
child.classList='navbar-item'
child.innerText = item
menuLeft.appendChild(child)
child.addEventListener('click', e => {
e.target
child.remove()
})
})
menu.appendChild(menuLeft)
brand.appendChild(brandImg)
header.appendChild(brand)
header.appendChild(menu)
this.shadowRoot.appendChild(header)
}
}
The reason you're seeing the default user agent font is that Bulma is obviously not made with shadow roots in mind.
It sets the font-family
for the following elements:
body,
button,
input,
optgroup,
select,
textarea {
font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
Because your div.button.is-large
is not a descendant to any of those elements, there is no Bulma font definition to be inherited. I highly assume that this will apply to other commonly inherited properties like color
as well.
To fix it, Just include the Bulma CSS on the main page as well:
<link rel=stylesheet href="https://cdn.jsdelivr.net/npm/bulma@0.9.2/css/bulma.min.css">
Inheritance-wise this will subject the elements in your shadow root to be "descendants" of the body
element, and thus, inherit inherited styles again.
Alternatively, I'd suggest you create a ComponentStyles.js
class with a static property styles
like this:
export class ComponentStyles {
static get styles() {
return `:host { font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; }`;
}
}
and in your components, you import it and then use it in the constructor:
import { ComponentStyles } from './path/to/ComponentStyles.js';
// ...
constructor() {
// ...
let style = document.createElement('style');
style.textContent = ComponentStyles.styles;
this.shadowRoot.appendChild(style);
// ...
}