Incorporating external CSS files via the link tag in a web component

I'm attempting to incorporate Bulma from CDN within a custom web component, but it doesn't seem to be functioning properly.

Here is my HTML code:

<!DOCTYPE html>
<html lang="en">
<head>
  <title>hello</title>
  <meta charset="utf-8">
</head>
<body>
    <my-element></my-element>
    <script src="index.js"></script>

</body>
</html>

And here is the JavaScript file content:

const sheet = new CSSStyleSheet()

sheet.replace('@import url("https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="7d1f0811101c3d4d5344534f">[email protected]</a>/css/bulma.min.css")');

class MyElement extends HTMLElement {
    connectedCallback(){
        let that = this
        let id = Math.random()
        this.id = id

        const shadowRoot = this.attachShadow({ mode: 'open' })
        shadowRoot.adoptedStyleSheets = [sheet]

        let child = document.createElement('button')
        child.classList.add("button")
        child.innerText = id

        child.id = count

        shadowRoot.appendChild(child)

        this.addEventListener('click', e => {
            e.target
            console.log(that.id)
            that.remove()
        })
    }
}

if(!customElements.get('my-element')){
    customElements.define('my-element', MyElement)
}

let count = Math.floor(Math.random() * 10) + 1
for(i = 0; i <= count; i++){
    let el = document.createElement('my-element')
    document.body.appendChild(el)
}

In testing, when I use

sheet.replaceSync('button { color: green; }')
instead of sheet.replace(...), everything works smoothly. What could be the reason for the external CSS link import not working?

UPDATE: I noticed the following warning in the console:

index.js:6 @import rules are not allowed here. See https://github.com/WICG/construct-stylesheets/issues/119#issuecomment-588352418.

Just to clarify, I am pursuing this method to apply consistent styling across multiple custom web components without the need to import the stylesheet repetitively.

Appreciate any insights or advice!

Answer №1

One strategy I suggest is to utilize a single instance for all of your components, like so:

import bulmaStyles from 'https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a8caddc4c5c9e8988691869a">[email protected]</a>/css/bulma.min.css';
const bulmaCSS = new CSSStyleSheet;
bulmaCSS.replaceSync(bulmaStyles);

export class Styles {
  static get bulma() { return bulmaCSS }
}

Then, in your components, import this class as follows:

import { Styles } from 'path/to/Styles.js';

class MyElement extends HTMLElement {
    constructor() {
      super();
      // incorporate it in the constructor after creating the shadow DOM
      this.attachShadow({ mode: 'open' })
      this.shadowRoot.adoptedStylesheets = [ Styles.bulma ];
    }
}

To be able to import the stylesheet's CSS into a variable, you must ensure your build stack supports it. For example, Webpack facilitates this with tools like webpack-raw-loader.

If you are not using a bundling tool, you may need to await CSS modules implementation or extract the styles from the DOM.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Why are my variables resetting in Angular after ngAfterViewInit?

There seems to be an issue with my variables resetting after successfully using them in ngAfterViewInit(). I have a few @ViewChild and regular variables that are utilized or set in ngAfterViewInit. However, when certain events that I added post-initializa ...

Is there a way to stop the Firebase web client from altering the error message generated by an https.onRequest function?

I am facing an issue where I cannot retrieve the original message I sent from an "https.onRequest" function in Firebase. The firebase client is rewriting the message based on the error code, making it difficult for me to recover the originally sent body or ...

Tips for matching the height of a child div to its parent's height:

Is there a way to ensure that the height of the child div matches the height of the parent div without explicitly setting it in the CSS? Even when the parent div has a height of 300px, the child divs car1front and card1back do not seem to adjust accordingl ...

Having trouble with uploading a file through ajax

I'm currently working on uploading form data through ajax, but I've encountered an issue with uploading images/files. Form Code <form class="form-inline" id="form_add" enctype="multipart/form-data"> <input type="file" id="file-inpu ...

I'm looking for some good .NET MVC frameworks that can help create dynamic AJAX applications

I am interested in developing applications with a dynamic user interface that utilizes ajax technology. Some key features I am looking for include: Automatic saving of user input in forms, even if the data is incomplete Realtime validation of form fields ...

