ArcDare
ArcDare

Reputation: 3106

Disinherit (reset) the CSS style of a specific element?

Ok, I have a beautiful web, with its styles within a CSS and everything

But now I've found a problem, I want ONE list to be virgin, without any style inherited.

I know I can do it just giving it a style="(...)" so it overwrites the inherited style, but, is there any instruction / trick / something to do it without doing this?

Upvotes: 20

Views: 25571

Answers (4)

Fred Gandt
Fred Gandt

Reputation: 4312

Shadow DOM

The feature(s) of the Shadow DOM v1 currently (constantly subject to change) have growing support, offering a wealth of possibilities, including scoped CSS.

Shadow DOM v0 was implemented in Chrome/Opera but other browser vendors are implementing v1.
MS Edge status: Under Consideration
Firefox status: in-development

From Google Developers: Shadow DOM v1: Self-Contained Web Components:

Hands down the most useful feature of shadow DOM is scoped CSS:

  • CSS selectors from the outer page don't apply inside your component.
  • Styles defined inside don't bleed out. They're scoped to the host element.

CSS selectors used inside shadow DOM apply locally to your component. In practice, this means we can use common id/class names again, without worrying about conflicts elsewhere on the page. Simpler CSS selectors are a best practice inside Shadow DOM. They're also good for performance.

Below, we attachShadow to a new createElement( "div" ) to which we apply the style.all = "unset" to disinherit all the rules applied to the rest of the document's divs.

We then fill our shadow-root with whatever content we like, and supply any styles desired, before appendChild( "new_div" ) injects our content into the body.

The result is stylistically isolated content.

const new_style = document.createElement( "style" ),
      new_div = document.createElement( "div" ),
      new_list = document.createElement( "ul" ),
      new_entries = [ "Lorem", "Ipsum", "Dolor" ],
      shadow = new_div.attachShadow( { mode: "open" } );
new_style.textContent = "ul { list-style: none; }";
new_div.style.all = "unset";
new_entries.forEach( ( v ) => {
  var li = document.createElement( "li" );
  li.textContent = v;
  new_list.appendChild( li );
} );
shadow.appendChild( new_style );
shadow.appendChild( new_list );
document.body.appendChild( new_div );
body {
  background: antiquewhite;
}
ul {
  margin: 2em;
  border: 2px gray solid;
  border-right: 0;
  border-left: 0;
  background: cornflowerblue;
}
li {
  margin: inherit;
  font-family: "Comic Sans MS";
}
<body>
  <ul>
    <li>Foo</li>
    <li>Bar</li>
    <li>Baz</li>
    <li>Qux</li>
  </ul>
</body>

Upvotes: 1

Marat Tanalin
Marat Tanalin

Reputation: 14123

The CSS Cascading and Inheritance Level 3 specification introduces ability to reset all properties at once. This is achieved by using the all shorthand property with the value of initial or unset depending on whether you need to reset inherited properties.

Note that these have nothing to do with browser’s default values.

The feature is available in Firefox 27+, Chrome 37+, and Opera 24+.

Until the feature is widely implemented, you can use “namespace” classes. For example, to separate layout styles from content styles, a class like content could be used as a namespace for all content styles.

Simplified example:

/* Global styles for UL lists. */
UL {list-style: none; margin: 0; padding: 0; }

/* Styles for UL lists inside content block. */
.content UL {list-style: disc; margin: 1em 0 1em 35px; }

Upvotes: 10

ZwartyZ
ZwartyZ

Reputation: 318

You can try this http://cleanslatecss.com/ it completely reset the target element, it's only css, no js, you just have to add a class to the target and it's all done.

The problem I found in the other answers is that nobody used !important so it could happen that the reset may not be applied to the element, everything is solved with cleanslate that do that for you.

Upvotes: 2

T. Junghans
T. Junghans

Reputation: 11683

This is a problem that is solved best by avoiding it from the beginning. I try to keep contextual (or descendant) selectors to a minimum and I avoid using tag names as selectors. Instead I make use of classes so that my html elements (<a>, <p>, <ul>, <span>, etc) will always look like they've not been styled no matter what the context/its parent element is.

In your case, I think you can only overwrite the inherited styles as you have mentioned with the inline-style attribute or with !important or even better, create a .reset class:

.reset { with: auto; height: auto; padding: 0; /* etc */ }

All solutions mentioned above have drawbacks, so you'll need to choose your battle.

Upvotes: 3

Related Questions