What causes styles to be hidden and why can't style tags be reattached after using insertRule in CSSOM?

When using CSSOM to add styles with insertRule, I've made an interesting observation.

The added styles do not show up in Firebug when viewing the HTML.

If the style tag is moved from head to body or appended to another element, the added styles do not work (this occurs in Firefox and Chrome).

However, if the styles are added after the tag is appended, they do work. But still, they do not appear in Firebug. Reassigning (or re-getting) the sheet when appending makes this process even stranger.

It's possible that the issue of not showing in Firebug is specific to Firebug itself, as regular static styles correctly display.

As for the problem of styles not working after being appended, I wonder if this behavior is standard since it happens across multiple browsers. Upon further inspection of the standards, I could not find any mention of this scenario unless my understanding is flawed.

var style = document.createElement('style'),
    sheet = style.sheet;
document.head.appendChild(style);
// Uncomment line 6 for styles to work
// Comment out line 8 
// document.querySelector('.container').appendChild(style);
// Get the sheet when line 6 is uncommented
sheet = style.sheet
sheet.insertRule('.test{color: red}');
document.querySelector('.container').appendChild(style);
// Styles do not apply after the previous line

Edit for better understanding:

If you append a <style></style> tag to the <head></head> of HTML and then apply styles using

style.sheet.insertRule(styleString)
, the added styles will be applied throughout the document.

However, if you have already appended the <style></style> tag to the <head></head> like

<head><style></style></head>
, and then try to append <style></style> somewhere else such as
<div><style></style></div>
, all styles will be lost and won't apply again.

Is this normal?

The code flow:

Works:

  1. Append <style> anywhere
  2. Add styles using
    style.sheet.insertRule(styleString)

Doesn't work:

  1. Append <style> anywhere
  2. Add styles using
    style.sheet.insertRule(styleString)
    to <style>
  3. Re-append the same <style> elsewhere

Additionally, it seems that styles added to <style></style> do not appear in Firebug, even though they are applied to the document.

Further clarification:

If I reappend the style element without modifying the stylesheet, the styles remain intact:

var style = document.querySelector('style');
document.head.appendChild(style);
* {color: red}
<p>Hello world</p>

However, if the stylesheet has been altered with JavaScript, those changes are reversed:

var style = document.querySelector('style'),
    sheet = style.sheet;
sheet.insertRule('* {color: red}', 0);
document.head.appendChild(style); // If you comment this line out, it works.
/* CSS rules inserted through JS */
<p>Hello world</p>

Answer №1

The reason for this behavior is that <style> elements only possess a sheet property once they are added to the document.
Thus, when you move or delete them from the document, their sheet property reverts back to null. Any rules applied to it using the insertRule method will vanish since they are no longer part of the <style>'s innerHTML.


Key excerpt from the specifications :

The algorithm to update a style block for CSS (text/css) is as follows:

  1. Let element be the style element.

  2. If element has an associated CSS style sheet, remove that CSS style sheet.

  3. If element is not in a Document, stop these steps.

  4. If Content Security Policy blocks element's inline behavior, stop here. [CSP]

  5. Create a CSS style sheet with specified properties: ...

Whenever the <style> element is updated, a new CSS style sheet is generated (unless blocked by conditions .3 and .4).


Quick demonstration :

var style = document.createElement('style');
console.log('before being appended : '+ style.sheet)
document.body.appendChild(style); 
console.log('after being appended : '+ style.sheet)
document.body.removeChild(style);
console.log('after being removed : '+ style.sheet)

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

Click event in jQuery triggers element movement

I'm having a tough time figuring this out. I initially thought it was the negative margin causing the issue, but even after removing it, the problem persists. Check out the link below to see what I mean when you click on one of the list items at the ...

Highlighting JavaScript code with React Syntax Highlighter exclusively

I've been struggling to highlight Ruby code, but it seems like no matter what I do, it keeps highlighting JavaScript instead. It's frustrating because I can't seem to get it right. import React from "react"; import atom from "node_module ...

Issue with ExpressJS Regex not correctly matching a path

I'm currently struggling with a simple regex that is supposed to match words consisting of letters (0-5) only, but for some reason it's not working as expected. Can anyone help me figure out the correct expression and how to implement it in Expre ...

Exploring the possibilities of using JPEGcam in conjunction with the powerful

