Karakter mana yang valid dalam nama / penyeleksi kelas CSS?

1203

Karakter / simbol apa yang diperbolehkan dalam pemilih kelas CSS ?
Saya tahu bahwa karakter berikut tidak valid , tetapi karakter apa yang valid ?

~ ! @ $ % ^ & * ( ) + = , . / ' ; : " ? > < [ ] \ { } | ` #
Darryl Hein
sumber
5
Pertanyaan terkait: stackoverflow.com/questions/2812072/…
BalusC
32
bagaimana dengan karakter utf8? Seperti saya dapat mengetik bahasa Yunani
GorillaApe
9
Karakter khusus dapat digunakan dalam nama kelas dengan melarikan diri mereka - dalam file CSS Anda, Anda dapat menentukan .hello/worldkelas dengan melarikan diri backslash: .hello\2fworld, hello\2f worldatauhello\/world
wyqydsyq
1
Pertanyaan terkait lainnya, bukan tentang "sintaks nama", tetapi tentang "sintaks atribut kelas" saat mengekspresikan beberapa nama .
Peter Krauss
2
Anda juga dapat menggunakan emoji. npmjs.com/package/postcss-modules-emoji-classname
Kevin Suttle

Jawaban:

1024

Anda dapat memeriksa langsung di tata bahasa CSS .

Pada dasarnya 1 , nama harus dimulai dengan garis bawah ( _), tanda hubung ( -), atau huruf ( a- z), diikuti oleh sejumlah tanda hubung, garis bawah, huruf, atau angka. Ada tangkapan: jika karakter pertama adalah tanda hubung, karakter kedua harus 2 menjadi huruf atau garis bawah, dan nama harus minimal 2 karakter.

-?[_a-zA-Z]+[_a-zA-Z0-9-]*

Singkatnya, aturan sebelumnya diterjemahkan menjadi yang berikut, diekstraksi dari spesifikasi W3C. :

Dalam CSS, pengidentifikasi (termasuk nama elemen, kelas, dan ID dalam pemilih) hanya dapat berisi karakter [a-z0-9] dan ISO 10646 karakter U + 00A1 dan lebih tinggi, ditambah dengan tanda hubung (-) dan garis bawah (_) ; mereka tidak bisa mulai dengan angka, atau tanda hubung diikuti oleh angka. Pengidentifikasi juga dapat berisi karakter yang lolos dan karakter ISO 10646 apa pun sebagai kode numerik (lihat item berikutnya). Misalnya, pengidentifikasi "B&W?" dapat ditulis sebagai "B \ & W \?" atau "B \ 26 W \ 3F".

Pengidentifikasi yang dimulai dengan tanda hubung atau garis bawah biasanya disediakan untuk ekstensi khusus browser, seperti pada -moz-opacity.

1 Semuanya dibuat sedikit lebih rumit dengan masuknya karakter unicode yang lolos (yang tidak ada yang benar-benar menggunakan).

2 Perhatikan bahwa, menurut tata bahasa yang saya tautkan, aturan yang dimulai dengan DUA tanda hubung, misalnya --indent1, tidak valid. Namun, saya cukup yakin saya sudah melihat ini dalam praktek.

Triptych
sumber
57
NB: W3C mengatakan bahwa penggunaan '-' atau '_' yang memimpin harus dicadangkan untuk ekstensi CSS khusus vendor (misalnya, -moz * kelas yang diterapkan oleh browser Mozilla).
mipadi
3
\ -Escapes biasanya digunakan, tetapi umumnya sebagian besar untuk keperluan peretasan CSS, mengisolasi browser yang tidak mendukungnya.
bobince
5
Untuk memperbarui komentar @Pim Jager lebih dari dua tahun kemudian, menurut w3counter.com/globalstats.php IE6 sekarang digunakan oleh kurang dari 3% pengguna, di belakang IE9 di 4%, IE7 di 9%, IE8 di 22%. Semua versi Firefox memiliki 28%, semua versi Chrome memiliki 17%.
Daniel Earwicker
3
Saya tahu ini adalah jawaban lama, tetapi CSS (setidaknya 2+) memungkinkan setiap karakter {Non-ASCII} dalam pengidentifikasi.
user2864740
11
In CSS, identifiers (including element names, classes, and IDs in selectors) can contain only the characters [a-zA-Z0-9] and ISO 10646 characters U+00A0 and higher, plus the hyphen (-) and the underscore (_); they cannot start with a digit, two hyphens, or a hyphen followed by a digit. Identifiers can also contain escaped characters and any ISO 10646 character as a numeric code (see next item). For instance, the identifier "B&W?" may be written as "B\&W\?" or "B\26 W\3F". Jadi - --indent1tidak valid dan perlu untuk melarikan diri sebagai \--indent1( --kelas istirahat di iOS, misalnya)
eithed
177

