如何从公共CSS样式中隔离div?

Med*_*7at 54 html css css3

我在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>
Run Code Online (Sandbox Code Playgroud)

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

img{
   width:100px;
   height:100px;
}
h1{
   font-size:26px;
   color:red;
}
Run Code Online (Sandbox Code Playgroud)

问题是:我如何通过公共标签样式阻止和隔离mydiv div标签内的标签?

jar*_*obs 103

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

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

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

你需要申请all: initial你的div all: unset及其后代:

#mydiv {
  all: initial; /* blocking inheritance for all properties */
}
#mydiv * {
  all: unset; /* allowing inheritance within #mydiv */
}
Run Code Online (Sandbox Code Playgroud)

您可能希望在div上使用类而不是id,因此您为其后代设置样式的任何规则都不必匹配或超过此规则中使用的高特异性.

为了非常安全,您可能还希望阻止潜在伪元素后代的样式:

#mydiv::before,
#mydiv::after,
#mydiv *::before,
#mydiv *::after {
  all: unset;
}
Run Code Online (Sandbox Code Playgroud)

或者,对于更广泛的浏览器支持,您可以手动尝试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;
  ...
}
Run Code Online (Sandbox Code Playgroud)

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

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

  • 凉.IE/Edge没有解决方法? (2认同)
  • 另一件要注意的事情是,如果父层次结构中的任何地方都有 `!important`,`all` 属性将无济于事。 (2认同)

Kam*_*mal 10

从技术上讲,这不是CSS的假设.如果样式表中为div标记定义了任何样式,则它将应用于所有div元素.

您可以尝试的一些事情是不使用标记名称进行样式, 而是给出类名并为类赋予样式声明.这样你就可以确定所有款式的去向.

要么.如果你想要一些特定的Div标签没有其他Div有的风格.你可以随时重置它给出一些不同的类名或id并重置样式声明


ben*_*ace 10

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

你必须这样做:

#mydiv,
#mydiv::before,
#mydiv::after,
#mydiv *
#mydiv *::before,
#mydiv *::after {
  all: revert;
}
Run Code Online (Sandbox Code Playgroud)

在撰写本文时,revert支持 Edge、Firefox、Chrome 和 Safari,但不支持 IE 或 Opera。

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

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

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

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

// etc.
Run Code Online (Sandbox Code Playgroud)


Nit*_*tin 5

如果它不使其他业务逻辑复杂化,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`;
});
Run Code Online (Sandbox Code Playgroud)

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

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