Html 如何将 div 与公共 CSS 样式隔离?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10064172/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 23:39:59  来源:igfitidea点击:

How To Isolate a div from public CSS styles?

htmlcss

提问by Med7at

i have some code for example here in html

我有一些代码,例如在 html 中

<html>
 <body>
  <img src='an image source'/>
  <h1>Hi it's test</h1>
  <div id='mydiv'>
    <img src='an image source'/>
    <h1>Hi it's test</h1>
  </div>
 </body>
</html>

if i used the following css code for styling it:

如果我使用以下 css 代码对其进行样式设置:

img{
   width:100px;
   height:100px;
}
h1{
   font-size:26px;
   color:red;
}

the question is : How can i prevent and isolate the tags inside the mydiv div tag from styling by the public tags style ?

问题是:如何防止和隔离 mydiv div 标签内的标签,使其不受公共标签样式的影响?

回答by jaredjacobs

CSS Cascading and Inheritance Level 3introduces the allshorthand propertyand the unsetkeyword, which, together, allow you to achieve this conveniently.

CSS层叠和继承级别3介绍all速记属性unset关键字,这一起,让您方便地实现这一目标。

For example, if an author specifies all: initialon an element it will block all inheritance and reset all properties, as if no rules appeared in the author, user, or user-agent levels of the cascade.

This can be useful for the root element of a "widget" included in a page, which does not wish to inherit the styles of the outer page. Note, however, that any "default" style applied to that element (such as, e.g. display: blockfrom the UA style sheet on block elements such as <div>) will also be blown away.

例如,如果作者all: initial在一个元素上指定,它将阻止所有继承并重置所有属性,就好像没有规则出现在级联的作者、用户或用户代理级别。

这对于包含在页面中的“小部件”的根元素非常有用,它不希望继承外部页面的样式。但是请注意,应用于该元素的任何“默认”样式(例如,display: block来自块元素上的 UA 样式表,例如<div>)也将被吹走。

You'll need to apply all: initialto your div and all: unsetto its descendants:

您需要应用all: initial到您的 divall: unset及其后代:

#mydiv {
  all: initial; /* blocking inheritance for all properties */
}
#mydiv * {
  all: unset; /* allowing inheritance within #mydiv */
}

You may want to use a class on your div instead of an id, so that any rules you write to style its descendants won't have to match or beat the high specificity used in this rule.

您可能希望在您的 div 上使用一个类而不是一个 id,这样您编写的任何规则来设置其后代的样式就不必匹配或击败此规则中使用的高特异性。

To be really safe, you may want to block styles on potential pseudo-element descendants too:

为了真正安全起见,您可能还想阻止潜在伪元素后代的样式:

#mydiv::before,
#mydiv::after,
#mydiv *::before,
#mydiv *::after {
  all: unset;
}

Alternatively, for broader browser support, you can manually attempt to do what alldoes by setting all known CSS properties (don't forget the prefixed versions):

或者,为了获得更广泛的浏览器支持,您可以手动尝试all通过设置所有已知的 CSS 属性(不要忘记带前缀的版本)来执行操作:

#mydiv {
  /*
   * using initial for all properties
   * to totally block inheritance
   */
  align-content: initial;
  align-items: initial;
  align-self: initial;
  alignment-baseline: initial;
  animation: initial;
  backface-visibility: initial;
  background: initial;
  ...
}

#mydiv::before,
#mydiv::after,
#mydiv *,
#mydiv *::before,
#mydiv *::after {
  /*
   * using inherit for normally heritable properties,
   * and initial for the others, as unset does
   */
  align-content: initial;
  align-items: initial;
  align-self: initial;
  ...
  color: inherit;
  ...
}

You can encourage browser support for the allshorthand property and track its adoption with these issue links:

您可以鼓励浏览器支持all速记属性并通过以下问题链接跟踪其采用情况:

Up-to-date browser support information for the allshorthand property is available here.

此处all提供了有关速记属性的最新浏览器支持信息。

回答by Kamal

You cannot technically, that's how CSS is suppose to work. If there is any style defined for div tag in your style sheet it will be applied to all div elements.

从技术上讲,你不能,这就是 CSS 应该如何工作。如果样式表中为 div 标签定义了任何样式,它将应用于所有 div 元素。

Few things that you can try is don't style with tag nameinstead give class nameand give style declaration to class. so that you can make sure where all styles will go.

您可以尝试的几件事是不要使用标签名称设置样式,而是提供类名并为类提供样式声明。这样您就可以确定所有样式的去向。

OR. if you want some specific Div tag to not have the style while other Divs to have. you can always reset it give some different class name or id and reset the style declarations