Yang mengejutkan saya, sebagian besar jawaban di sini salah. Ternyata itu:

Karakter apa pun kecuali NUL diizinkan dalam nama kelas CSS di CSS. (Jika CSS berisi NUL (lolos atau tidak), hasilnya tidak ditentukan. [ CSS-karakter ])

Tautan jawaban Mathias Bynens ke penjelasan dan demo menunjukkan cara menggunakan nama-nama ini. Ditulis dalam kode CSS, nama kelas mungkin perlu diloloskan , tetapi itu tidak mengubah nama kelas. Misalnya, representasi yang tidak perlu diloloskan secara berlebihan akan terlihat berbeda dari representasi lain dari nama itu, tetapi itu masih merujuk pada nama kelas yang sama.

Sebagian besar bahasa lain (pemrograman) tidak memiliki konsep melarikan diri dari nama variabel ("pengidentifikasi"), sehingga semua representasi dari suatu variabel harus terlihat sama. Ini tidak terjadi di CSS.

Perhatikan bahwa dalam HTML tidak ada cara untuk memasukkan karakter spasi (spasi, tab, umpan baris, umpan form, dan carriage return) dalam atribut nama kelas , karena mereka sudah memisahkan kelas dari satu sama lain.

Jadi, jika Anda perlu mengubah string acak menjadi nama kelas CSS: jaga NUL dan spasi, dan keluar (sesuai untuk CSS atau HTML). Selesai

Robert Siemer
sumber
7
Baris pertama jawaban Anda harus "sebagian besar jawaban di sini sudah usang / hanya berlaku untuk CSS2".
Salman A
7
@SalmanA Jawaban yang saya rujuk salah sejak awal. Mereka tidak berlaku untuk CSS2.1, CSS2 atau CSS1.
Robert Siemer
@RobertSiemer poin bagus, saya memindahkan komentar saya ke stackoverflow.com/questions/50812118/… (yang tidak pernah kurang terkait dengan topik ini)
Peter T.
Dan implementasi JavaScript: github.com/mathiasbynens/CSS.escape/blob/master/css.escape.js
Duarte Cunha Leão
71

Saya telah menjawab pertanyaan Anda secara mendalam di sini: http://mathiasbynens.be/notes/css-escapes

Artikel ini juga menjelaskan cara keluar dari karakter apa pun di CSS (dan JavaScript), dan saya juga membuat alat yang berguna untuk ini. Dari halaman itu:

Jika Anda memberi elemen nilai ID ~!@$%^&*()_+-=,./';:"?><[]{}|`#, pemilih akan terlihat seperti ini:

CSS:

<style>
  #\~\!\@\$\%\^\&\*\(\)\_\+-\=\,\.\/\'\;\:\"\?\>\<\[\]\\\{\}\|\`\#
  {
    background: hotpink;
  }
</style>

JavaScript:

<script>
  // document.getElementById or similar
  document.getElementById('~!@$%^&*()_+-=,./\';:"?><[]\\{}|`#');
  // document.querySelector or similar
  $('#\\~\\!\\@\\$\\%\\^\\&\\*\\(\\)\\_\\+-\\=\\,\\.\\/\\\'\\;\\:\\"\\?\\>\\<\\[\\]\\\\\\{\\}\\|\\`\\#');
</script>
Mathias Bynens
sumber
4
@ Darryl Tentu saja, ini adalah contoh yang cukup ekstrem, tetapi hal-hal seperti class="404-error"dapat bermanfaat
Mathias Bynens
Saya punya contoh: saya mengkonversi output sistem menyoroti sintaks ke CSS. ini memiliki nama kelas seperti "ISO C ++: Jenis ( _t / _type)". jika saya hanya mengganti spasi putih saya punya nama kelas yang valid.
domba terbang
Di situs web Anda, Anda mengatakan bahwa karakter spasi dapat menggunakan garis miring terbalik. Ketika saya mencobanya dengan nama kelas, saya tidak bisa membuatnya berfungsi. Saya perhatikan tidak ada ruang dalam contoh ini. Apa itu mungkin?
Adamarla
@ Adamarla <p class="foo bar">menambahkan dua kelas ke pelemen :, foodan bar. Tidak ada cara (yang dapat saya pikirkan) untuk menambahkan classname yang berisi spasi putih ke elemen HTML. Informasi tentang cara keluar dari karakter spasi putih dimasukkan karena berguna untuk keluar dari karakter tersebut dalam konteks pengidentifikasi lain, misalnya nama keluarga font.
Mathias Bynens
3
Seperti kebanyakan hal dalam hidup, tampaknya dalam CSS ada perbedaan antara "secara teknis legal sampai ekstrem" dan "waras".
Volksman
69

