Mud
Mud

Reputation: 28991

How to limit the scope of a CSS reset?

I want to use a CSS reset in my app, but my app has the requirement of eventually being embeddable in other apps as a component, so I don't want to do a global reset because it might affect my parent app.

For example, here's a portion of Eric Meyer's reset (edited for brevity):

div, span,h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, em, img, ins, kbd,
q, s, b, u, i, ul, li, form, label, legend, table, caption {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    vertical-align: baseline;
}

My first idea to constrain this reset to children of my main component node is to use decendant selectors. Let's say my app is called "foo":

.foo div, .foo span, foo h1, .foo h2, .foo h3, .foo h4, .foo h5, .foo h6, .foo p, .foo blockquote,
.foo pre, .foo a, .foo em, .foo img, .foo ins, .foo kbd, .foo q, .foo s, .foo b, .foo u, .foo i,
.foo ul, .foo li, .foo form, .foo label, .foo legend, .foo table, .foo caption  {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    vertical-align: baseline;
}

The problem I'm having is that this wins the specificity fight on almost everything in my app.

For instance:

.huge-red-border {
    border: 10px solid red;
}

<div class="foo"> <!-- my component's root node -->
    <div class="huge-red-border">
        I should have a huge red border, but I don't
        because ".foo div" takes precedent over ".huge-red-border".
    </div>
</div>

I can't add !important to every one of my rules (because I need that distinguisher to have meaning within my rules).

Any ideas on how to solve this?

Upvotes: 2

Views: 352

Answers (1)

Michael Benjamin
Michael Benjamin

Reputation: 371251

It is a specificity and cascade issue.

You can overcome it by putting your preferred elements further down in the stylesheet and boosting their specificity:

.foo div {     /* specificity points: 11 */
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  vertical-align: baseline;
}
div.huge-red-border {    /* specificity points: 11 */
  border: 10px solid red;
}
<div class="foo">
  <!-- my component's root node -->
  <div class="huge-red-border">
    I should have a huge red border, but I don't because ".foo div" takes precedent over ".huge-red-border".
  </div>
</div>

Here's another method that allows you to keep boosting specificity using the :not() pseudo-class:

.foo div {   /* specificity points: 11 */
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  vertical-align: baseline;
}
.huge-red-border:not(html):not(body) { /* specificity points: 12 */
  border: 10px solid red;
}
<div class="foo">
  <!-- my component's root node -->
  <div class="huge-red-border">
    I should have a huge red border, but I don't because ".foo div" takes precedent over ".huge-red-border".
  </div>
</div>

From the spec:

6.6.7. The negation pseudo-class

The :not() pseudo allows useless selectors to be written.

For instance :not(*|*), which represents no element at all, or foo:not(bar), which is equivalent to foo but with a higher specificity.

Upvotes: 3

Related Questions