JavaScript - Dynamically loaded CSS: CSS variables are not immediately accessible to JavaScript, but are successfully evaluated within the CSS itself

I am encountering an issue with dynamically loading stylesheets via JavaScript into my application. Within these stylesheets, I have various CSS variables that I need to access and modify from my JavaScript code.

When the stylesheets are directly embedded in the head tag, everything functions correctly. The CSS variables are evaluated by CSS and can be accessed in JS.

However, when dynamically loaded during runtime, a peculiar error occurs. While the CSS variable is being evaluated by CSS, it is not visible to JS.

Has anyone encountered a similar problem before?

Here is a Plunker demonstrating the issue:

https://plnkr.co/edit/EChqjvZQJp7yz3L6nknU?p=preview

This is the method I am using to dynamically load the CSS:

var fileref = document.createElement("link");
fileref.setAttribute("rel", "stylesheet");
fileref.setAttribute("type", "text/css");
fileref.setAttribute("href", "not_embedded_from_start.css");

document.getElementsByTagName("head")[0].appendChild(fileref);

And here is how I am attempting to read the CSS variable:

var cS = window.getComputedStyle(document.querySelector("html"));
var pV = cS.getPropertyValue('--foo');

Here is an illustrative example of the CSS:

:root {
  --foo: green
}

#foo {
  background-color: var(--foo);
}

Answer №1

The reasoning behind this issue is due to the fact that the stylesheet has not finished loading during runtime, resulting in the CSS variable being inaccessible to JavaScript until a later point.

To address this, you can easily add an onload event handler to the dynamically inserted stylesheet. This event handler will trigger a function, like stylesheetLoaded(), once the stylesheet has fully loaded and is accessible to JavaScript:

var newStyleSheet = document.createElement("link");
newStyleSheet.setAttribute("rel", "stylesheet");
newStyleSheet.setAttribute("type", "text/css");
newStyleSheet.onload = function() { stylesheetLoaded(); }
newStyleSheet.setAttribute("href", "not_embedded_from_start.css");

It's important to set the onload handler before defining the href attribute.

In the stylesheetLoaded() function, you can then implement any necessary logic based on the now-accessible CSS variable:

var stylesheetLoaded = function() {
  computedStyles = window.getComputedStyle(document.querySelector("html"));
  propertyValue = computedStyles.getPropertyValue('--baz');
  document.getElementById("baz").innerText = propertyValue;
}

You can view a demonstration based on your code here: https://plnkr.co/edit/OYXk7zblryLs3F5VM51h?p=preview

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

Top method for displaying loading popup using $http

As a newcomer to Angular, I am curious to know if it's possible to achieve the following scenario and also where I can find documentation to help me get started. The scenario: In my MEAN app, there is currently a 'loading...' popup controll ...

Arranging an array based on relationships between children and parents

I have an array of objects like this: const data = [{id: 3, name: ''}, {id: 4, name: ''}, {id: 5, name: '', parent: 3}, {id: 6, name: '', parent: 5}, {id: 7, name: '', parent: 4}, {id: 8, name: '&ap ...

What steps do I need to follow in order to modify a CSS style definition to create a border around

I currently have a CSS style defined as follows: [class*="col-"] { border: 1px solid #dddddd; } This particular CSS definition gives borders to all of the bootstrap grid columns on my page. However, I now want to apply borders only to the bootstrap ...

Vue js lacks the ability to effectively link HTML elements to corresponding JavaScript functions

I seem to be missing a crucial element in my spring boot application. I am attempting to follow the initial steps outlined in the Vue documentation to create the most basic Vue application possible. Here is what I currently have: @Controller public class ...

When working with JavaScript and Node.js, it is not possible to access an object's index that is

Utilizing babyparse (PapaParse) in nodejs to convert CSV to JavaScript objects has been quite challenging for me. After processing, the output of one object looks like this: { 'ProductName': 'Nike t-shirt', ProductPrice: '14.9 ...

The visibility of the Google +1 button is lost during the partial postback process in ASP.NET

When trying to implement the Google Plus One button using AddThis on one of our localized pages, we encountered a strange issue. Despite retrieving data from the backend (let's assume a database), the plus button was not loading during an AJAX based p ...

Display updated text on hover over button panel

Is it possible to achieve the following using only CSS without any JavaScript? The desired outcome is a div containing two font awesome icons aligned to the right side. Specifically, I am looking for: - Icon of a pen that reacts on mouse hover - Icon o ...

Insert a scrollbar into the new popup window on Internet Explorer after the window has been opened

I am looking to enable scrolling in a pop-up window after it has been opened. While FireFox offers the 'window.scrollbars' property for this, Internet Explorer does not have a similar feature. Is there a way to add scrolling functionality in IE u ...

Adding and removing/hiding tab-panels in Angular 4 with PrimeNg: A step-by-step guide

I'm currently working on a tabView project with a list of tab-panels. However, I am struggling to find a way to dynamically hide and unhide one of the tab panels based on specific runtime conditions. Does anyone have any suggestions or insights on how ...

HTML needs to be wrapped around every set of three items using C# ForEach loop

Currently, I am faced with the task of constructing an HTML code structure within C# code behind. Specifically, I need to insert an HTML element that spans 3 columns in a row of 12 columns (utilizing Zurb Foundation). To achieve this, I am iterating throu ...

WebView no longer refreshes when the document location is updated

I currently have a basic HTML/JavaScript application (without Phonegap) that I utilize alongside a native Android app and a WebView. When certain situations arise, I need to reload the current page in the JavaScript portion. On my old phone with Android 4 ...

Leverage the power of require() beyond the confines of Node

I'm currently exploring how to integrate an Angular.js application with Node.js. At the moment, I have the following code in the file MY-PROJECT/public/js/controllers.js function LoginController( $scope ) { // fetch waiters var Waiter = require( ...

JavaScript timekeepers and Ajax polling/scheduling

After looking into various methods like Comet and Long-Polling, I'm searching for a simpler way to push basic ajax updates to the browser. I've come across the idea of using Javascript timers to make Ajax calls at specific intervals. Is this app ...

Tips on how to customize/ng-class within a directive containing a template using replace: true functionality

To keep replace: true, how can ng-class be implemented on the directive below without causing conflicts with the template's ng-class? This currently results in an Angular error: Error: Syntax Error: Token '{' is an unexpected token at co ...

Utilizing $http (REST) to send information from a form

Struggling to leverage Angular for CRUD processes, especially encountering difficulties with POST requests to the server. This is my controller: angular.module('myModule').controller("ListingCtrl", function($scope, posts) { $scope.addProje ...

Tips for adjusting the position of overflowing text on a website using CSS in real-time

I'm currently working on an Angular application and I'd like to customize the styling so that any text exceeding 128 characters is not displayed. Ideally, if the text exceeds 128 characters, it should move to the left; otherwise, it should remain ...

Import data from a distant file into a node Buffer within the web browser

Currently, I am utilizing browserify to utilize this particular package within the browser. Specifically, I have developed a phonegap application that retrieves .fsc files from the server. The code snippet looks like this: var reader = new FileReader( ...

View real-time data in Vuejs 3 as it executes

I am currently working on a form that populates a table with data retrieved from a Laravel API. I am using Vue.js 3 and Composition API to build my entire application. When the button is clicked, I want the table to be filled with data from the form. The b ...

Formatting text and images in CSS

Looking to align images at the bottom of each column in a div with 3 columns, but struggling due to varying text lengths. Any tips on how to achieve this? Thank you, Carolin #content_row{ margin-top:150px; margin-left:10px; margin-right:10 ...

Use the jQuery function `stop(true, true)` to swiftly end all animations currently in the queue

For handling animations in jQuery, I have been utilizing the stop(true, true) method to clear running animations so that the next one can start right away. What I observed was that while the first parameter, clearQueue, clears the entire animation queue, t ...