0

I have code similar to the following:

.banner.customer-service {
    height: calc(70vh - 85px - 8em);
    background:url(//careers.jobvite.com/marinecreditunion/images/customerservice.jpg) center center / cover no-repeat;
}
.banner.customer-service span {
    background:rgba(0,0,0,0.5);
}
.banner.early-talent {
    height: calc(70vh - 85px - 8em);
    background:url(//careers.jobvite.com/marinecreditunion/images/earlytalent.jpg) center center / cover no-repeat;
}
.banner.early-talent span {
    background:rgba(0,0,0,0.5);
}
<div class="banner"><p>Header</p></div>
<div class="banner customer-service"><p>Specific Header</p></div>
<div class="banner early-talent"><p>Other Specific Header</p></div>

I have 12 classes similar to the .banner.specific-class. What I'm hoping to do is something like this:

.banner.* > p {} /* stuff to apply to the p tag */

I DON'T want the style applied to elements with just .banner; I only want to apply the styles to elements with .banner and a second class.

My goal is to apply styling ONLY to elements that have .banner.other-class p and not the base .banner p.

Is there a way to do this without writing individual CSS styles for each of the 12 classes?

TylerH
  • 20,799
  • 66
  • 75
  • 101
brettwbyron
  • 95
  • 12

3 Answers3

2

You could use .banner > p {} or .banner p {} if your paragraphs are not necessarily direct children.

EDIT

My goal is to apply styling ONLY to elements that have .banner.other-class p and not the base .banner p.

Is there a way to do this without writing individual CSS styles for each of the 12 classes?

You can define your rules for a custom class, like this:

.banner.my-custom-class p {
    /*Your rules*/
}

and then you can ensure that you add that class to banner. Another possibility is to create a class which should not be applied, like:

.banner:not(.my-other-custom-class) p {
    /*Your rules*/
}

and then you can add this class to tags where you do not want your styles to be applied. If you need further customizations, you might consider customization via Javascript, or giving more information about your classes to us. Of course, the simplest is to create rules for each different classes, like

.banner.myclass1 p, .banner.myclass2 p, banner.myclass3 p {
    /*Your rules*/
}
TylerH
  • 20,799
  • 66
  • 75
  • 101
Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
2

If all of your additional 12 classes have a hyphen, you can target them with the wildcard attribute selector applied to the .banner class, like so:

.banner[class*="-"] p

Demo:

.banner[class*="-"] p {
    color: red;
}
<div class="banner"><p>Unstyled Header</p></div>
<div class="banner customer-service"><p>Styled Header</p></div>
<div class="banner"><p>Unstyled Header</p></div>
<div class="banner early-talent"><p>Other Styled Header</p></div>
<div class="banner"><p>Unstyled Header</p></div>
<div class="banner other-class"><p>Another Styled Header</p></div>
<div class="banner"><p>Unstyled Header</p></div>
<div class="banner another-class"><p>One More Styled Header</p></div>
<div class="banner"><p>Unstyled Header</p></div>

You could also use .banner[class*=" "] p, but that would "fail" technically and apply to any situations where you have class="banner " (e.g. the initial banner class followed by a whitespace) ...in case you might be dynamically adding or removing classes via JavaScript or PHP or something.

If there is no shared character between the 12 classes, you may need to use JavaScript to select them, or apply a third class to the elements that have at least .banner and one other class and just select by that class. Re-dressing the HTML may be the best solution here, so that you can keep your CSS simple.

TylerH
  • 20,799
  • 66
  • 75
  • 101
  • Unfortunately, not all of the specific classes have hyphens. Is there any way to get MORE generalized from `.banner[class*='-'] p` to something like `.banner[class*=*] p `? – brettwbyron Mar 11 '19 at 14:30
  • @brettwbyron No, unfortunately you can't use `*` as a wildcard for the *value* of an attribute selector; you have to use an exact, literal character or string. – TylerH Mar 11 '19 at 14:33
2

You can think about this differently and target all the elements then reset the style where only the banner class is present but you need to pay attention to whitespace in the class attribute:

.banner {
  color:red;
}

[class="banner"] {
  color:blue;
}
<div class="banner"><p>Header</p></div>
<div class="banner customer-service"><p>Specific Header</p></div>
<div class="banner early-talent"><p>Other Specific Header</p></div>


<div class="banner "><p>I will be red!!!</p></div>

To avoid the whitespace issue you may consider some JS and use the trim() function. Here is another answer where I used the same trick: https://stackoverflow.com/a/52557233/8620333

You can also combine this with :not()

.banner:not([class="banner"]) {
  color:red;
}
<div class="banner"><p>Header</p></div>
<div class="banner customer-service"><p>Specific Header</p></div>
<div class="banner early-talent"><p>Other Specific Header</p></div>


<div class="banner "><p>I will be red!!!</p></div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • So, the `[class="banner"]` selector targets only the elements with the class `banner` and has no whitespace? So, anything else has styling, and I just have to style the base `.banner` more specifically rather than the other way around? – brettwbyron Mar 11 '19 at 15:27
  • @brettwbyron exactly, or you consider the not selector to avoid reset the style and select only the needed elements – Temani Afif Mar 11 '19 at 15:28
  • If it is possible to have a tag with the banner class, but some other class as well, but the rules are not to be applied there, then this will not work. – Lajos Arpad Mar 11 '19 at 17:39