<script language="JavaScript"> webcam.set_api_url( 'test.php' ); webcam.set_quality( 90 ); // JPEG quality (1 - 100) webcam.set_shutter_sound( true ); // play shutter click sound </script> I am exploring the u ...

Storing a class method in a variable: A guide for JavaScript developers

I am currently working with a mysql connection object called db. db comes equipped with a useful method called query which can be used to execute sql statements For example: db.query('SELECT * FROM user',[], callback) To prevent having to type ...

Error: The function or method save() has not been resolved

The function model.save() for mongoose is not being properly defined. models/genre.js 'use strict'; const mongoose = require('mongoose'); const Schema = mongoose.Schema; const GenreSchema = new Schema({ name: {type: String, requi ...

I'm curious if anyone has had success utilizing react-testing-library to effectively test change events on a draftJS Editor component

​I'm having trouble with the fireEvent.change() method. When I try to use it, I get an error saying there are no setters on the element. After that, I attempted using aria selectors instead. const DraftEditor = getByRole('textbox') Draf ...

In Vue3, have you ever wondered why the $emit function seems to work fine before a promise fetch,

https://i.sstatic.net/yJmDY.jpg I have encountered an issue while attempting to pass the result of a promise fetch from a child component to a parent component using emit. Strangely, the emit function was working perfectly fine before the $fetch operation, ...

Connecting a hero image in CSS for Flask application: a step-by-step guide

Adding a hero image to my Flask app page has been challenging. Here is the directory structure of my Flask project: -static |--css_files |--my.css |--images |--img.jpg -templates |--layout.html In order to incorporate a hero image, I have includ ...

When the page loads, should the information be transmitted in JSON format or should PHP be responsible for formatting it?

I'm considering whether it would be more server-efficient and effective to send data to the user in JSON format upon page load, with JavaScript handling the conversion into readable information. For instance, when a user visits my index page, instead ...

Guide to adding icons above the footer of a bootstrap 4 card

I have a straightforward Bootstrap 4 card with a footer that includes some text and an icon. Take a look at the code snippet below: <div class="card"> <div class="card-header"> Featured </div> <div class="card-body"> ...

Challenges with Loading JSON Dynamically in Next.js using an NPM Package

In my TypeScript project, I have implemented a functionality where a json configuration file is dynamically loaded based on an enum value passed as a parameter to the getInstance function in my PlatformConfigurationFactory file. public static async getIn ...

Previewing an uploaded image before submitting with FileBase64: A step-by-step guide

How can I implement a preview for an uploaded image before submitting the form? I have the upload functionality working but I would like to add a preview feature for the image. Below is the code snippet I am currently using: const [shop, setShop] = us ...

The script fails to execute upon the loading of the view

I am facing an issue with a simple JavaScript code that aims to target an element within an angular view: var buttons = document.querySelectorAll('.msg-type i'); console.log(buttons.length); When I run this code, it incorrectly prints out 0 on ...

Incorporate new content into a jquery mobile listview on the fly

I'm attempting to use JavaScript to dynamically populate a listview with items. Here is the code I have written: //Function to load data fields for items dynamically function initialiseFields(listViewId){ for(var i = 0; i < 10; i++){ ...

The <base> tag functions properly when used with the <a href> attribute, but encounters issues when used with JavaScript's document

Encountering an issue with the <base> tag in Internet Explorer (tested on IE11). Despite successfully getting my links to work using the <a href> tag, they fail to work when attempting to use JS document.location. To see this issue in action, ...

AngularJS editable factory for validating floating point numbers

Currently facing an issue with AngularJS regarding xeditable. <a editable-number="some.object".... Encountering difficulty inputting float numbers. How can I successfully add and validate float numbers in the view? ...

Navigating to the following webpage with Selenium using Python

url_main = "https://comic.naver.com/webtoon/detail.nhn?titleId=131385&no=292" This particular website features a comment pagination at the bottom of the page. Upon inspecting the page, I noticed that the buttons were structured like this: &l ...

What is the best way to resize an image within a canvas?

As I work on displaying an image using the cover simulation in canvas, I came across a helpful solution. Currently, the image changes based on screen resolution, but only updates after a page refresh. https://i.sstatic.net/qEL26.gif Is there a way to ac ...

How to insert an image of varying dimensions into a div using HTML5

How can I insert an image into a div container with different shapes such as rectangle, square, or circle using HTML5? I am looking for something similar to the example below Your assistance would be much appreciated ...