8

This is a made-up example to represent a type of problem I have on a daily basis, when I'm using a content management system that sets up the HTML for tons of webpages and I need general ways of applying CSS according to mockups. I'm wondering if there is a non-Javascript way of solving it.

Suppose I have a div of class some-div, which will either have 1 or 2 child divs. When it has 1 child div, that child should have a red background; when it has 2 child divs, they should have blue backgrounds:

    <div class="some-class">
        <div>
             <p>The background of this should be red.</p>
        </div>
    </div>
    
    <div class="some-class">
        <div>
             <p>The background of this should be blue.</p>
        </div>
        <div>
             <p>The background of this should be blue</p>
        </div>
    </div>

Is there a way of doing this in CSS? A hack, perhaps?

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • Look here http://stackoverflow.com/questions/8720931/can-css-detect-the-number-of-children-an-element-has – Lior Raz Dec 24 '14 at 19:58
  • 3
    Probably hypocritical on my own part but I'm willing to let this question slide because it's clearly well-written and well-constructed, and the solution is non-obvious. I would totally understand if the OP had no idea what to try to begin with. – BoltClock Dec 25 '14 at 04:26

5 Answers5

11

Well, I'll cave. Here's my solution

http://jsfiddle.net/z7ajmh5z/

.some-class div {
    background: blue;
}

.some-class div:first-child:last-child {
    background: red;
}
    <div class="some-class">
        <div>
             <p>The background of this should be red.</p>
        </div>
    </div>
    
    <div class="some-class">
        <div>
             <p>The background of this should be blue.</p>
        </div>
        <div>
             <p>The background of this should be blue</p>
        </div>
    </div>

Edit

Apparently, there is also the :only-child selector which I found by looking into @LiorRaz's comment

It has about as much support as :last-child

Would be worth at least looking into. Here's an embedded example.

.some-class div {
  background: blue
}

.some-class div:only-child {
  background: red;
}
    <div class="some-class">
        <div>
             <p>The background of this should be red.</p>
        </div>
    </div>
    
    <div class="some-class">
        <div>
             <p>The background of this should be blue.</p>
        </div>
        <div>
             <p>The background of this should be blue</p>
        </div>
    </div>
Community
  • 1
  • 1
Joseph Marikle
  • 76,418
  • 17
  • 112
  • 129
  • 1
    Perfect and with wider support – Gabriele Petrioli Dec 24 '14 at 20:07
  • 1
    Browser support for the level 3 structural pseudo-classes is identical. No browser I'm aware of supports more or fewer pseudo-classes than others. Don't worry about browser support unless you need to develop for IE8. – BoltClock Dec 25 '14 at 04:27
  • Oh, that's right - Chrome has [all kinds](http://stackoverflow.com/questions/20335187/complex-selector-dont-work-in-last-blink-version-nth-child2nth-last-child2) of [issues](http://stackoverflow.com/questions/20436485/google-chrome-and-nth-last-child) with `:nth-last-child()`. IE9+ is fine. – BoltClock Dec 25 '14 at 04:52
8

you can target the div with css pseudo FIDDLE HERE

CSS

.some-class div:only-child
{
    background: red;
}
.some-class div:not(:only-of-type)
{
    background: blue;
}
Ghostff
  • 1,407
  • 3
  • 18
  • 30
5

For modern browsers that support the :nth-last-of-type (http://www.w3.org/TR/selectors/#nth-last-child-pseudo)

.some-class div{
    background-color: red;
}

.some-class div + div,
.some-class div:nth-last-child(2){
    background-color: blue;
}

Demo at http://jsfiddle.net/gaby/ofhb3hj1/

Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317
4

Yes you can do this with nth-of-type. Set all of them to background-color: red then you can target every .some-class starting after the 1st one and overwrite the div color to be blue:

.some-class div{
  background-color: red;
}

.some-class:nth-of-type(1n+2) div{
  background-color: blue;
}

FIDDLE

UPDATE FOR ckuijjer

Who said: don't think this is a solution. The question is can you color the child <div>'s a red if there it's the only child and blue if there are two children.

Yes you can. Here is how:

.some-class:nth-of-type(1n+2) div:first-child{
  background-color: red;
}

.some-class:nth-of-type(1n+2) div:nth-of-type(1n+2){
 background-color: blue;
}

FIDDDLE

Bottom line is this is how to do it, no matter what the OP was trying to portray in his/her explanation and whether or not I or anyone else understood what he/she actually wanted, the answer (question title was: Is it possible to do this with only CSS?) is: yes, it can be done with just CSS. Just need the right equation.

jmore009
  • 12,863
  • 1
  • 19
  • 34
  • 1
    I don't think this is a solution. The question is can you color the child `
    `'s a red if there it's the only child and blue if there are two children.
    – ckuijjer Dec 24 '14 at 19:59
  • @GabyakaG.Petrioli there could be definite complications if the HTML were to change and the `nth-of-type` may have to be adjusted, but the OP asked for a specific example. – jmore009 Dec 24 '14 at 19:59
  • yes, but not this one. His question is about the two child divs, not the containers.. (*its two examples he gives not a big one*) – Gabriele Petrioli Dec 24 '14 at 20:00
  • @GabyakaG.Petrioli look at the fiddle HTML text and tell me thats not exactly what he was asking for... – jmore009 Dec 24 '14 at 20:01
  • 1
    @jmore009 nice! i really love seeing all the different pseudo class solutions. – ckuijjer Dec 24 '14 at 20:06
  • Your 2nd approach is still not what the TO expects. He/she expects kind of a hypotetical `.some-class:child-count(2) div {background: blue; } .some-class:child-count(1) div { background: red; }`. And it should (probably) work if both `div.some-class` are alone in the DOM. I admit, the TO should clarify this point. – try-catch-finally Dec 24 '14 at 20:33
  • also his first sentence: `This is a made-up example to represent a type of problem I have on a daily basis` this was a hypothetical question – jmore009 Dec 24 '14 at 20:40
  • 1st: @ckuijjer you've changed the words in the paragraphs to match the output. Just use the TO's markup and you'll see your outcome is wrong. Try removing one of the `div`s or add more in an alternating order to test it. 2nd: If you're not sure what the TO expects *ask for clarification*. For me the TO's explation was clear, so was it for 3 other. @jmore009: Even for "made-up examples" a clear question should get a _correct_ answer. – try-catch-finally Dec 24 '14 at 21:04
  • @try-catch-finally good catch! I was just so happy with all the pseudo class solutions that I didn't take a good look at this solution – ckuijjer Dec 24 '14 at 21:13
  • As others have already mentioned, I wouldn't rely on the assumption that the first `.some-class` will only ever contain one child and the second element (or subsequent elements) will only ever contain two children. Otherwise it makes the question deceptively easy. If you wanted to stretch the "possible with only CSS" definition you could patch together some really brittle hack and call it "possible", only for it to fall apart the moment any of the markup is changed (which, in fact, is what would happen with this answer). How would that be useful? – BoltClock Dec 25 '14 at 04:29
-1

Just add a class to all the ones you want red, and a separate one to all that you want blue. Example:

<div class="some-class">
    <div class="red">
         <p>The background of this should be red.</p>
    </div>
</div>

<div class="some-class">
    <div class="blue">
         <p>The background of this should be blue.</p>
    </div>
    <div class="blue">
         <p>The background of this should be blue</p>
    </div>
</div>

.blue {
background: blue;
}

.red {
background: red;
}
Horray
  • 693
  • 10
  • 25