Apakah ada pemilih CSS berdasarkan awalan kelas?

175

Saya ingin menerapkan aturan CSS ke elemen apa pun yang salah satu kelasnya cocok dengan awalan yang ditentukan.

Misalnya saya ingin aturan yang akan berlaku untuk div yang memiliki kelas yang dimulai dengan status-(A dan C, tetapi tidak B dalam cuplikan berikut):

<div id='A' class='foo-class status-important bar-class'></div>
<div id='B' class='foo-class bar-class'></div>
<div id='C' class='foo-class status-low-priority bar-class'></div>

Semacam kombinasi dari:
div[class|=status]dandiv[class~=status-]

Apakah bisa dilakukan di bawah CSS 2.1? Apakah bisa dilakukan di bawah spesifikasi CSS?

Catatan: Saya tahu saya bisa menggunakan jQuery untuk meniru itu.

THX-1138
sumber

Jawaban:

373

Ini tidak bisa dilakukan dengan CSS2.1, tapi mungkin dengan atribut CSS3 pemilih substring-matching (yang sedang didukung di IE7 +):

div[class^="status-"], div[class*=" status-"]

Perhatikan karakter spasi di pemilih atribut kedua. Ini mengambil divelemen yang classatributnya memenuhi salah satu dari kondisi ini:

  • [class^="status-"] - dimulai dengan "status-"

  • [class*=" status-"]- berisi substring "status-" yang terjadi langsung setelah karakter spasi. Nama kelas dipisahkan oleh spasi per spesifikasi HTML , karenanya karakter spasi yang signifikan. Ini memeriksa setiap kelas lain setelah yang pertama jika beberapa kelas ditentukan, dan menambahkan bonus memeriksa kelas pertama jika nilai atributnya adalah ruang-empuk (yang dapat terjadi dengan beberapa aplikasi yang menampilkan classatribut secara dinamis).

Secara alami, ini juga berfungsi di jQuery, seperti yang ditunjukkan di sini .

Alasan Anda perlu menggabungkan dua penyeleksi atribut seperti dijelaskan di atas adalah karena pemilih atribut seperti [class*="status-"]akan cocok dengan elemen berikut, yang mungkin tidak diinginkan:

<div id='D' class='foo-class foo-status-bar bar-class'></div>

Jika Anda dapat memastikan bahwa skenario seperti itu tidak akan pernah terjadi, maka Anda bebas menggunakan pemilih semacam itu demi kesederhanaan. Namun, kombinasi di atas jauh lebih kuat.

Jika Anda memiliki kendali atas sumber HTML atau aplikasi yang menghasilkan markup, mungkin lebih mudah untuk membuat status-awalan kelasnya sendiri sebagaistatus gantinya seperti yang disarankan Gumbo .

BoltClock
sumber
1
Jika karena alasan aneh apa pun Anda memiliki kelas yang dipanggil status-dan Anda tidak ingin mencocokkannya, pemilih menjadi lebih rumit: div[class^="status-"]:not(.status-), div[class*=" status-"]:not(.status-)Plus Anda kehilangan dukungan IE7 / IE8. Untungnya, jika markup Anda waras, Anda tidak perlu mengecualikan kelas seperti itu.
BoltClock
Apa yang salah dengan ini: [class*=" anim-overlay-"] a:hover:after{...}. Kelas CSS saya adalah anim-overlay-1, anim-overlay-2.....anim-overlay-8
MB Parvez Rony
2
@ WebDevRon: Anda lupa bagian ^ =. Jika atribut kelas Anda dijamin untuk memulai dengan anim-overlay- maka Anda mungkin tidak memerlukan bagian * =.
BoltClock
Terima kasih. Hal lain, bisakah saya menggunakan ini .anim-overlay-*{...}?
MB Parvez Rony
2
@Daniel Compton: Terima kasih atas hasil editnya. Saya telah diingatkan di belakang tentang bagaimana kata-kata seperti itu dapat merendahkan seseorang yang sesuatu mungkin tidak begitu jelas. Saya tahu beberapa orang benar-benar tidak menghargai perubahan semacam ini, jadi saya merespons sebagian besar untuk memberi tahu Anda bahwa saya setuju.
BoltClock
14

