3

Problem Statement

How do I apply css to all elements of a certain class except when first child is of certain id?

Examples

I have html as follows:

HTML Example 1

<div class="content-body">
  <div>
  </div>
</div>

HTML Example 2

<div class="content-body">
  <div id="container-special">
  </div>
</div>

css as follows:

.content-body {
  max-width: 1050px;
}

Now, I would like the css to apply only when the first child div is not of id=container-special, i.e, I would like the css to take effect only for example 1.

What I have tried

I have considered css selectors :first-child, and not, but I am unable to figure out how to apply them for my case.

Any help is appreciated.

Update1 [Solution]

Thanks to everyone who answered my question. Based on provided inputs, I used the following solution:

.content-body {
  max-width: 1050px;
}
// called when component containing <div id="container-special> is loaded
fixParentContainerWidthOnMount() {
  const cr = document.getElementById('container-special')
  const parent = cr.parentElement
  if (parent.className.includes('content-body')) {
    parent.classList.remove('content-body')
  }
}

// called when component containing <div id="container-special> is unloaded
fixParentContainerWidthOnDestroy() {
  const cr = document.getElementById('container-special')
  const parent = cr.parentElement
  if (
    parent.className.includes('container') &&
    !parent.className.includes('content-body')
  ) {
    parent.classList.add('content-body')
  }
}
Manas
  • 483
  • 7
  • 23
  • 1
    This is not possible because CSS is cascading. – mootookoi Jul 21 '19 at 06:55
  • Possible duplicate of [Is there a CSS parent selector?](https://stackoverflow.com/questions/1014861/is-there-a-css-parent-selector) – connexo Jul 21 '19 at 07:09
  • 1
    As @mootookoi said, this cannot be achieved with CSS because you cannot apply styles based on child properties. There just no grammar for a selector that would do that. – connexo Jul 21 '19 at 07:10
  • Thanks. I will try some non-css approach for this use case. – Manas Jul 21 '19 at 07:14

3 Answers3

6

Here you have to use a combination of css selector types. You have to use child-combinator and :not psuedo class here. But this will apply the styling to all the other tags which come under content-body except the container-special div.

.content-body>:not(#container-special) {
  max-width: 1050px;
}

However if you want to prevent applying the style to that entire div. You need to make some changes in the HTML code too.

HTML

<div class="content-body" id="container-special">
  <div></div>
</div>

CSS

.content-body:not(#container-special) {
  max-width: 1050px;
}
terance98
  • 109
  • 5
3

Simply slightly change your markup:

From

<div class="content-body">
  <div id="container-special">
  </div>
</div>

to

<div class="content-body has-container-special">
  <div id="container-special">
  </div>
</div>

which allows you to formulate

.content-body:not(.has-container-special) {
  max-width: 1050px;
}

If you cannot change the markup, you could add that class via Javascript:

document.addEventListener('DOMContentLoaded', function() {
  const el = document.querySelector('.content-body #container-special:first-child');
  if (el) el.parentElement.classList.add('has-container-special');
})
connexo
  • 41,035
  • 12
  • 60
  • 87
2

If you were to use jQuery you could access the element like this:

$('.content-body > :not(#container-special)').parent().css("max-width", "1050px")

Or for normal JS you could set the CSS:

.content-body {
  max-width: 1050px;
}

And then remove it from the element that contains the element with that ID:

var cs = document.getElementById('container-special')
var parent = cs.parentElement

if (parent.className == 'content-body') {
  parent.style.maxWidth = "initial"
}
Rob Kwasowski
  • 2,415
  • 2
  • 7
  • 28