Bagaimana poin dalam kekhususan CSS dihitung

125

Meneliti kekhususan Saya menemukan blog ini - http://www.htmldog.com/guides/cssadvanced/specificity/

Ini menyatakan bahwa spesifisitas adalah sistem penilaian poin untuk CSS. Ini memberi tahu kita bahwa elemen bernilai 1 poin, kelas bernilai 10 poin dan ID bernilai 100 poin. Di atas juga dikatakan bahwa poin-poin ini dijumlahkan dan jumlah keseluruhan adalah kekhususan pemilih itu.

Sebagai contoh:

tubuh = 1 poin
tubuh .wrapper = 11 poin
tubuh .wrapper #container = 111 poin

Jadi, dengan menggunakan poin-poin ini, saya berharap CSS dan HTML berikut menghasilkan teks menjadi biru:

#a {
    color: red;
}

.a .b .c .d .e .f .g .h .i .j .k .l .m .n .o {
  color: blue;
}
<div class="a">
  <div class="b">
    <div class="c">
      <div class="d">
        <div class="e">
          <div class="f">
            <div class="g">
              <div class="h">
                <div class="i">
                  <div class="j">
                    <div class="k">
                      <div class="l">
                        <div class="m">
                          <div class="n">
                            <div class="o" id="a">
                              This should be blue.
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Mengapa teks berwarna merah ketika 15 kelas akan sama dengan 150 poin dibandingkan dengan 1 ID yang sama dengan 100 poin?

Tampaknya poin tidak hanya dijumlahkan; mereka digabungkan. Baca lebih lanjut tentang itu di sini - http://www.stuffandnonsense.co.uk/archives/css_specificity_wars.html

Apakah itu berarti kelas di selector kita = 0,0,15,0OR 0,1,5,0?

(naluri saya mengatakan itu yang pertama, karena kami TAHU kekhususan pemilih ID terlihat seperti ini 0,1,0,0:)

Sam
sumber
Ini juga sesuatu yang aneh: stackoverflow.com/questions/25565928/…
Armel Larcier

Jawaban:

138

Jawaban Pekka secara praktis benar, dan mungkin cara terbaik untuk memikirkan masalah tersebut.

Namun, seperti yang telah ditunjukkan oleh banyak orang, rekomendasi W3C CSS menyatakan bahwa "Menggabungkan tiga angka abc (dalam sistem bilangan dengan basis besar) memberikan kekhususan." Jadi geek dalam diri saya hanya perlu mencari tahu seberapa besar pangkalan ini.

Ternyata "basis yang sangat besar" yang digunakan (setidaknya oleh 4 browser yang paling umum digunakan * ) untuk mengimplementasikan algoritme standar ini adalah 256 atau 2 8 .

Artinya, gaya yang ditentukan dengan 0 id dan 256 nama kelas akan menimpa gaya yang ditentukan hanya dengan 1 id. Saya menguji ini dengan beberapa biola:

Jadi ada, secara efektif, sebuah "sistem poin," tapi itu bukan basis 10. Ini basis 256. Begini cara kerjanya:

(2 8 ) 2 atau 65536, dikalikan jumlah id di pemilih
+ (2 8 ) 1 atau 256, dikalikan jumlah nama kelas di pemilih
+ (2 8 ) 0 atau 1, dikalikan jumlah tag- nama di pemilih

Ini tidak terlalu praktis untuk latihan back-of-the-envelope untuk mengkomunikasikan konsep.
Mungkin itulah sebabnya artikel tentang topik tersebut menggunakan basis 10.

***** [Opera menggunakan 2 16 (lihat komentar karlcow). Beberapa mesin pemilih lainnya menggunakan tak terhingga - secara efektif tidak ada sistem poin (lihat komentar Simon Sapin).]

