General CSS Selector Specification

For a document:

<h1>Section 1</h1>
<p>I came after a h1 and should be red.</p>
<p>I came after a h1 and should be red.</p>

<h2>Section 2</h2>
<p>I came after a h2 and should be green.</p>
<p>I came after a h2 and should be green.</p>

<h1>Section 3</h1>
<p>I should be the same color as the section one text?</p>
<p>I should be the same color as the section one text?</p>

      

I tried to style it:

h1 ~ p {
    color: red;
}

h2 ~ p {
    color: green;
} 

      

http://jsfiddle.net/4ks7j938/7/

I expected paragraphs 1 and 3 to have the same style, and the third paragraph matches a more specific selector h1 ~ p

because it h1

is a closer cousin than h2

. However, in my testing, the result is that paragraphs 2 and 3 are styled the same way.

Two questions:

Does the css selector spec define this behavior somewhere? The css spec in the General sibling selector seems open to interpretation here.

How can I achieve the intended result with the same method as points 1 and 3? I cannot add classes or any attributes to the html, I can only manipulate the css.

+3


source to share


5 answers


Both selectors have the same specificity, which causes the precedence to h2 ~ p

be defined after, therefore cascading over h1 ~ p

. How close a sibling is does not matter.
For the behavior you want, you can use the adjacent sibling selector +

.

If you change h1 ~ p

after you see it accepts the foreword



h2 ~ p {
    color: green;
}

h1 ~ p {
    color: red;
}
      

<h1>Section 1</h1>
<p>I came after a h1 and should be red.</p>
    
<h2>Section 2</h2>
<p>I came after a h2 and should be green.</p>

<h1>Section 3</h1>
<p>I should be the same color as the section one text?</p>
      

Run codeHide result


+5


source


Musa seems correct that you cannot solve this in the general case using CSS alone.

But here's one solution for three sections:

h1 ~ p,
h1 ~ h1 ~ p {
    color: red;
}

h2 ~ p {
    color: green;
}

      

http://jsfiddle.net/4ks7j938/12/



Or, depending on the number of interlaces, this could work as well and could be expanded to more partitions:

h1 ~ p,
h1 ~ h2 ~ h1 ~ p,
h1 ~ h2 ~ h1 ~ h2 ~ h1 ~ p
/* add more as needed */ {
    color: red;
}

h2 ~ p,
h2 ~ h1 ~ h2 ~ p,
h2 ~ h1 ~ h2 ~ h1 ~ h2  ~ p
/* add more as needed */ {
    color: green;
}

      

http://jsfiddle.net/4ks7j938/15/

However, neither approach is particularly scalable.

+3


source


What a difficult question! If you have access to add some jQuery it might be helpful to use move methods . The following works, but you will need to fit your specific needs, so another way might be better.

$( "h1" )
  .nextUntil( "h2" )
    .css( "color", "red" );

$( "h2" )
  .nextUntil("h1")
    .css( "color", "green" );

      

updated violin

+1


source


your code has the css of the tag h1

on the first line, so it will look for the tag p

that is the sibling with the tag h1

and will apply red to the whole tag p

. on the very next line, two tags will be found p

, which below the first h1 tag and those two

p` tag will be applied by the second css. This is the protrusion problem you have. Now the solution to your problem is css3 adjacent sibling selector

Have a look at this fiddle: http://jsfiddle.net/4ks7j938/9/

0


source


You can use this code:

h1 ~ p {
    color: red; 
}
h2+p{
    color: green; 
}

      

-1


source







All Articles