简体   繁体   中英

Remove CSS styling that's applying to injected HTML

I'm creating a Chrome Extension that injects a HTML banner/overlay using JQuery into the current page.

I've noticed that some pages will affect the overlay I've created. This includes changing the margins/fonts/etc of the elements within the overlay. I've tried using unset but I'm still having the styling change.

I've created an example. When switching between google and stackoverflow the checkbox and its text moves.

Example

$("body").append(
  "<div id='my-overlay'><div id='my-overlay-right'>" +
    '<input type="checkbox" id="my-overlay-checkbox" name="my-checkbox" value="MyCheckbox"><label id="my-overlay-checkbox-text">This is a checkbox</label>' +
    "<button id='my-overlay-close-button'>X</button></div></div>"
);

$("#my-overlay *").css({
  all: "unset !important",
});

$("div#my-overlay").css({
  all: "unset !important",
  position: "fixed",
  border: "1px solid black",
  "margin-left": "-250px  !important",
  "margin-top": "0 !important",
  "margin-bottom": "0  !important",
  "margin-right": "0 !important",
  left: "500px",
  top: "-20px",
  width: "500px",
  height: "20px",
  transform: "translate(0, 20px)",
  "z-index": 10000,
  "background-color": "rgba(256,0,0,0.8)",
  transition: "opacity 0.3s, visibility 0.5s",
});

$("div#my-overlay-right").css({
  all: "unset !important",
  float: "right",
  margin: "0  !important",
  padding: 0,
});

$("input#my-overlay-checkbox").css({
  margin: "1px !important",
  padding: "0 !important",
});

$("label#my-overlay-checkbox-text").css({
  all: "unset !important",
  margin: "0",
  padding: "0",
  "font-weight": "normal",
  "font-size": "12px",
  "line-height": "1",
  color: "white",
  "font-family": "Verdana, Geneva, sans-serif",
});
$("button#my-overlay-close-button").css({
  all: "unset !important",
  "font-size": "16px",
  margin: "1px 10px 0 15px !important",
  padding: "0 !important",
  "background-color": "Transparent",
  "background-repeat": "no-repeat",
  border: "none",
  cursor: "pointer",
  overflow: "hidden",
  outline: "none",
  color: "white",
});

What is the correct method of removing all styling from components inserted into a web page?

Update

I've tried adding a reset-this class and applying it to all of my elements. This has fixed the differences between google and stackoverflow but there are still some differences on other pages.