Baca spesifikasi W3C . (Ini adalah CSS 2.1, cari versi yang sesuai untuk asumsi Anda tentang peramban)

sunting: paragraf yang relevan berikut:

Dalam CSS, pengidentifikasi (termasuk nama elemen, kelas, dan ID dalam pemilih) hanya dapat berisi karakter [a-z0-9] dan ISO 10646 karakter U + 00A1 dan lebih tinggi, ditambah dengan tanda hubung (-) dan garis bawah (_) ; mereka tidak bisa mulai dengan angka, atau tanda hubung diikuti oleh angka. Pengidentifikasi juga dapat berisi karakter yang lolos dan karakter ISO 10646 apa pun sebagai kode numerik (lihat item berikutnya). Misalnya, pengidentifikasi "B&W?" dapat ditulis sebagai "B \ & W \?" atau "B \ 26 W \ 3F".

sunting 2: seperti yang ditunjukkan @mipadi dalam jawaban Triptych, ada peringatan ini , juga di laman web yang sama:

Dalam CSS, pengidentifikasi dapat dimulai dengan '-' (tanda hubung) atau '_' (garis bawah). Kata kunci dan nama properti yang dimulai dengan '-' atau '_' dicadangkan untuk ekstensi khusus vendor. Ekstensi khusus vendor tersebut harus memiliki salah satu format berikut:

'-' + vendor identifier + '-' + meaningful name 
'_' + vendor identifier + '-' + meaningful name

Contoh:

Misalnya, jika organisasi XYZ menambahkan properti untuk menggambarkan warna perbatasan di sisi timur tampilan, mereka mungkin menyebutnya -xyz-border-east-color.

Contoh lain yang diketahui:

 -moz-box-sizing
 -moz-border-radius
 -wap-accesskey

Tanda hubung awal atau garis bawah dijamin tidak akan pernah digunakan di properti atau kata kunci oleh tingkat CSS saat ini atau di masa depan. Jadi implementasi CSS yang khas mungkin tidak mengenali properti seperti itu dan mungkin mengabaikannya sesuai dengan aturan untuk menangani kesalahan parsing. Namun, karena tanda hubung awal atau garis bawah adalah bagian dari tata bahasa, pelaksana CSS 2.1 harus selalu dapat menggunakan parser yang menyesuaikan CSS, terlepas dari apakah mereka mendukung ekstensi khusus vendor.

Penulis harus menghindari ekstensi khusus vendor

Jason S
sumber
Saya merujuk pada suntingan kedua Anda tentang tanda hubung utama dan garis bawah, tetapi lupa untuk menjelaskannya. Maaf bila membingungkan.
Albin
24

Ekspresi reguler lengkap adalah:

-?(?:[_a-z]|[\200-\377]|\\[0-9a-f]{1,6}(\r\n|[ \t\r\n\f])?|\\[^\r\n\f0-9a-f])(?:[_a-z0-9-]|[\200-\377]|\\[0-9a-f]{1,6}(\r\n|[ \t\r\n\f])?|\\[^\r\n\f0-9a-f])*

Jadi semua karakter Anda yang terdaftar kecuali " -" dan " _" tidak diizinkan jika digunakan secara langsung. Tetapi Anda bisa menyandikannya menggunakan backslash foo\~baratau menggunakan notasi unicode foo\7E bar.

