Next-Sibling Combinator Should Not Work with Complex Selectors

Next-sibling combinator should not work with complex selectors

In the specification you can read:

The next-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.

Nothing is saying that it should only work for "sequences of simple selectors". It's simply saying that the + character separates two sequences of simple selectors and it restricts nothing beyond this so you can have more selectors.

Let's consider the following examples:

.a .b + .b
.b + .b
span.a:not(.b) .b + .b > div

In all of them we have the portion .b + .b which is described by:

the "plus sign" (U+002B, +) character that separates two sequences of simple selectors.


If you read at the start of the specification you will find the generic rule that confirms this:

A selector is a chain of one or more sequences of simple selectors separated by combinators. One pseudo-element may be appended to the last sequence of simple selectors in a selector.

A sequence of simple selectors is a chain of simple selectors that are not separated by a combinator. It always begins with a type selector or a universal selector. No other type selector or universal selector is allowed in the sequence.

A simple selector is either a type selector, universal selector, attribute selector, class selector, ID selector, or pseudo-class.

Basically we can have

Seq_simple_selectors + Seq_simple_selectors Seq_simple_selectors > Seq_simple_selectors

Then inside each Seq_simple_selectors we can have something like:

 div.a.b#id::before

If we consider your example .a .b + .b you have 3 sequences and in each sequence only one simple selector.

You second example is also fine and working if you have the correct HTML that goes with:

.b + .a .b {
background: red;
height: 20px;
}
<div class="b"></div>
<div class="a">
<div class="b"></div>
</div>

CSS general sibling combinator (~) not working with negation pseudo-class (:not)

When all else fails, RTFM. I found the answer to my question in the W3 selector specification:

The negation pseudo-class, :not(X), is a functional notation taking a
simple selector (excluding the negation pseudo-class itself) as an
argument.

and

A simple selector is either a type selector, universal selector,
attribute selector, class selector, ID selector, or pseudo-class.

In other words, it doesn't work because it shouldn't work. The general sibling combinator is not a simple selector, so it cannot be used with the negation pseudo-class.

Links:

  1. http://www.w3.org/TR/css3-selectors/#negation
  2. http://www.w3.org/TR/css3-selectors/#simple-selectors-dfn

css adjacent Sibling combinators - complected selecting

I'm not sure this is possible with CSS, but it's quite simple with jQuery:

var $ul = $('a.title', $('ul.flexMenu-popup > li > ul.subnav').parent());

if ($ul.length) {
alert('yes');
}
else {
alert('no');
}

Why does the general-sibling combinator allow toggling pseudo-element's content, but not the adjacent-sibling?

This is a long-standing bug in WebKit browsers related to the use of certain dynamic pseudo-classes with next-sibling combinators. This happens whether you're applying styles to the sibling element itself or a pseudo-element of that sibling element.

I don't know if anybody has filed a bug report yet, but this has been seen rather frequently on the site:

  • Webkit bug with `:hover` and multiple adjacent-sibling selectors
  • CSS adjacent sibling selectors, Safari and <nav> elements

Strangely it was also reported that Chrome had issues with the general sibling combinator, but as you note it works in your given scenario:

  • Why doesn't this CSS selector work: a:hover ~ span?

So either that was fixed, or something else triggers/triggered it.

CSS Sibling selector doesn't work inside :not()

:not() pseudo-class could not contain sibling selector.

http://dev.w3.org/csswg/selectors3/#negation

The negation pseudo-class, :not(X), is a functional notation taking a simple selector (excluding the negation pseudo-class itself) as an argument.

http://dev.w3.org/csswg/selectors3/#simple-selectors-dfn

A simple selector is either a type selector, universal selector, attribute selector, class selector, ID selector, or pseudo-class.

CSS chaining adjacent sibling with :checked not working

I think you have the same issue as described here:

Webkit bug with `:hover` and multiple adjacent-sibling selectors

As a workaround just add :checked ~ p {} (intentionally empty) and it works:

http://jsbin.com/abeniy/7/edit

Is there a previous sibling selector?

No, there is no "previous sibling" selector.

On a related note, ~ is for general successor sibling (meaning the element comes after this one, but not necessarily immediately after) and is a CSS3 selector. + is for next sibling and is CSS2.1.

See Adjacent sibling combinator from Selectors Level 3 and 5.7 Adjacent sibling selectors from Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification.

the difference between subsequent sibling combinator (~ )and child selector () in css

General sibling means the element is after another element, where the child selector targets elements that are directly inside of certain elements.

Siblings:

HTML:

<div class="brother"></div>
<div class="sister"></div>

CSS:

.brother ~ .sister {
/* This styles .sister elements that follow .brother elements */
}

Children:

HTML

<div class="parent">
<div class="child">
<div class="child"></div>
</div>
</div>

CSS:

.parent > .child{
/* This styles .child element that is the direct child of the parent element;
It will not style the .child element that is the child of .child */
}

How to combine multiple selectors with Adjacent sibling selector?

The only thing you can do is to remove the extraneous { visibility: visible; } and replace it with a comma:

.new-comment-input:focus + .new-comment-button, 
.new-comment-button:focus,
.new-comment-input:active + .new-comment-button,
.new-comment-button:active {
visibility: visible;
}

You have four selectors split into two rulesets, but you can't combine any of them so you have to simply merge their two groups into one. :focus:active means both of those states at the same time (AND), not either one of them (OR), so you can't combine them that way.



Related Topics



Leave a reply



Submit