Penyeleksi Atribut CSS akan memungkinkan Anda untuk memeriksa atribut untuk string. (dalam hal ini - nama kelas)

https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors

(Sepertinya itu sebenarnya pada status 'rekomendasi' untuk 2.1 dan 3)


Berikut ini adalah garis besar bagaimana saya * pikir itu bekerja:

  • [ ]: adalah wadah untuk penyeleksi kompleks jika Anda ...
  • class: 'class' adalah atribut yang Anda lihat dalam kasus ini.
  • * : modifier (jika ada): dalam hal ini - "wildcard" menunjukkan Anda sedang mencari kecocokan APAPUN.
  • test- : nilai (dengan asumsi ada satu) dari atribut - yang berisi string "test-" (yang bisa berupa apa saja)

Jadi, misalnya:

[class*='test-'] {
  color: red;
}

Anda bisa lebih spesifik jika Anda memiliki alasan yang bagus, dengan elemennya juga

ul[class*='test-'] > li { ... }

Saya sudah mencoba menemukan case edge, tapi saya melihat tidak perlu menggunakan kombinasi ^dan *- karena * mendapatkan semuanya ...

contoh: http://codepen.io/sheriffderek/pen/MaaBwp

http://caniuse.com/#feat=css-sel2

Segala sesuatu di atas IE6 akan dengan senang hati taat. :)

perhatikan bahwa:

[class] { ... }

Akan memilih apa pun dengan kelas ...

sheriffderek
sumber
[class*='test-']akan mencocokkan elemen seperti <div class='foo-test-bar'>. Itulah satu sisi kasus yang membutuhkan menggabungkan ^ dan * seperti yang dijelaskan dalam jawaban saya. Dan IE6 tidak mendukung pemilih atribut.
BoltClock
@BoltClock - terima kasih telah menjelaskan! - Saya tidak mendukung <EI9 - dan saya tidak akan pernah menulis kelas yang akan saling menginjak - jadi bagi saya ini berhasil. :)
sheriffderek
6

Ini tidak mungkin dengan penyeleksi CSS. Tetapi Anda bisa menggunakan dua kelas alih-alih satu, mis. Status dan penting alih-alih status penting .

Gumbo
sumber
14
Ide yang baik tentang memisahkan ke dalam kelas sendiri, tetapi adalah mungkin dengan CSS. Lihat jawaban saya.
BoltClock
2

Anda tidak dapat melakukan ini, tidak. Ada satu pemilih atribut yang sama persis atau parsial hingga tanda -, tetapi tidak berfungsi di sini karena Anda memiliki banyak atribut. Jika nama kelas yang Anda cari selalu menjadi yang pertama, Anda bisa melakukan ini:

<html>
<head>
<title>Test Page</title>
<style type="text/css">
div[class|=status] { background-color:red; }
</style>
</head>
<body>
<div id='A' class='status-important bar-class'>A</div>
<div id='B' class='bar-class'>B</div>
<div id='C' class='status-low-priority bar-class'>C</div>

</body>
</html>

Perhatikan bahwa ini hanya untuk menunjukkan pemilih atribut CSS mana yang paling dekat, tidak disarankan untuk menganggap nama kelas akan selalu ada di depan karena javascript dapat memanipulasi atribut.

SBUJOLD
sumber
2
ya, pikirkan itu. Ini mungkin menjadi masalah ketika jQuery masuk ke dalam gambar, karena mungkin memasukkan kelas di depan.
THX-1138
Ya saya akan mengedit posting saya untuk membuatnya jelas bukan cara yang disarankan untuk melakukannya. Jika Anda memiliki kontrol atas nama kelas maka saran Gumbo pasti akan menjadi cara untuk pergi (ditambah penyeleksi atribut pada browser IE yang lebih lama tidak didukung).
SBUJOLD