Подтвердить что ты не робот

Как изолировать div от общедоступных стилей CSS?

У меня есть код, например, здесь, в html

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

если я использовал следующий код css для его стилизации:

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

возникает вопрос: как я могу предотвратить и изолировать теги внутри тега div mydiv от стиля в стиле общих тегов?

4b9b3361

Ответ 1

CSS Cascading и Inheritance Level 3 представляет сокращенное свойство all и ключевое слово unset, которое вместе позволит вам достичь этого удобно.

Например, если автор указывает all: initial на элемент, он будет заблокировать все наследование и reset все свойства, как будто никаких правил появился на уровне автора, пользователя или пользователя-агента каскада.

Это может быть полезно для корневого элемента "виджета", включенного в страницу, которая не хочет наследовать стили внешней страницы. Обратите внимание, однако, что любой стиль по умолчанию, примененный к этому элементу (такой как, например, display: block из таблицы стилей UA на блочных элементах как <div>) также будет сбрасываться.

Вам нужно применить all: initial к вашему div и all: unset его потомкам:

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

Вы можете использовать класс в своем div вместо id, так что любые правила, которые вы пишете для стилирования его потомков, не должны соответствовать или бить высокую специфичность, используемую в этом правиле.

Чтобы быть действительно безопасным, вы можете также заблокировать стили для потенциальных потомков псевдоэлементов:

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

В качестве альтернативы, для более широкой поддержки браузера вы можете вручную сделать то, что 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;
  ...
}

Вы можете поощрять поддержку браузера для стенографического свойства all и отслеживать его принятие с помощью этих ссылок на проблемы:

Текущая информация о поддержке браузера для all сокращенного свойства доступна здесь.

Ответ 2

Вы не можете технически, как CSS должен работать. Если существует какой-либо стиль, определенный для div в вашей таблице стилей, он будет применяться ко всем элементам div.

Несколько вещей, которые вы можете попробовать, это не использовать стиль с именем тега, а вместо этого дать имя класса и дать объявление стиля классу. так что вы можете убедиться, где все стили будут идти.

ИЛИ. если вы хотите, чтобы какой-то определенный тег Div не имел стиля, в то время как другие Divs имели. вы всегда можете reset дать несколько разных имен классов или id и reset объявления стилей

Ответ 3

Старый вопрос, но с момента принятого ответа все немного изменилось. Теперь для решения этой проблемы есть ключевое слово, рекомендованное CSSWG под названием revert, которое лучше подходит, чем initial и unset, поскольку сбрасывает свойство элемента к значению, определенному в таблице стилей агента пользователя, а не к начальному значению свойства, независимо от того, какой элемент он использовал. Так, например, для div внутри #mydiv будет установлено отображение block, как мы и ожидали, а не inline.

Вы должны сделать это:

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

К сожалению, revert не поддерживается ни одним браузером, кроме Safari (для Mac и iOS) на момент написания.

Есть также кое-что еще, чтобы принять во внимание относительно принятого ответа. Если вы хотите стилизовать что-либо внутри #mydiv, вам нужно сделать это с помощью селектора, который, по крайней мере, столь же специфичен, как и тот, который вы использовали для отмены или отмены всего, в противном случае он будет переопределен этим правилом, даже если он появится после это в CSS.

Поэтому вам нужно сделать что-то вроде этого (обратите внимание на #mydiv, который повышает специфичность правил):

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

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

// etc.

Ответ 4

Одна вещь, которая может быть полезна, - это синтаксический селектор CSS, который доступен во всех браузерах, включая IE7+. Это позволяет применять стиль, который не каскадируется на детей. Например, в вашем коде вы можете использовать этот CSS:

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

И этот CSS применим только к элементам непосредственно в элементе BODY.

Ответ 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 height
newIframe.addEventListener('load', function onIFrameLoad(e) {
    const iframeBody = this.contentDocument.querySelector("body");
    this.style.height = '${iframeBody.scrollHeight}px';
});

Это прекрасно сработало, когда мне пришлось встраивать сложный HTML файл в мою веб-страницу, извлеченную удаленно, без предупреждения MixedContent и без родительских стилей HTML, перекрывающих встроенный HTML. Спасибо https://benfrain.com/sandbox-local-htmlcss-code-snippets-inside-iframe-style-guidespattern-libraries/ за эту прекрасную идею!

Хотя хитрость CSS #mydiv * { all: unset }, как предлагается в принятом решении здесь, работает, она перестала быть сложной операцией браузера, поскольку на моей странице было много узлов DOM.