简体   繁体   中英

CSS3 Selectors: + vs ~ and the opposite of ~?

After seeing the different selectors available (as of CSS3), the difference between the + and ~ seem to be nearly the same. And it also appears there is no selector with opposite functionality to ~ .

Taken from www.w3schools.com :

  • div + p : Selects all <p> elements that are placed immediately after <div> elements.
  • p ~ ul : Selects every <ul> element that are preceded by a <p> element.

The effect of p ~ ul can be rewritten as:

Selects all <ul> elements that are placed after a <p> element.

Because preceded by a <p> means the <p> is before the <ul> .

This leaves the only difference between these operators being that + only select elements immediately after (I assume all consecutive occurrences), whereas ~ selects elements anywhere after (but still with the same parent).

  1. Is my understanding of the difference correct?

Originally I thought the two operators were opposites due to the somewhat confusing english. So, my follow-up questions is this:

  1. How can I select every element placed before (or immediately before) another element?


I'm working with this case scenario:

I have 2 div's side-by-side in the same parent div.

 <div id="container"> <div id="column_left"> </div> <div id="column_right"> </div> </div> 

When I hover either div, both should gradually become more opaque using CSS transitions. When I'm not hovering either, they should become more transparent.

So, to select the right column when the left is hovered I would using the selector:

 #column_left:hover+column_right { opacity: 0.9; transition: opacity 300ms; -webkit-transition: opacity 300ms; } 

Now, how can I select the left column when the right is hovered?

Here is my CSS so-far:

 div { border: 1px solid black; background: #262626; } #left { float: left; width: 200px; height: 200px; margin: 0; transition: background 300ms; -webkit-transition: background 300ms; } #right { display: inline-block; width: 200px; height: 200px; transition: background 300ms; -webkit-transition: background 300ms; } #left:hover,#left:hover~#right { background: #909090; transition: background 300ms; -webkit-transition: background 300ms; } 
 <div id=left> </div> <div id=right> </div> 

Is my understanding of the difference correct?

Yes. Selectors L3 defines those two types of sibling combinators (emphasis mine):

  • Adjacent sibling combinator

    The adjacent sibling combinator is made of the "plus sign" (U+002B, +) character that separates two sequences of simple selectors. The elements represented by the two sequences share the same parent in the document tree and the element represented by the first sequence immediately precedes the element represented by the second one.

  • General sibling combinator

    The general sibling combinator is made of the "tilde" (U+007E, ~) character that separates two sequences of simple selectors. The elements represented by the two sequences share the same parent in the document tree and the element represented by the first sequence precedes (not necessarily immediately) the element represented by the second one.

How can I select every element placed before (or immediately before) another element?

As explained in Is there a previous sibling selector? , it's not possible to do that with Selectors L3. Selectors L4 may introduce some way to do it, but probably it will only be available in JS (eg through querySelector ) but not in CSS stylesheets because of performance reasons.

A solution for your specific use case

When I hover either div, both should gradually become more opaque using CSS transitions. When I'm not hovering either, they should become more transparent.

 .wrap { float:left; overflow:hidden } div { border: 1px solid black; } #left { float: left; width: 200px; height: 200px; margin: 0; background-color: red; transition: background 300ms; -webkit-transition: background 300ms; } #right { float:left; width: 200px; height: 200px; background-color: blue; transition: background 300ms; -webkit-transition: background 300ms; } .wrap:hover > #right, .wrap:hover > #left { background: #909090; transition: background 300ms; -webkit-transition: background 300ms; } 
 <div class="wrap"> <div id=left> </div> <div id=right> </div> </div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM