防止现有的 CSS 样式化注入的 HTML/CSS
Posted
技术标签:
【中文标题】防止现有的 CSS 样式化注入的 HTML/CSS【英文标题】:Prevent existing CSS from styling injected HTML/CSS 【发布时间】:2010-10-18 11:30:23 【问题描述】:我正在开发一个项目,该项目在我无法控制的网页上注入 JS+CSS+html。
我担心我的注入代码的主机页面样式 -- 我希望我的注入代码只服从 我的 样式,而不是他们的样式。
目前,我能想到的唯一方法是为容器<div>
的类显式指定每个可能的标签(使用预定义的已知浏览器默认值),并依靠继承来传播这些规则一直到我注入的 HTML 的其余部分。此 CSS 需要出现在页面底部的 <head>
标记中。
不过,我认为这不是最好的解决方案,我也不期待实施它。当然还有更好的方法。
【问题讨论】:
尝试在那个 div 上实现阴影。 【参考方案1】:你只需要非常 specific 使用你的 CSS 选择器。也就是说,比主机页面的 CSS 规则更具体。您可能还想添加一种全局 CSS 重置,修改为仅重置您的 HTML。我的意思是指将所有颜色、背景、字体、填充等重置为单一标准的东西。从那里你可以建立自己的风格。
【讨论】:
+1 表示 Eric Meyer 重置,而不是可怕的 * padding: 0;边距:0 CSS 重置是为了跨浏览器标准化,而不是跨 CSS 样式表。 是的,但是 CSS 重置(比宿主 CSS 更具体)将覆盖之前设置的规则(删除时髦的粉红色背景等) 粉色背景是 CSS 设计师的朋友! 不,您的标准 CSS 重置不会,除非您的 CSS 重置确实 every 样式。标准 CSS 重置只是为了纠正浏览器的差异,例如边距和填充默认值。【参考方案2】:使用特定类别的<div>
包装注入的 HTML,例如
<div class="my-super-specialized-unique-wrapper"><!--contents--></div>
然后在您的 CSS 中,在所有规则前面加上 .my-super-specialized-unique-wrapper
并在每个规则上使用 !important。这将指示客户端浏览器将您的规则视为任何匹配元素的至高无上,而不管任何其他可能针对它们的样式 - 即使您无法控制的其他规则更具体。
【讨论】:
感谢您的回答!我已经为所有事情使用了超特定的类名,所以这已经完成了。 :-) 不过我确实有几个问题: - CSS 规则是否会通过指定元素名称(例如div layer table
等)覆盖 !important - 我是否需要为每个规则指定 !important?
!important 会覆盖 everything,无论何时、何地或如何指定。您需要为每个规则中的每个样式指定它,您担心样式可能会被您无法控制的另一个样式覆盖。
当然,如果您无法控制的样式表也使用 !important,则可能会带来额外的担忧。那么我相信这是最后一个声明的 !important 的问题。
@Rex,我相信如果有两个 !important 规则竞争,它将采用标准特异性规则。无论如何,您仍然需要在包装器上重置 CSS。【参考方案3】:
为什么不用像这样的内联格式注入 html 元素:
<p style="color:red">This to be injected</p>
内联样式优先于任何其他规则,并且您已经在创建标记以便插入它。
其他解决方案是在您的元素上使用 非常具体的 DOM id,然后在您添加的 CSS 上设置样式
【讨论】:
如果宿主 CSS 以其他方式更改样式,这将无济于事,例如:p font-weight: bold ...你最终会得到红色和粗体的段落。跨度> 是的。我假设他内联了他想要的所有样式属性,而不仅仅是颜色。这只是一个例子。【参考方案4】:其他人提出了很好的方法来防止您的 CSS 影响页面,以及确保您的 CSS 优先,但您似乎最关心页面的 CSS 影响您 - 即添加一个时髦的、意想不到的样式(比如让所有的 div 都有粉红色的背景)。
我能想到的防止他们的样式影响您注入的代码的唯一方法是让您对您注入的内容进行沙箱化,例如在iframe
中。否则你需要定义的东西太多了——你必须定义每一种风格(padding
、border
、margin
、background
...这个列表还在继续) “*
”选择器(或者更好的是“#yourid *
”,这样你就可以覆盖你自己的内容),这样你就可以保证对你的 CSS 的绝对控制。
编辑:我意识到后一种解决方案不一定会太痛苦,如果您使用全向选择器将所有内容重置为基线:
#myid *
somestyle1: default;
somestyle2: default;
...
我找到了someone who has written up such a solution。如果您在页面上向下滚动足够远,您会看到它(来自 SuzyUK)。它看起来并不完整,但肯定是一个好的开始。
(我也很想知道是否有防止这种情况的好方法。在将代码注入页面之前,我已经编写了 Greasemonkey 脚本,并且必须编写 CSS 来覆盖页面的 CSS,但是在那些我知道我的目标是谁并且可以直接针对页面定制我的 CSS 的案例。)
【讨论】:
这是一个更新的元素定位 CSS 重置:github.com/premasagar/cleanslate 你有没有想过隐藏那个特定的 div。【参考方案5】:如果您使用的是 Mozilla 浏览器,您实际上可以(如果非法)在
元素之外的 元素中添加可见的 DOM 内容。这将避免任何与正文匹配并由您的内容继承的样式。某些样式可能会在 html 上匹配,这会破坏这种技术,但我发现它很有用。例如。使用 jquery: $('html').append('
blah blah blah ');如果您不希望您的库实例干扰由您正在修改的页面定义的库的使用,那么使用流行的库本身就是一个挑战。 Greasemonkey 的“@require”对我不起作用。我发现有必要(但可能!)保存由 jquery 脚本分配的两个或三个全局名称的任何现有值,将我的库实例插入 DOM,等待它被加载(必须使用计时器,这很烦人,但我找不到解决办法),缓存分配给我自己命名空间中全局变量的值以供我自己使用,然后恢复保存的值。
【讨论】:
【参考方案6】:我不确定应该如何使用它,浏览器对此的支持,但它是使用http://www.w3.org/TR/shadow-dom/的主要原因之一
这个想法是您可以插入一个 Web 组件,该组件可以完全设置样式并具有仅影响 shadow-DOM 的特定事件(因此您的模块不会影响页面的其余部分)。
【讨论】:
以上是关于防止现有的 CSS 样式化注入的 HTML/CSS的主要内容,如果未能解决你的问题,请参考以下文章
如何在我的 PHP/SQL/HTML/CSS 代码上实现 MVC 样式? [关闭]