$("body").append(
  "<div id='my-overlay' class='reset-this'><div id='my-overlay-right' class='reset-this'>" +
  "<input type=\"checkbox\" id=\"my-overlay-checkbox\" class=\"reset-this\" name=\"my-checkbox\" value=\"MyCheckbox\"><label id=\"my-overlay-checkbox-text\"  class=\"reset-this\">This is a checkbox</label>" +
  "<button id='my-overlay-close-button'  class='reset-this'>X</button></div></div>"
);
$(".reset-this").css({
  animation: "none",
  "animation-delay": "0",
  "animation-direction": "normal",
  "animation-duration": "0",
  "animation-fill-mode": "none",
  "animation-iteration-count": "1",
  "animation-name": "none",
  "animation-play-state": "running",
  "animation-timing-function": "ease",
  "backface-visibility": "visible",
  background: "0",
  "background-attachment": "scroll",
  "background-clip": "border-box",
  "background-color": "transparent",
  "background-image": "none",
  "background-origin": "padding-box",
  "background-position": "0 0",
  "background-position-x": "0",
  "background-position-y": "0",
  "background-repeat": "repeat",
  "background-size": "auto auto",
  border: "0",
  "border-style": "none",
  "border-width": "medium",
  "border-color": "inherit",
  "border-bottom": "0",
  "border-bottom-color": "inherit",
  "border-bottom-left-radius": "0",
  "border-bottom-right-radius": "0",
  "border-bottom-style": "none",
  "border-bottom-width": "medium",
  "border-collapse": "separate",
  "border-image": "none",
  "border-left": "0",
  "border-left-color": "inherit",
  "border-left-style": "none",
  "border-left-width": "medium",
  "border-radius": "0",
  "border-right": "0",
  "border-right-color": "inherit",
  "border-right-style": "none",
  "border-right-width": "medium",
  "border-spacing": "0",
  "border-top": "0",
  "border-top-color": "inherit",
  "border-top-left-radius": "0",
  "border-top-right-radius": "0",
  "border-top-style": "none",
  "border-top-width": "medium",
  bottom: "auto",
  "box-shadow": "none",
  "box-sizing": "content-box",
  "caption-side": "top",
  clear: "none",
  clip: "auto",
  color: "inherit",
  columns: "auto",
  "column-count": "auto",
  "column-fill": "balance",
  "column-gap": "normal",
  "column-rule": "medium none currentColor",
  "column-rule-color": "currentColor",
  "column-rule-style": "none",
  "column-rule-width": "none",
  "column-span": "1",
  "column-width": "auto",
  content: "normal",
  "counter-increment": "none",
  "counter-reset": "none",
  cursor: "auto",
  direction: "ltr",
  display: "inline",
  "empty-cells": "show",
  float: "none",
  font: "normal",
  "font-family": "inherit",
  "font-size": "medium",
  "font-style": "normal",
  "font-variant": "normal",
  "font-weight": "normal",
  height: "auto",
  hyphens: "none",
  left: "auto",
  "letter-spacing": "normal",
  "line-height": "normal",
  "list-style": "none",
  "list-style-image": "none",
  "list-style-position": "outside",
  "list-style-type": "disc",
  margin: "0",
  "margin-bottom": "0",
  "margin-left": "0",
  "margin-right": "0",
  "margin-top": "0",
  "max-height": "none",
  "max-width": "none",
  "min-height": "0",
  "min-width": "0",
  opacity: "1",
  orphans: "0",
  outline: "0",
  "outline-color": "invert",
  "outline-style": "none",
  "outline-width": "medium",
  overflow: "visible",
  "overflow-x": "visible",
  "overflow-y": "visible",
  padding: "0",
  "padding-bottom": "0",
  "padding-left": "0",
  "padding-right": "0",
  "padding-top": "0",
  "page-break-after": "auto",
  "page-break-before": "auto",
  "page-break-inside": "auto",
  perspective: "none",
  "perspective-origin": "50% 50%",
  position: "static",
  right: "auto",
  "tab-size": "8",
  "table-layout": "auto",
  "text-align": "inherit",
  "text-align-last": "auto",
  "text-decoration": "none",
  "text-decoration-color": "inherit",
  "text-decoration-line": "none",
  "text-decoration-style": "solid",
  "text-indent": "0",
  "text-shadow": "none",
  "text-transform": "none",
  top: "auto",
  transform: "none",
  "transform-style": "flat",
  transition: "none",
  "transition-delay": "0s",
  "transition-duration": "0s",
  "transition-property": "none",
  "transition-timing-function": "ease",
  "unicode-bidi": "normal",
  "vertical-align": "baseline",
  visibility: "visible",
  "white-space": "normal",
  widows: "0",
  width: "auto",
  "word-spacing": "normal",
  "z-index": "auto",
  all: "initial unset"
});

CSS works with classes or IDs for selectors (most time), so have you try to remove the class using removeClass ?

And if the styling is using the element itself (h1, h2, p...) what you can do is create an empty CSS class to reset everything to default. Then apply this class to the items you want to reset, thus will overwrite all changes previous made. See here

Good luck:)

As far as I understand, as long as you inject it into the DOM of another web page (not internal page belongs to your extension), this web page still can change it at anytime, sometimes this happens later, depending on the page's logic.

My approach to avoid this would be to try to sandbox it on my own, by adding a unique id to it that's most probably not going to conflict with another id with the same name at the web page (maybe using your extension's id for that?)

You can do this at your extension's content script like this:

var extId = chrome.runtime.id;
var elementUniqueId = 'ext_' + extId + '_my-overlay';

And move your CSS to be after the unique id.

In addition to that, you'll still need to watch this injected element periodically, and if/when it get removed/changed by the web page, you re-inject/re-style it again.

Maybe something like:

setInterval(function () {
    //if my element removed by the page:
    if (!elementUniqueId.length) {
        //inject my element again;
    }
}, 50);

One other approach would be injecting it as iframe , this way the parent web page won't be able to access it. But, this comes with its cost/extra work as well (including messaging back and forth between this iframe page and the content-script).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM