Search code examples
javascripthtmlcssgoogle-chrome-extension

JavaScript code doesn't change style in HTML page


I'm new to webDev and to JavaScript. I'll preface by saying that I tried to look for (a lot of) similar question but it was just people getting the grammar wrong.

I was annoyed at a particular page not making stuff selectable, so I tried making an extension that changes the " user-select : "none" " to " user-select : "contain" " (chrome).

my extension runs this

    const elements = document.querySelectorAll("*[style]");


elements.forEach((element) => {
  const userSelect = element.style.userSelect;
  const flex = element.style.flex;

  //select by style because Objects have no id there and classes change everytime you reload for some reasons.

  if (userSelect === "none" && flex === "1 1 0%") {
    console.log(element.className + "was changed, the complete style was" + 
    element.style);
    element.style.userSelect = "contain";
    element.style.setProperty('user-select', 'contain');
    console.log("new style is " + element.style.cssText);
    //tried both out of desperation, log is unchanged
  }
});

the console log keeps returning the correct element but when i press F12 the "user-select" attribute is unchanged, the script runs way after the page is loaded.

I even tried running this out of desperation

element.style.cssText = element.style.cssText.replace("user-select: none", "user-select: contain");
        console.log("after the replace it is " + element.style.cssText);

and the "user-select" attribute just disappears from the style.

If I change it manually to "user-select : contain" from the F12 window I can correctly select everything I want.

I'm new to this but completely lost. Also sorry for writing so much


Solution

  • I see what’s happening! The issue is that your script is trying to modify styles using element.style, but that only works for inline styles—and most of the time, user-select: none is applied through CSS stylesheets, not inline styles. That’s why your changes aren’t sticking.

    Why isn’t it working?

    1. element.style.userSelect only affects inline styles. If user-select: none comes from an external CSS file, element.style.userSelect won’t see it at all.
    2. Even element.style.cssText.replace(...) won’t help, because it doesn’t affect styles defined in a stylesheet.
    3. DevTools (F12) shows "computed styles," not inline styles. You might see user-select: none in DevTools, but that doesn’t mean it’s an inline style.

    How to Fix

    Instead of modifying styles element-by-element, you should inject a new global CSS rule that overrides the existing one.

    const style = document.createElement('style');
    style.innerHTML = `* { user-select: contain !important; }`;
    document.head.appendChild(style);