CSS3, объединяющий селекторы с ИЛИ вместо И

Учитывая этот селектор:

body[class*="page-node-add-"][class~="page-node-edit"] {background:red;}

Он будет соответствовать телу, имеющему класс, содержащий подстроку page-node-add- И класс, который точно соответствует page-node-edit.

Я хотел бы сказать, что соответствует первому ИЛИ второму (но не обоим). Является ли это возможным?

Проблема с использованием запятой:

Если у меня есть длинный селектор, например:

body[class*="page-node-add-"] form.node-form > .field-type-field-collection > table > thead tr th,
body[class~="page-node-edit"] form.node-form > .field-type-field-collection > table > thead tr th
{...}

Это боль, я думал, что CSS3 исправит это, я представлял себе что-то вроде:

body([class*="page-node-add-"]):or([class~="page-node-edit"]) {background:red;}

Спасибо


person Dominic    schedule 25.05.2012    source источник
comment
Серьезно, вам нужно поработать над своим стилем написания CSS, ваши селекторы выглядят (и, скорее всего, работают) ужасно.   -  person Christoph    schedule 25.05.2012
comment
Спасибо, но я очень хорошо умею писать css, и обычно я бы так не делал. У меня есть задача перейти к 1000 строкам разметки CMS, созданной в области администрирования (так что совместимость с браузером не проблема, и попробуйте раскрасить код, свернуть элемент и т. д. с помощью css и js, чтобы это имело смысл для среднего редактора веб-сайта.   -  person Dominic    schedule 25.05.2012


Ответы (3)


Вам нужно будет разделить их с помощью запятой:

body[class*="page-node-add-"], body[class~="page-node-edit"] {background:red;}

Проблема с использованием запятой:

... заключается в том, что вы не можете сделать это иначе, чем через запятую. Возможно, это можно было бы исправить с помощью Selectors 3, но, к сожалению, спецификация говорит об обратном. Это будет исправлено только с помощью селекторов 4 либо потому, что это не было предлагалось до недавнего времени или было предложено, но не попало в категорию 3.

На уровне 4 селекторов вы сможете сделать что-то вроде этого:

body:matches([class*="page-node-add-"], [class~="page-node-edit"]) form.node-form > .field-type-field-collection > table > thead tr th
{...}

В настоящее время это реализуется под первоначально предложенным названием :any() с префиксами :-moz-any() и :-webkit-any(). Но использование :any() в общедоступном CSS бессмысленно, учитывая, что

  1. его поддерживают только Gecko и WebKit; и

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

    body:-moz-any([class*="page-node-add-"], [class~="page-node-edit"]) form.node-form > .field-type-field-collection > table > thead tr th
    {...}
    body:-webkit-any([class*="page-node-add-"], [class~="page-node-edit"]) form.node-form > .field-type-field-collection > table > thead tr th
    {...}
    

Другими словами, пока реализации не обновятся до стандартизированного :matches(), нет другого жизнеспособного решения (кроме использования препроцессора для генерации повторяющихся селекторов).

person BoltClock    schedule 25.05.2012
comment
Аналогичный ответ (который мне нравится немного больше, поскольку он ссылается на другой предыдущий ответ на этот вопрос): /a> (также на этой странице). - person Destiny Architect; 18.06.2015
comment
@Destiny Architect: на самом деле я предпочитаю этот ответ предыдущему, поскольку он подчеркивает контрпродуктивность использования префиксов в производстве. Но я, вероятно, все равно должен пометить вопросы как дубликаты. Вопрос только в том, кого из них следует обмануть. - person BoltClock; 18.06.2015

Я нашел ответ здесь:

Сокращение CSS для определения нескольких классов

Mozilla и webkit имеют -moz-any или -webkit-any, хотя в спецификации CSS4 есть :matches. Удивлен, что об этом не подумали в CSS3, так как это значительно уменьшило бы количество повторяющегося кода без необходимости использовать SASS или LESS или что-то еще.

person Dominic    schedule 25.05.2012
comment
Ага, но из-за префиксов приходится дублировать правила. Применяя этот другой мой ответ к тому, что у вас есть, вы можете видеть, что это на самом деле не помогает... - person BoltClock; 25.05.2012
comment
Аналогичный ответ: stackoverflow.com/a/10753216/2255628 (также на этой странице). 'соответствует' хорошему описанию на css-tricks.com/almanac/selectors/m/matches но в настоящее время отсутствует в caniuse.com/#search=matches как dom.spec.whatwg.org/#dom-element-matchesselectors — это не то же самое. - person Destiny Architect; 18.06.2015

Итак, вы действительно хотите XOR, когда я прочитаю ваш вопрос. Вы можете добиться этого, используя селектор :not и сказав «класс один, а не другой» и наоборот.

div.one:not(.two), div.two:not(.one) {
    background:red;
}

Вот скрипт: http://jsfiddle.net/XfgxK/3/

person Fabian Barney    schedule 25.05.2012
comment
Это именно то, что он хочет, насколько я правильно понял вопрос. - person Fabian Barney; 25.05.2012
comment
Как только вы замените эти классы заданными атрибутами или полными сложными селекторами, это станет безумно длинным. Опять же, для этого пока нет жизнеспособного обходного пути. - person BoltClock; 25.05.2012
comment
@BoltClock Нет, OP запрашивает xor. - person Christoph; 25.05.2012
comment
Ну, это довольно запутанно. ОП нашел еще один мой ответ, в котором говорится то же самое, и он называет это ответом, но после второго прочтения кажется, что он запрашивает XOR, а не OR. - person BoltClock; 25.05.2012
comment
Кроме того, если у вас нет других классов для фильтрации, вам не обязательно говорить div.one:not(.two), вы можете просто сказать div:not(.two). См. jsfiddle.net/BoltClock/XfgxK/4 и stackoverflow.com/questions/10711730/ - person BoltClock; 25.05.2012
comment
Да, но вы должны знать, что это другой сценарий, поскольку теперь вы сопоставляете бывшие несвязанные элементы div. jsfiddle.net/TyYJ5/1 Это не так при использовании прежнего кода: jsfiddle.net/XfgxK/5 - person Fabian Barney; 25.05.2012