Difference between the selectors div + p (plus) and div ~ p (tilde)
CssCss SelectorsCss Problem Overview
The way that w3schools phrases it, they sound the same.
> W3Schools' CSS reference
>
> div + p
> Selects all <p>
elements that are placed immediately after <div>
elements
>
> div ~ p
> Selects every <p>
element that are preceded by a <div>
element
If a <p>
element is immediately after a <div>
element, doesn't that mean that the <p>
element is preceded by a <div>
element?
Anyhow, I'm looking for a selector where I can select an element that is place immediately before a given element.
Css Solutions
Solution 1 - Css
Adjacent sibling selectors X + Y
> Adjacent sibling selectors have the following syntax: E1 + E2, where > E2 is the subject of the selector. The selector matches if E1 and E2 > share the same parent in the document tree and E1 immediately precedes > E2, ignoring non-element nodes (such as text nodes and comments).
ul + p {
color: red;
}
> In this example it will select only the > element that is immediately preceded by the former element. In this > case, only the first paragraph after each ul will have red text.
ul + p {
color: red;
}
<div id="container">
<ul>
<li>List Item</li>
<li>List Item</li>
<li>List Item</li>
<li>List Item</li>
</ul>
<p>This will be red</p>
<p>This will be black</p>
<p>This will be black</p>
</div>
General sibling selectors X ~ Y
> The ~ combinator separates two selectors and matches the second > element only if it is preceded by the first, and both share a common > parent.
ul ~ p {
color: red;
}
> This sibling combinator is similar to X + Y, however, it's less > strict. While an adjacent selector (ul + p) will only select the first > element that is immediately preceded by the former selector, this one > is more generalized. It will select, referring to our example above, > any p elements, as long as they follow a ul.
ul ~ p {
color: red;
}
<div id="container">
<ul>
<li>List Item
<ul>
<li>Child</li>
</ul>
</li>
<li>List Item</li>
<li>List Item</li>
<li>List Item</li>
</ul>
<p>This will be red.</p>
<p>This will be red.</p>
<p>This will be red.</p>
<p>This will be red.</p>
</div>
Source
Solution 2 - Css
> If a <p>
element is immediately after a <div>
element, doesn't that mean that the <p>
element is preceded by a <div>
element?
This is correct. In other words, div + p
is a proper subset of div ~ p
— anything matched by the former is also matched by the latter, by necessity.
The difference between +
and ~
is that ~
matches all following siblings regardless of their proximity from the first element, as long as they both share the same parent.
Both of these points are most succinctly illustrated with a single example, where each rule applies a different property. Notice that the one p
that immediately follows the div
has both rules applied:
div + p {
color: red;
}
div ~ p {
background-color: yellow;
}
<section>
<div>Div</div>
<p>Paragraph</p>
<p>Paragraph</p>
<p>Paragraph</p>
</section>
<section>
No div
<p>Paragraph</p>
<p>Paragraph</p>
<p>Paragraph</p>
</section>
> Anyhow, I'm looking for a selector where I can select an element that is place immediately before a given element.
Unfortunately, there isn't one yet.
Solution 3 - Css
consider this example:
p + p { /* the first p immediately after a preceding p */
color: red;
}
p ~ p { /* all p's after a preceding p */
font-weight: bold;
}
<div>
<p>1</p>
<div>separator</div>
<p>2</p> <!-- only ~ is applied here -->
<p>3</p> <!-- both + and ~ are applied here -->
</div>
Solution 4 - Css
1) Adjacent Sibling Selectors (S1 + S2)
Adjacent sibling selector is used to select a specified element which is immediate next to another specified element. Both elements should be in the same level.
div + p {
color:red;
}
Adjacent Sibling Selectors example
2) General Sibling Selectors (S1 ~ S2)
General sibling selector is used to select all specified sibling elements of another specified element.
div ~ p {
color:red;
}
General Sibling Selectors example
Adjacent Sibling(S1 + S2) vs General Sibling(S1 ~ S2) selectors:
Adjacent sibling(S1 + S2) selector selects immediate sibling element only but general sibling(S1 ~ S2) selector selects all sibling elements of another specified element. Both cases, both elements(S1 and S2) should be in the same level.
Remaining selectors are explained here: https://www.csssolid.com/35-css-selectors-to-remember.html