Gumbo
sumber
mengapa [\200-\377]? [\178-\1114112]diizinkan tanpa hambatan dalam CSS 3.
domba terbang
\377di sini sebenarnya salah. Ada catatan pada bagian Grammar of CSS2.1's Lexical Scanner yang menyatakan: "The" \ 377 "mewakili jumlah karakter tertinggi yang dapat ditangani oleh versi Flex saat ini (desimal 255). Itu harus dibaca sebagai" \ 4177777 "( desimal 1114111), yang merupakan titik kode tertinggi di Unicode / ISO-10646. " Itu juga harus dari \240, bukan \377. Saya kira ini sudah 7 tahun sekarang jadi hal-hal mungkin telah berubah sedikit sejak itu.
James Donnelly
1
Saya percaya ekspresi reguler yang lebih akurat adalah -?(?:[_a-z]|(?![\u0000-\u0239]).*|\\[0-9a-f]{1,6}(\r\n|[ \t\r\n\f])?|\\[^\r\n\f0-9a-f])(?:[_a-z0-9-]|(?![\u0000-\u0239]).*|\\[0-9a-f]{1,6}(\r\n|[ \t\r\n\f])?|\\[^\r\n\f0-9a-f])*.
James Donnelly
2
@JamesDonnelly Silakan mengedit jawaban saya jika Anda merasa perlu beberapa pembaruan.
Gumbo
11

Bagi mereka yang mencari solusinya, Anda bisa menggunakan pemilih atribut, misalnya, jika kelas Anda dimulai dengan angka. Perubahan:

.000000-8{background:url(../../images/common/000000-0.8.png);} /* DOESN'T WORK!! */

untuk ini:

[class="000000-8"]{background:url(../../images/common/000000-0.8.png);} /* WORKS :) */

Juga, jika ada beberapa kelas, Anda harus menentukannya di pemilih saya pikir.

Sumber:

  1. https://benfrain.com/when-and-where-you-can-use-numbers-in-id-and-class-names/
  2. Apakah ada solusi untuk membuat kelas CSS dengan nama yang dimulai dengan angka valid?
D.Tate
sumber
5

Pemahaman saya adalah bahwa garis bawah secara teknis valid. Periksa:

https://developer.mozilla.org/en/underscores_in_class_and_id_names

"... kesalahan dengan spesifikasi yang diterbitkan pada awal 2001 membuat menggarisbawahi hukum untuk pertama kalinya."

Artikel yang ditautkan di atas mengatakan tidak pernah menggunakannya, lalu memberikan daftar peramban yang tidak mendukung mereka, yang semuanya, dalam hal jumlah pengguna setidaknya, lama-lama.

maha
sumber
4

Untuk HTML5 / CSS3 kelas dan ID dapat dimulai dengan angka.

Marius
sumber
1
Apakah Anda punya sumber untuk ini? Mungkin saya kehilangan sesuatu, tetapi penyeleksi spec CSS3 tautan ke definisi pengidentifikasi dalam spesifikasi CSS 2.1 yang tidak mengizinkan nomor terkemuka.
Ryan
11
w3.org/TR/2003/WD-css3-syntax-20030813/#characters <- masih tidak mengizinkan nomor terkemuka dll (meskipun berfungsi)
Jamie Pate
10
HTML 5 memungkinkan kelas dan ID dimulai dengan angka (mis class="1a".). Namun, pengidentifikasi CSS tidak dapat dimulai dengan angka (mis. Tidak .1aakan berfungsi). Anda dapat menghindarinya, tangguh (misalnya .\31 aatau .\000031a).
Oriol
Meskipun biasanya berfungsi di CSS juga, tetapi sepertinya itu masih belum resmi. "Nama properti dan nama at-rule selalu merupakan pengidentifikasi, yang harus dimulai dengan huruf atau tanda hubung diikuti dengan huruf, dan kemudian dapat berisi huruf, angka, tanda hubung, atau garis bawah." - w3.org/TR/css3-syntax/#syntax-description
Stiker
@ Pangloss Tapi nama kelas bukan nama properti atau nama at-rule.
Bennett McElwee
1

Keluar dari jawaban @ Triptych, Anda dapat menggunakan 2 pencocokan regex berikut untuk membuat string valid:

[^a-z0-9A-Z_-]

Ini adalah pasangan terbalik yang memilih apa pun yang bukan huruf, angka, tanda hubung atau garis bawah untuk memudahkan penghapusan.

^-*[0-9]+

Ini cocok dengan 0 atau 1 tanda hubung diikuti oleh 1 atau lebih angka di awal string, juga agar mudah dihapus.

Bagaimana saya menggunakannya di PHP:

//Make alphanumeric with dashes and underscores (removes all other characters)
$class = preg_replace("/[^a-z0-9A-Z_-]/", "", $class);
//Classes only begin with an underscore or letter
$class = preg_replace("/^-*[0-9]+/", "", $class);
//Make sure the string is 2 or more characters long
return 2 <= strlen($class) ? $class : '';
Manny Fleurmond
sumber