Difficulty accessing class functions from the test application in Node.js NPM and Typescript

I created an NPM package to easily reuse a class. The package installs correctly and I can load the class, but unfortunately I am unable to access functions within the class. My project is built using TypeScript which compiles into a JavaScript class: For ...

When a fetch request is called inside a map function in React, the return

I attempted to retrieve a map array through fetch resolves so that each element inside favoriteCards would return a value and assign it to the test variable useEffect(() => { const test = favoriteCards.map((card) => { accuWeatherApi.getCurrentW ...

Avoiding unnecessary re-renders in your application by utilizing the useRef hook when working with

To prevent the component from re-rendering every time the input value changes, I am trying to implement useRef instead of useState. With useState, the entire component re-renders with each key press. This is the usual approach, but it causes the entire co ...

Creating dynamic dropdown menus within a Rails 3 form using Prototype and incorporating database queries

Recently, I've been on the hunt for a seamless method to create dynamic dropdown menus within a form that can be populated with data from a database based on the selection of a previous dropdown. Unfortunately, my search for a suitable Rails 3/prototy ...

Sending an AJAX request with an unpredictable quantity of parameters

I built a form for my website that pulls questions from a database based on certain variables. This means the number of questions available is unknown. The code snippet for displaying these questions looks like this: HTML <ol class="questions"> ...

There seems to be an issue with the functionality of ChartJS when used

Currently working on a project that involves creating a chart using chartjs.org. I have retrieved data from my database in a PHP document and saved it into a JSON file: print json_encode($result->fetch_all()); The resulting data looks like this: [["1 ...

Set the return value of the mongoose function to a variable in node.js

As a newcomer to node js and mongoose, I have encountered the following code in my node js project. I am trying to store the mongoose return record userData in a variable user that is outside of the callback function. var user = null; User.findOne({$and: ...

Attempting to establish a connection between a node server and a MongoDB server

I have been attempting to link my mongo cluster with my local server, but this persistent error keeps appearing. Even though I am following a tutorial that seems to work flawlessly for the tutor, I encounter this error repeatedly. Below, you can find a scr ...

Obtaining the ID from a JSON object in react.js ES6: A Comprehensive Guide

I have an array of JSON objects containing properties like Name, ID, and Address. My goal is to retrieve the IDs from all objects in this JSON array using react.js ES6. If anyone could offer guidance on how to accomplish this task, it would be greatly appr ...

What is the best way to reduce the viewport size of my application to 67% of the Chrome browser view?

Recently, I acquired an Angular application that comes with hundreds of SCSS files. However, when the application is viewed in a browser set to 100%, it appears ugly and too zoomed in. Applying zoom: 70%; to the index.html body improves the appearance, bu ...

Prevent regex from matching leading and trailing white spaces when validating email addresses with JavaScript

In my current setup, I utilize the following regular expression for email validation: /^[a-zA-Z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$/ My attempt to validate the email is shown below: if (!event.target.value.match(/^[a-zA-Z0-9._%+-]+@[a-z0-9.-]+\. ...

Understanding the Impact of npm Dependencies on AAB (Android App Bundle) Release Size in React Native

Switching over to React-Native and Node.js from a Python background has left me confused about how dependencies are managed in React-Native (which I assume is similar to node.js). Query When creating a React Native AAB, are all Node Modules declared in th ...

Disregard the views folder when using Express

I've configured a settings file to store important information like the application path and cookie secret for my express app. However, I'm facing an issue where it seems to be disregarding my specified view path directory. config.js: ... expor ...

Tips for comparing array objects in two separate React states

Comparing object arrays in two different React states can be challenging. Here is an example of the state values: review1 = [{name: John, Title: Manager},{name: Peter, Title: Engineer}, {name: Serena, Title: Supervisor}] review2 = [{personName: John, isma ...

How come my button is initiating automatically instead of manually?

Working on developing an API using Angular 2 with the Janus media server has brought up an issue regarding the start button. When running Janus, the button initiates automatically instead of manually. The following function was implemented for this purpos ...