Pemilih CSS “(A atau B) dan C”?

176

Ini seharusnya sederhana, tetapi saya kesulitan menemukan istilah pencarian untuk itu.
Katakanlah saya punya ini:

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

Di CSS, bagaimana saya bisa membuat pemilih yang cocok dengan sesuatu yang cocok dengan "(.a atau .b) dan .c"?

Saya tahu saya bisa melakukan ini:

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

Tetapi, dengan anggapan saya harus banyak melakukan jenis logika ini, dengan berbagai kombinasi logis, adakah sintaks yang lebih baik?

Josh
sumber
Hati-hati jika Anda harus mendukung Internet Explorer 6, karena itu akan mengabaikan lebih dari satu nama kelas dalam pemilih CSS.
fforw
24
Untungnya, untuk proyek ini, saya dapat memberi tahu pengguna IE6 untuk melakukan peningkatan sendiri.
Josh
12
Demi kejelasan, saya mencoba untuk selalu meletakkan baris baru setelah koma, atau setidaknya spasi.
ANeves
2
@Aneves +1 untuk baris baru. Ini adalah apporach terbaik menurut saya, terutama saat menggunakan kontrol sumber.
Curt

Jawaban:

149

apakah ada sintaks yang lebih baik?

Tidak. Operator CSS or( ,) tidak mengizinkan pengelompokan. Ini pada dasarnya operator logis dengan presedensi terendah di penyeleksi, jadi Anda harus menggunakannya .a.c,.b.c.

Matt Ball
sumber
25

Belum, tetapi ada fungsi :matches()pseudo-class eksperimental yang melakukan hal itu:

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

Anda dapat menemukan lebih banyak info di sini dan di sini . Saat ini, sebagian besar browser mendukung versi awalnya :any(), yang berfungsi dengan cara yang sama, tetapi akan diganti oleh :matches(). Kami hanya harus menunggu lebih lama sebelum menggunakan ini di mana-mana (saya pasti akan).

Pembuat kode logam
sumber
Tidak masuk akal untuk menyalahkan IE karena tidak mengimplementasikan sesuatu yang mereka tidak pernah pikirkan dan tidak ada dalam konsep awal. :-moz-any()dan :-webkit-any()muncul jauh sebelum Mozilla menyarankannya untuk Selectors 4 (yang mengarah ke inkarnasi saat ini sebagai :matches()).
BoltClock
1
Sama tidak masuk akal untuk mengharapkan vendor untuk mengimplementasikan fitur dari draft yang tidak stabil terlepas dari berapa lama draft telah tersedia (ini untuk menjelaskan fakta bahwa Selectors 4 tetap tidak stabil dan sebagian besar tidak diterapkan lebih dari tiga tahun setelah FPWD-nya) .
BoltClock
@BoltClock, mereka menyalahkan IE6 selama satu dekade penuh untuk hal-hal yang tidak ada pada tahun 2001. Orang-orang hanya ingin menyalahkan seseorang.
GetFree
Satu kata untuk yang eksperimental adalah Anda tidak ingin mulai mengandalkan mereka kecuali jika itu diterapkan secara resmi. Meskipun itu bisa tampak seperti solusi hebat - kemungkinan menghilangnya apa yang secara pribadi mencegah saya untuk mengimplementasikannya dalam proyek-proyek saya. Bahkan untuk melacak satu kelas pseudo eksperimental tidak membuat saya merasa aman. Kemungkinan besar itu akan digunakan di lebih dari satu tempat di proyek dan dalam kasus dan jika Anda memiliki lebih dari satu tempat Anda menggunakannya - Anda entah bagaimana harus melacak semuanya. Anda pasti dapat memiliki fallback dan masih berhasil tetapi itu tidak terdengar bersih
Alexey Shevelyov
Apakah saya satu-satunya yang mendapatkan Uncaught DOMException: Failed to execute 'querySelector' on 'Document': ':any(.a .b)' is not a valid selector.kesalahan? 🤔
thomas
12

Jika Anda memiliki ini:

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

Dan Anda hanya ingin memilih elemen yang memiliki .xdan ( .aatau .b), Anda dapat menulis:

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

tapi itu nyaman hanya ketika Anda memiliki tiga "sub-kelas" dan Anda ingin memilih dua dari mereka.

Memilih hanya satu sub-kelas (misalnya .a):.a.x

Memilih dua sub-kelas (misalnya .adan .b):.x:not(.c)

Memilih ketiga sub-kelas: .x

Šime Vidas
sumber
6
Setiap klausa logis dari formulir a or b or c or dadalah sama dengan not(not(a) and not(b) and not(c) and not(d))begitu 'atau' sebenarnya hanya fungsi kenyamanan. Secara teori seharusnya bisa bertahan tanpa itu dalam semua kasus. Dalam kasus OP (.a or .b) and .c->:not(:not(.a):not(.b)).c
Max Murphy
2
@ MaxMurphy Sudahkah Anda menguji ini?
Šime Vidas
4
Sampai jam lima pagi ini, ya! Saya punya js yang memuntahkan logika urutan pertama, dengan pemilih di daun, memberikan hasil seperti :not(:not([data-status="ACT"]):not([data-status="ISS"]):not([data-status="COR"]))[data-month="08"]. Kode tidak cukup bersih untuk dibaca publik, kalau tidak, saya akan mempostingnya. Saya menguji pada chrome, safari dan ponsel Android low end.
Max Murphy
2
@ MaxMurphy Anda punya poin bagus, tapi saya pikir Anda telah menggunakan definisi yang agak disiksa "fungsi kenyamanan." Apa pun yang dapat dilakukan oleh komputer digital dapat diuraikan menjadi gerbang NAND, tetapi saya tidak akan menyebut rekayasa perangkat lunak lainnya sebagai "sekelompok fungsi kenyamanan." Perbedaan derajat dengan cepat menjadi perbedaan de facto jenis ketika konstruksi dapat dikombinasikan.
Sarah G
1
@ Maxmurphy Saya mengalami kesulitan mencari tahu bahwa Anda hanya bercanda. :( Negasi CSS pseudo-class,: not (X), adalah notasi fungsional yang mengambil pemilih X sederhana sebagai argumen. Itu cocok dengan elemen yang tidak diwakili oleh argumen. X tidak boleh mengandung pemilih negasi lain . (Dari Mozilla docs ,
stress
5

Tidak. Standar CSS tidak menyediakan hal-hal yang Anda cari.

Namun, Anda mungkin ingin melihat KURANG dan SASS .

Ini adalah dua proyek yang bertujuan untuk memperluas sintaks CSS default dengan memperkenalkan fitur tambahan, termasuk variabel, aturan bersarang, dan perangkat tambahan lainnya.

Mereka memungkinkan Anda untuk menulis kode CSS lebih terstruktur, dan salah satu dari mereka hampir pasti akan memecahkan kasus penggunaan khusus Anda.

Tentu saja, tidak ada peramban yang mendukung sintaks yang diperluas (terutama karena kedua proyek tersebut masing-masing memiliki sintaks dan fitur yang berbeda), tetapi yang mereka lakukan adalah menyediakan "kompiler" yang mengubah kode KURANG atau SASS Anda menjadi CSS standar, yang kemudian dapat Anda peroleh. gunakan di situs Anda.

Spudley
sumber
Pada titik itu, saya mungkin juga hanya menggunakan pencetakan PHP "Tipe konten: teks / css"
Josh