或者。如果您希望某些特定的 Div 标签没有样式而其他 Div 有样式。你总是可以重置它给一些不同的类名或 id 并重置样式声明

回答by benface

Old question, but things have changed a little bit since the accepted answer. There is now a CSSWG-recommended keyword called revertwhich would be better suited than initialand unsetto solve this problem, as it resets an element's property to the value defined in the user agent stylesheetrather than the initial value of the property regardless of which element it's used on. So for instance, a divinside #mydivwill have its display set to blockas we would expect and not inline.

老问题,但自接受的答案以来,情况发生了一些变化。现在有一个 CSSWG 推荐的关键字revert,它更适合initialunset解决这个问题,因为它将元素的属性重置为用户代理样式表中定义的值,而不是属性的初始值,而不管它使用的是哪个元素在。因此,例如,div内部#mydiv将其显示设置block为我们所期望的而不是inline

You'd have to do this:

你必须这样做:

#mydiv,
#mydiv::before,
#mydiv::after,
#mydiv *
#mydiv *::before,
#mydiv *::after {
  all: revert;
}

Unfortunately, revertis not supported by any browserother than Safari (for Mac and iOS) at the time of writing.

不幸的是,在撰写本文时,除 Safari(适用于 Mac 和 iOS)之外revert的任何浏览器都不支持

There is also something else to take in consideration regarding the accepted answer. If you want to style anything inside #mydiv, you need to do so with a selector that is at least as specific as the one you used to unset or revert everything, otherwise it will be overridden by that rule, even if it comes after it in the CSS.

关于已接受的答案,还需要考虑其他事项。如果你想在里面设置任何样式#mydiv,你需要使用一个至少与你用来取消设置或还原所有内容的选择器一样具体的选择器,否则它将被该规则覆盖,即使它出现在它之后CSS。

So you'd need to do something like this (note the #mydivwhich boost the specificityof the rules):

所以你需要做这样的事情(注意#mydiv提高规则的特殊性):

#mydiv p {
  margin-top: 20px;
}

#mydiv .bg-black {
  background-color: black;
}

// etc.

回答by Nitin

iframe is also a decent solution for isolation of styles if it doesn't complicate other business logic. Plus this can be done in pure JavaScript and may work in older browsers too.

如果 iframe 不会使其他业务逻辑复杂化,那么它也是一个不错的样式隔离解决方案。此外,这可以在纯 JavaScript 中完成,也可以在旧浏览器中工作。

const HTMLToIsolate = `...` // get your div tag as HTML string
const parentContainerRef = document.body; // or something else
const newIframe = document.createElement('iframe');
// set height & width to 100% and remove borders for newIframe

parentContainerRef.appendChild(newIframe)
newIframe.contentWindow.document.open('text/html', 'replace');
newIframe.contentWindow.document.write(HTMLToIsolate);
newIframe.contentWindow.document.close();

// bonus to remove scroll bars by setting proper iframe's height
newIframe.addEventListener('load', function onIFrameLoad(e) {
    const iframeBody = this.contentDocument.querySelector("body");
    this.style.height = `${iframeBody.scrollHeight}px`;
});

This worked perfectly for me when I had to embed a complex HTML file into my webpage fetched remotely without MixedContentwarning and without parent HTML styles overriding the embedded HTML. Thanks to https://benfrain.com/sandbox-local-htmlcss-code-snippets-inside-iframe-style-guidespattern-libraries/for this excellent idea!

当我不得不将复杂的 HTML 文件嵌入到远程获取的网页中时,这对我来说非常有效,而没有MixedContent警告,也没有父 HTML 样式覆盖嵌入的 HTML。感谢https://benfrain.com/sandbox-local-htmlcss-code-snippets-inside-iframe-style-guidespattern-libraries/这个绝妙的主意!

Though #mydiv * { all: unset }CSS trick, as suggested in the accepted solution hereworks, it ended being a complex browser operation as there were many DOM nodes on my page.

尽管#mydiv * { all: unset }CSS 技巧,正如这里接受的解决方案所建议的那样有效,但它最终成为一个复杂的浏览器操作,因为我的页面上有许多 DOM 节点。

回答by jpsimons

One thing that might be helpful is the CSS direct child selector, which is available in all browsers including IE7+. That lets you apply styling that doesn't cascade down into children. For example in your code you could use this CSS:

可能有用的一件事是CSS 直接子选择器,它在包括 IE7+ 在内的所有浏览器中都可用。这使您可以应用不会向下级联到子项的样式。例如,在您的代码中,您可以使用此 CSS:

body > img {
  width:100px;
  height:100px;
}
body > h1 {
  font-size:26px;
  color:red;
}

And that CSS would only apply to elements directly on the BODY element.

并且该 CSS 仅适用于直接在 BODY 元素上的元素。