Pembaruan, Juli 2014:
Seperti yang dikatakan Blazemonger di awal tahun, browser webkit (chrome, safari) sekarang tampaknya menggunakan basis yang lebih tinggi dari 256. Mungkin 2 16 , seperti Opera? IE dan Firefox masih menggunakan 256.

Faust
sumber
34
Penting: perhatikan bahwa angka 256 tidak ada di spesifikasi . Dengan demikian, jawaban ini menjelaskan detail implementasi (yang memang berguna).
Matt Fenwick
6
Tidak hanya 256 yang tidak ada dalam spesifikasi seperti yang dikatakan @MattFenwick, tetapi juga bervariasi di seluruh penerapan. Tampaknya lebih besar di Opera. Di WeasyPrint dan cssselect itu adalah "infinity": Saya menggunakan tuple integer, bukan integer tunggal.
Simon Sapin
3
Opera @ Faust menggunakan 16 bit, bukan 8
karlcow
4
Jawaban ini memiliki gambaran yang lebih praktis daripada jawaban Pekka, sejujurnya. Pada dasarnya apa yang dikatakan @Matt Fenwick: yang Anda gambarkan adalah implementasi praktis dari spesifikasi tersebut. Salah satu kekurangannya, tapi tidak ada yang harus dilakukan, baik oleh penulis atau pelaksana.
BoltClock
7
256 tampaknya tidak cukup dalam versi webkit saat ini (Chrome dan Safari), lebih jauh menggarisbawahi poin @ MattFenwick.
Blazemonger
28

Pertanyaan bagus.

Saya tidak tahu pasti - semua artikel yang berhasil saya temukan menghindari contoh beberapa kelas, misalnya di sini - tetapi saya berasumsi bahwa ketika datang untuk membandingkan spesifikasi antara pemilih kelas dan ID , kelas akan dihitung dengan nilai 15saja, tidak peduli seberapa rinci itu.

Itu cocok dengan pengalaman saya dalam bagaimana kekhususan berperilaku.

Namun, harus ada beberapa kelas yang bertumpuk karena

.a .b .c .d .e .f .g .h .i .j .k .l .m .n .o

lebih spesifik daripada

.o

satu-satunya penjelasan yang saya miliki adalah bahwa spesifisitas kelas bertumpuk dihitung hanya terhadap satu sama lain tetapi tidak terhadap ID.

Pembaruan : Saya setengah jalan sekarang. Ini bukan sistem poin, dan informasi tentang kelas dengan berat 15 poin salah. Ini adalah sistem penomoran 4 bagian yang dijelaskan dengan sangat baik di sini .

Titik awalnya adalah 4 angka:

style  id   class element
0,     0,   0,    0

Berdasarkan penjelasan W3C tentang spesifisitas , nilai spesifisitas untuk aturan tersebut di atas adalah:

#a            0,1,0,0    = 100
classes       0,0,15,0   = ... see the comments

ini adalah sistem penomoran dengan basis yang sangat besar (tidak ditentukan?).

Pemahaman saya, karena alasnya sangat besar, tidak ada angka di kolom 4 yang bisa mengalahkan angka> 0 di kolom 3, begitu juga untuk kolom 2, kolom 1 .... Apakah benar?

Saya akan tertarik apakah seseorang dengan pemahaman yang lebih baik di Matematika daripada saya dapat menjelaskan sistem penomoran dan bagaimana mengubahnya menjadi desimal ketika elemen individu lebih besar dari 9.

Pekka
sumber
Itu karena itu antara .o & .a .b dll Jadi itu akan mempertimbangkannya secara kolektif. Tapi antara ID & kelas misalnya: .a dan #a ID akan selalu overpower. Ini akan (saya asumsikan) hanya dihitung antar kelas jika tidak ada daya tarik yang lebih kuat. Misalnya kelas akan pergi ke elemen dan id atas kelas.
Sphvn
@Ozaki itulah yang saya asumsikan juga, tetapi itu bertentangan dengan apa yang dikatakan OP tentang sistem poin. Harus ada lebih banyak permainan. Saya ingin melihat aturan di baliknya.
Pekka
Baru sadar kita berdua sampai pada kesimpulan yang sama. Kerja bagus!
Sam
5
Untuk sisi matematika, kita dapat mengerjakan basis 16 di sini (karena tidak ada bilangan individual yang melebihi 15). Jadi 0,1,0,0 = 0100h = 256 0,0,15,0 = 00f0h = 240 256> 240 sehingga pemilih id menang.
Matthew Wilson
1
Ya, Anda dapat menganggap kalkulasi spesifisitas dilakukan dalam sistem bilangan dengan basis besar. Saya pikir istilah "concatenating" (juga digunakan dalam spesifikasi) adalah deskripsi yang jauh lebih baik. (Datang ke sini dari menjawab pertanyaan baru yang ternyata adalah penipuan yang satu ini, lanjutkan ...)
BoltClock
9

Draf Kerja Level 4 Selectors saat ini melakukan pekerjaan yang baik dalam menjelaskan Specificity dalam CSS:

Kekhususan dibandingkan dengan membandingkan ketiga komponen secara berurutan: spesifisitas dengan nilai A yang lebih besar lebih spesifik; jika dua nilai A terikat, maka spesifisitas dengan nilai B yang lebih besar lebih spesifik; jika kedua nilai B juga terikat, maka spesifisitas dengan nilai c lebih besar lebih spesifik; jika semua nilai terikat, kedua spesifikasi tersebut sama.

Ini berarti bahwa nilai A, B, dan C sama sekali tidak bergantung satu sama lain.

15 kelas tidak memberi pemilih Anda skor spesifisitas 150, itu memberi nilai B 15. Satu nilai A cukup untuk mengalahkan ini.

Sebagai metafora, bayangkan sebuah keluarga dengan 1 orang tua, 1 orang tua dan 1 anak. Ini bisa direpresentasikan sebagai 1,1,1 . Jika orang tua memiliki 15 anak, itu tidak langsung membuat mereka menjadi orang tua lain ( 1,2,0 ). Ini berarti bahwa orang tua memiliki tanggung jawab yang jauh lebih besar daripada yang mereka miliki dengan hanya 1 anak ( 1,1,15 ). ;)

Dokumentasi yang sama juga mengatakan:

Karena batasan penyimpanan, implementasi mungkin memiliki batasan pada ukuran A , B , atau c . Jika demikian, nilai yang lebih tinggi dari batas harus dijepit ke batas itu, dan tidak meluap.

Ini telah ditambahkan untuk mengatasi masalah yang disajikan dalam jawaban Faust , di mana implementasi CSS pada tahun 2012 memungkinkan nilai spesifisitas saling melimpah.

Kembali pada tahun 2012, sebagian besar browser menerapkan batasan 255, tetapi batasan ini dibiarkan meluap. 255 kelas memiliki skor spesifisitas A, B, c 0,255,0 , tetapi 256 kelas overflow dan memiliki skor A, B, c 1,0,0 . Tiba-tiba nilai B kita menjadi nilai A. Dokumentasi Selectors Level 4 sepenuhnya menyinari masalah itu dengan menyatakan bahwa batas tidak akan pernah bisa meluap. Dengan implementasi ini, baik 255 dan 256 kelas akan memiliki yang sama A, B, c skor 0,255,0 .

Masalah yang diberikan dalam jawaban Faust telah diperbaiki di sebagian besar browser modern.

James Donnelly
sumber
8

Saat ini saya menggunakan buku Penguasaan CSS: Solusi Standar Web Tingkat Lanjut .

Bab 1, halaman 16 mengatakan:

Untuk menghitung seberapa spesifik suatu aturan, setiap jenis selektor diberi nilai numerik. Kekhususan aturan kemudian dihitung dengan menjumlahkan nilai dari setiap pemilihnya. Sayangnya, spesifisitas tidak dihitung dalam basis 10 tetapi angka basis yang tinggi dan tidak ditentukan. Ini untuk memastikan bahwa pemilih yang sangat spesifik, seperti pemilih ID, tidak pernah diganti oleh banyak pemilih yang kurang spesifik, seperti pemilih jenis.

(penekanan saya) dan

Kekhususan pemilih dipecah menjadi empat tingkat konstituen: a, b, c, dan d.

  • jika gayanya adalah gaya sebaris, maka a = 1
  • b = jumlah total pemilih id
  • c = jumlah kelas, kelas semu, dan pemilih atribut
  • d = jumlah pemilih jenis dan pemilih elemen semu

Selanjutnya dikatakan bahwa Anda sering dapat melakukan penghitungan dalam basis 10, tetapi hanya jika semua kolom memiliki nilai kurang dari 10.


Dalam contoh Anda, id tidak bernilai 100 poin; masing-masing bernilai [0, 1, 0, 0]poin. Oleh karena itu, satu id mengalahkan 15 kelas karena [0, 1, 0, 0]lebih besar dari [0, 0, 15, 0]pada sistem bilangan basis tinggi.

Matt Fenwick
sumber
4

Saya suka membandingkan peringkat Spesifitas dengan tabel medali Olimpiade (metode pertama emas - berdasarkan jumlah medali emas, lalu perak, dan perunggu).

Ini bekerja juga dengan pertanyaan Anda (sejumlah besar pemilih dalam satu kelompok kekhususan). Kekhususan dipertimbangkan setiap kelompok secara terpisah. Di dunia nyata saya sangat jarang melihat kasus dengan lebih dari selusin penyeleksi).

Ada juga kalkulator kekhususan yang cukup bagus yang tersedia di sini . Anda dapat meletakkan contoh Anda (#a dan .a .b .c .d .e .f .g .h .i .j .k .l .m .n .o) di sana dan melihat hasilnya.

Contoh tabel medali Olimpiade Rio 2016 masukkan deskripsi gambar di sini

rkarczmarczyk.dll
sumber
3

Saya tidak percaya bahwa penjelasan blog itu benar. Spesifikasinya ada di sini:

http://www.w3.org/TR/CSS2/cascade.html#specificity

"Poin" dari pemilih kelas tidak bisa menjadi lebih penting daripada pemilih "id". Ini tidak bekerja seperti itu.

Matthew Wilson
sumber
Seperti yang saya katakan dalam jawaban saya. ^^ Namun itu membuat perbedaan jika Anda memiliki lebih dari jenis yang sama (elemen, kelas, id). Tapi itu cukup jelas jika 5 mengatakan merah dan 3 mengatakan biru, saya akan menjadi merah.
Sphvn
Kata-kata di sekitar spesifisitas mungkin tidak banyak berubah antara CSS2 dan CSS2.1, tetapi Anda benar-benar harus mengacu pada spesifikasi CSS2.1 di diskusi mendatang karena ini sepenuhnya menggantikan CSS2 yang secara umum rusak pada titik rilis.
Robin Whittleton
1

Saya akan mengatakan bahwa:

Element < Class < ID

Saya pikir mereka hanya menumpuk tergantung apa yang Anda dapatkan jika kelipatannya sama. Jadi Kelas akan selalu menimpa elemen dan ID selalu di atas Kelas tetapi jika turun ke mana dari 4 elemen di mana 3 menjadi biru dan 1 merah, itu akan menjadi biru.

Sebagai contoh:

.a .b .c .d .e .f .g .h .i .j .k .l
{
color: red;
}

 .m .n .o
{
color blue;
}

Harus berubah menjadi merah.

Lihat Contoh http://jsfiddle.net/RWFWq/

"jika 5things mengatakan merah dan 3 mengatakan biru, baik aku akan merah"

Sphvn
sumber