Есть ли такая вещь, как CSS-селектор "все включено"? - PullRequest
28 голосов
/ 08 декабря 2011

Мой HTML:

<p>Doggies</p>
<p class="green_guys">Froggies</p>
<p>Cupcakes</p>
<p>Piggies</p>

Селектор братьев и сестер по системе "все включено" (как мне хотелось бы), когда он используется для выбора братьев и сестер green_guys, будет выбирать собачку кексы и поросята.

Другие селекторы:

Селектор + (a.k.a. соседний селектор брата ) будет выбирать только кексы:

.green_guys + p {
    /* selects the <p> element that immediately follows .green_guys */
}

Селектор ~ (a.k.a. общий селектор братьев и сестер ) будет выбирать только кексы и поросята:

.green_guys ~ p {
    /* selects all <p> elements that follow .green_guys */
}

Ответы [ 4 ]

17 голосов
/ 08 декабря 2011

Нет комбинатора, который смотрит назад или вокруг, есть только соседние и общие комбинаторы, которые смотрят вперед.

Лучшее, что вы можете сделать, - это определить способ ограничить выбор только этими p элементами с одним и тем же родителем, а затем выбрать p дочерних элементов, которые :not(.green_guys). Например, если родительский элемент имеет идентификатор #parent, вы можете использовать этот селектор:

#parent > p:not(.green_guys) {
    /* selects all <p> children of #parent that are not .green_guys */
}

Однако приведенное выше все равно будет соответствовать вашим p элементам, даже если нет из них имеет класс. В настоящее время невозможно выбрать братьев и сестер элемента, только если существует существование указанного элемента (что является целью комбинатора родного брата - установить связь между двумя элементами брата) .


Селекторы 4 :has(), мы надеемся, исправят это без необходимости использования комбинатора предшествующего брата, что приведет к следующему решению:

p:has(~ .green_guys), .green_guys ~ p {
    /* selects all <p> elements that are siblings of .green_guys */
}

Это не будет ничего совпадать, если ни один из дочерних элементов родительского элемента не имеет класса.

2 голосов
/ 08 декабря 2011

Не то, что я знаю.Также нет селектора siblings.

Это может сработать, хотя:

#parent_of_green_guys > p:not(.green_guys) {
  foo: bar;
}

Или, если вы не ищете p с атрибутами class:

#parent_of_green_guys > p:not([class]) {
  foo: bar;
}
0 голосов
/ 03 июня 2019

Я действительно нашел 3 способа сделать это:

Решение 1

.parent > p:not(.green_guys) {
  text-decoration: line-through; /* or whatever you like */
}

Демо: https://jsbin.com/cafipun/edit?html,css,output

ПРОФИ: быстро ипросто.

CONS: вам нужно знать родительский селектор (чтобы это не было сверхпортативным решением).

Solution 2

p ~ p:not(.green_guys),
p:first-child:not(.green_guys) {
  text-decoration: line-through; /* or whatever you like */
}

Демонстрация: https://jsbin.com/seripuditu/edit?html,css,output

PROS: нет необходимости знать родительский селектор (это может быть очень полезно для использования в общих случаях).

CONS: рискует быть слишком универсальным(будьте осторожны, например, если у вас есть другие p вокруг вашего HTML!).

Решение 3

Небольшой вариант Решение 2 (чтобы избежать CONS ).В этом случае вы указываете селектор брата, чтобы получить более конкретный контекст.

p.siblings ~ p:not(.green_guys),
p.siblings:first-child:not(.green_guys) {
  text-decoration: line-through; /* or whatever you like */
}

Демонстрация: https://jsbin.com/hakasek/edit?html,css,output

PROS: это переносимое решение, нет необходимости знатьродительский селектор (он может быть очень хорош в общих случаях), и не нужно беспокоиться о конфликте с другими элементами.

CONS: все братья и сестры должны быть четко определены (например, с классом или атрибутом).

0 голосов
/ 19 июня 2015

Мой сценарий был немного другим, но я хотел выбрать братьев и сестер элемента ввода для отображения одного, когда он был активен, и другого, если он оставлен недействительным.

Мой HTML был таким, и я не смогвыделите недопустимый текст.

<input name="importantAnswer">
<div class="help-text"></div>
<div class="invalid-text"></div>

Мне удалось обойти его, встроив братьев и сестер в соседний и используя для этого дочерние селекторы.

<input name="importantAnswer">
<div class="messages">
   <div class="help-text"></div>
   <div class="invalid-text"></div>
</div>


.help-text, .invalid-text {
   visibility:hidden;
}

.input:active +.messages > .help-text {
   visibility:visible;
}

.input.invalid:visited +.messages > .invalid-text {
   visibility:visible;
}

И это сработало.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...