4

I am styling a series of pages of which I have no control of their markup, and it is presenting some unique challenges. The styles are based on a design mockup that I was given and therefore there are instances of- for example- h2 elements that must look different than other particular h2 elements in order for the design to be adhered to.

Currently, I am trying to apply some styling that should affect most h2 elements, but not h2 elements which appear within a div with the class "block". How would the CSS selector look in this case? I went out on a limb and tried this, but was correct in assuming it wasn't quite right.

h2:not(.block h2) {
   ~styling for main h2 elements~
}
.block h2 {
  ~separate styling for h2 elements within .block div~
}

Can someone shed some light? Thanks!

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • Have you tried changing the order and putting .block h2 above, as the the first one doesn't know what .block h2 is when it's loaded first. – Thomas James Sep 21 '16 at 21:25
  • Can you give us a sample of the HTML and the actual styles that need to be applied? – j08691 Sep 21 '16 at 21:27
  • 1
    Unfortunately it doesn't work this way, the selector inside `:not()` must be a simple selector. This means that descendent selectors like `.block h2` won't work. – joshhunt Sep 21 '16 at 21:29
  • 2
    You're really better off if you don't jump through hoops trying to avoid styles for "general" h2 affecting those h2 inside div.block, but rather simply __overwrite__ the _general_ styles that you don't like for `div.block h2` with the _specific_ property values that you do want those to have. – CBroe Sep 21 '16 at 21:36
  • There's a canonical for this somewhere... – BoltClock Sep 22 '16 at 04:22

2 Answers2

5

You can try this:

h2 {...}

.block h2 {...}
1

I am trying to apply some styling that should affect most h2 elements, but not h2 elements which appear within a div with the class block.

You haven't indicated the level where the h2 exists within the div. So here are a few options, if you want to use the :not() pseudo-class.

If the h2 is one level in:

div:not(.block) h2 {
    color: red;
}
<div class="block">
    <h2>with block class</h2>
</div>

<div>
    <h2>without block class</h2>
</div>

If the h2 is two levels in:

div:not(.block) div h2 {
  color: red;
}
<div class="block">
  <div>
    <h2>with block class</h2>
  </div>
</div>

<div>
  <div>
    <h2>without block class</h2>
  </div>
</div>

If the h2 is three levels in:

div:not(.block) div div h2 {
  color: red;
}
<div class="block">
  <div>
    <div>
      <h2>with block class</h2>
    </div>
  </div>
</div>

<div>
  <div>
    <div>
      <h2>without block class</h2>
    </div>
  </div>
</div>

and so on...

Also keep in mind that :not(), as it currently exists in most browsers, only accepts simple selectors as an argument.

Your example...

h2:not(.block h2) {
   ~styling for main h2 elements~
}

... will fail in most browsers because the argument contains a complex selector (created by a descendant combinator, in this case).

More details here: https://stackoverflow.com/a/37305971/3597276

Community
  • 1
  • 1
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701