CSS-селектор "(A або B) і C"?


176

Це має бути простим, але у мене виникають проблеми з пошуком пошукових термінів.
Скажімо, у мене таке:

<div class="a c">Foo</div>
<div class="b c">Bar</div>

Як у CSS я можу створити селектор, який відповідає тому, що відповідає "(.a чи .b) та .c"?

Я знаю, що міг би це зробити:

.a.c,.b.c {
  /* CSS stuff */
}

Але, якщо припустити, що мені доведеться багато робити цю логіку, з різними логічними комбінаціями, чи кращий синтаксис?


Будьте обережні, якщо вам доведеться підтримувати Internet Explorer 6, оскільки він просто ігнорує більше одного імені класу у селекторі CSS.
fforw

24
На щастя, для цього проекту я можу сказати користувачам IE6, щоб вони самі пройшли оновлення.
Джош

12
Для наочності я намагаюся завжди ставити новий рядок після коми або, принаймні, пробілу.
ANeves

2
@ANeves +1 для нового рядка. На мій погляд, це найкращий підхід, особливо при використанні управління джерелами.
Curt

Відповіді:


149

чи кращий синтаксис?

Ні. orОператор CSS ( ,) не дозволяє групувати. Це по суті логічний оператор з найнижчим пріоритетом у селекторах, тому ви повинні використовувати .a.c,.b.c.


25

Ще немає, але є експериментальна :matches()псевдокласова функція, яка робить саме це:

:matches(.a .b) .c {
  /* stuff goes here */
}

Більше інформації про нього можна знайти тут і тут . В даний час більшість браузерів підтримують його початкову версію :any(), яка працює так само, але буде замінена на :matches(). Треба просто почекати ще трохи, перш ніж користуватися цим скрізь (я точно буду).


Нерозумно звинувачувати IE у тому, що вони не реалізували те, про що вони просто ніколи не думали, і не було в жодному проекті. :-moz-any()і :-webkit-any()з'явився задовго до того, як Mozilla запропонував його для селекторів 4 (що призводить до його теперішнього втілення як :matches()).
BoltClock

1
Не менш розумно розраховувати, що будь-який постачальник реалізує функцію від нестабільної чернетки незалежно від того, як довго проект був доступний (це враховує той факт, що селектори 4 залишаються нестабільними і значною мірою не виконуються більше трьох років після його FPWD) .
BoltClock

@BoltClock, вони впродовж цілого десятиліття звинувачували IE6 у тому, що не існувало 2001 року. Люди просто хочуть когось звинуватити.
GetFree

Одне слово експериментальних полягає в тому, що ви не хочете починати покладатися на них, якщо це не офіційно здійснено. Хоча це може здатися чудовим рішенням - можливість його зникнення, що особисто заважає мені реалізовувати це у своїх проектах. Навіть відслідковувати один експериментальний псевдоклас не дає мені почуватися в безпеці. Швидше за все, він буде використовуватися в більш ніж одному місці в проекті, і якщо у вас є більше одного, де ви його використовуєте - вам потрібно якось все це відстежувати. Ви, безумовно, можете мати резервні запаси і все одно витягувати це, але це не звучить чисто
Олексій Шевельов

я єдиний, хто отримує Uncaught DOMException: Failed to execute 'querySelector' on 'Document': ':any(.a .b)' is not a valid selector.помилку? 🤔
томас

12

Якщо у вас є це:

<div class="a x">Foo</div>
<div class="b x">Bar</div>
<div class="c x">Baz</div>

І ви хочете лише вибрати елементи, які містять .xі ( .aабо .b), ви можете написати:

.x:not(.c) { ... }

але це зручно лише тоді, коли у вас є три "підкласи" і ви хочете вибрати два з них.

Вибір лише одного підкласу (наприклад .a):.a.x

Вибір двох підкласів (наприклад, .aта .b):.x:not(.c)

Вибір усіх трьох підкласів: .x


6
Будь-який логічний пункт форми a or b or c or dтакий самий, як not(not(a) and not(b) and not(c) and not(d))"або" - це фактично лише функція зручності. Теоретично слід обійтися без цього у всіх випадках. У випадку з ОП (.a or .b) and .c->:not(:not(.a):not(.b)).c
Макс Мерфі

2
@MaxMurphy Ви протестували це?
Šime Vidas

4
Станом на п'яту годину цього ранку, так! У мене є js, який розгалужує логіку першого порядку, із селекторами на листках, що дає такі результати, як :not(:not([data-status="ACT"]):not([data-status="ISS"]):not([data-status="COR"]))[data-month="08"]. Код недостатньо чистий для ознайомлення з громадськістю, але в іншому випадку я його опублікую. Я перевірив хром, сафарі та телефон низького класу Android.
Макс Мерфі

2
@MaxMurphy У вас є чудовий момент, але я думаю, ви посилалися на досить мучене визначення "функції зручності". Все, що може зробити цифровий комп’ютер, можна розкласти на ворота NAND, але я не називаю решту програмної інженерії "купою функцій зручності". Різниці ступенів швидко стають фактичними відмінностями роду, коли конструкції можна комбінувати.
Сара Г

1
@MaxMurphy Мені важко було зрозуміти, що ти просто жартуєш. :( Негативний псевдоклас CSS,: not (X) - це функціональна позначка, яка бере аргумент простий селектор X. Він відповідає елементу, який не представлений аргументом. X не повинен містити іншого селектора заперечення . (Від Mozilla docs , наголос мій)
törzsmókus

5

Ні. Стандартний CSS не забезпечує те, що ви шукаєте.

Однак, можливо, ви захочете зазирнути на МЕНШЕ і СТРАШНЕ .

Це два проекти, які мають на меті розширити синтаксис CSS за замовчуванням шляхом введення додаткових функцій, включаючи змінні, вкладені правила та інші вдосконалення.

Вони дозволяють написати набагато більш структурований CSS-код, і будь-який з них майже напевно вирішить ваш конкретний випадок використання.

Звичайно, жоден із браузерів не підтримує розширений синтаксис (тим більше, що кожен з двох проектів має різний синтаксис та особливості), але те, що вони роблять, - це "компілятор", який перетворює ваш менший або SASS-код у стандартний CSS, який ви можете потім розміщення на вашому сайті.


У цей момент я можу також просто використовувати PHP-друк "Тип вмісту: текст / css"
Джош
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.