13

I am developing a web page capturer and find that some stylesheet rules of a web page captured from Reddit.com are lost.

After a further investigation I found that the source HTML code of a Reddit.com page has a style element like this:

<style type="text/css" data-styled-components="..." data-styled-components-is-local="true">...</style>

When JavaScript has been on, the style element is processed by the script and be emptied:

<style type="text/css" data-styled-components="" data-styled-components-is-local="true"></style>

And that's why my capturer failed to get the stylesheets.

When the content of a style element is changed by script, the document stylesheet of the page would normally change accordingly and the page would be re-rendered to reflect the change.

However, for the Reddit.com page, after the style element is emptied, its stylesheet rules can still be accessed via document.styleSheets[1].cssRules, while document.styleSheets[1].ownerNode.textContent is "".

Additionally, if I modify the style element by running a script like document.styleSheets[1].ownerNode.textContent = "/*null*/", document.styleSheets[1].cssRules becomes empty and the web page is re-rendered, just like what my capturer has got.

I am confused by the bizarre behavior. I'd like to know why and how the Reddit.com page keep the styles after emptying the style element. Any information is appreciated.

6
  • "However, for the Reddit.com page, after the style element is emptied, its stylesheet rules can still be accessed via document.styleSheets[1].cssRules" If you are able to get the CSS rules what is the issue? Commented Feb 24, 2019 at 10:23
  • 2
    1. My capturer rely on raw stylesheet text rather than document.styleSheets, which is not accessible for a stylesheet file from another origin due to SOP. 2. This question is not only for the issue of my capturer, but also the reason why such inconsistency of style element content and the actual document stylesheet can exist. Commented Feb 24, 2019 at 10:32
  • What is a "raw stylesheet"? Am not certain what the issue is. How can the result be reproduced? Have you asked the authors of the site why the code performs in the manner that you have described? Commented Feb 24, 2019 at 10:36
  • Row stylesheet text is the text content of a style element or the retrieved file text of an external or imported stylesheet. You can open a page in Reddit.com, such as reddit.com and run document.styleSheets[1].cssRules and document.styleSheets[1].ownerNode.textContent from the console to see whether this issue exists. Commented Feb 25, 2019 at 6:51
  • Still not following what the issue is. document.styleSheets[1].cssRules lists the rules of the styleSheet, document.styleSheets[1].ownerNode.outerHTML is "<style type="text/css" data-styled-components="" data-styled-components-is-local="true"></style>", document.styleSheets[1].ownerNode.sheet references the styleSheet. Are you expecting for no cssRules to exist because no CSS text exists in the <style> element? Commented Feb 25, 2019 at 6:56

2 Answers 2

5

CSS rules of a <style> element sheet can be inserted, added or modified programmatically, where the .textContent of the <style> element returns an empty string "" if CSS text is not set at or appended to the <style> element.

<!DOCTYPE html>
<html>
  <head>
    <style id="style"></style>
  </head>
  <body>
    <div>abc</div>
    <p>123</p>
    <script>
      const style = document.querySelector("#style");
      const {sheet} = style;
      sheet.insertRule("div{color:blue}", 0);
      sheet.addRule("p", "color:green", 1);
      console.log(style.textContent);
      style.textContent = "";
      console.assert(style.textContent.length > 0, [style.textContent]); // assertion failed
      console.log(style.textContent === ""); // true
    </script>
  </body>

</html>

See also Modify element :before CSS rules programmatically in React

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you . I did not know changing style via script with insertRule alike does not correapond to DOM change, which differs from changing element styles with <elem>.style.<...>.
It is interesting that the css is reconstructed per rule in styleElement.sheet.cssRules[0].cssText, but it is not concatenated into styleElement.textContent. This api is very misleading, as el.textContent = el.textContent; will actually remove all the styles.
0

Also check out Modify a stylesheet rule with CSSOM example from the MDN:

<html>
<head>
<title>Modifying a stylesheet rule with CSSOM</title>
<style type="text/css">
  body {
   background-color: red;
  }
</style>
<script type="text/javascript">
  var stylesheet = document.styleSheets[0];
  stylesheet.cssRules[0].style.backgroundColor="blue";
</script>
</head>
<body>
The stylesheet declaration for the body's background color is modified via JavaScript.
</body>
</html>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.