CSS: setelah tidak menambahkan konten ke elemen tertentu

100

Saya kesulitan memahami perilaku :afterproperti CSS . Menurut spesifikasi ( disini dan disini ):

Seperti yang ditunjukkan oleh namanya, :beforedan :afterpseudo-elemen menentukan lokasi konten sebelum dan sesudah konten pohon dokumen elemen.

Tampaknya ini tidak membatasi elemen mana yang dapat memiliki properti :after(atau :before). Namun, tampaknya hanya bekerja dengan spesifik elemen ... <p>karya, <img>tidak, <input>tidak, <table>tidak. Saya bisa menguji lebih banyak, tetapi intinya dibuat. Perhatikan bahwa ini tampaknya cukup konsisten di seluruh browser. Apa yang menentukan apakah suatu objek dapat menerima properti :beforedan :after?

eykanal
sumber

Jawaban:

156

imgdan inputkeduanya merupakan elemen yang diganti .

Elemen yang diganti adalah elemen yang penampilan dan dimensinya ditentukan oleh sumber daya eksternal. Contohnya termasuk gambar ( <img>tag), plugin ( <object>tag), dan unsur-unsur bentuk ( <button>, <textarea>, <input>, dan <select>tag). Semua jenis elemen lainnya dapat disebut sebagai elemen yang tidak diganti.

:beforedan :afterhanya bekerja dengan elemen yang tidak diganti.

Dari spesifikasi :

Catatan. Spesifikasi ini tidak sepenuhnya mendefinisikan interaksi dari :beforedan :afterdengan elemen yang diganti (seperti IMG dalam HTML). Ini akan dijelaskan secara lebih rinci dalam spesifikasi yang akan datang.

Dengan span:before, span:after, DOM terlihat seperti ini:

<span><before></before>Content of span<after></after></span>

Jelas, itu tidak akan berhasil <img src="" />.

tigapuluhdot
sumber
2
"Konten yang dihasilkan tidak mengubah pohon dokumen." Jadi saya akan terkejut jika Anda dapat menemukan sesuatu seperti " <before></before>" di sumbernya.
Knu
4
@Knu: Kamu benar, aku menjelaskannya dengan buruk. Anda tidak akan pernah menemukan <before></before>. Saya seharusnya mengatakan "berpura-pura DOM" atau sesuatu. Intinya adalah untuk menunjukkan itu :beforedan :afterberada di dalam elemen, bukan di luarnya.
tigapuluhdot
Tidak, mereka tidak disimpan di shadow DOM.
alat
3
Spesifikasi yang dikutip tidak mengatakan itu :beforedan :aftertidak berfungsi untuk elemen yang diganti; ia hanya mengatakan bahwa ia tidak "sepenuhnya mendefinisikan" bagaimana dan bahwa ini akan didefinisikan di masa depan (yang belum terjadi sejauh ini). Apa yang terjadi di DOM tidak relevan di sini. Meskipun browser tidak mendukung elemen pseudo ini untuk beberapa elemen, ini tidak ada dalam spesifikasi, hanya implementasi yang dilakukan.
Jukka K. Korpela
Saya dulu menganggap logis penjelasan itu ::beforedan ::aftertidak berfungsi untuk elemen void (kosong) yang tidak pernah memiliki konten aktual, sebelum / sesudah itu dapat diterapkan. Tapi yang mengejutkan, mereka bekerja untuk hrelemen di hampir semua browser.
Ilya Streltsyn
9

:beforedan :aftertidak diharuskan bekerja untuk elemen yang diganti, dan spesifikasi CSS tidak menentukan bagaimana mereka akan bekerja untuk mereka, dan konsep elemen yang diganti agak kabur.

Spesifikasi CSS 2.1 dengan jelas menyarankan bahwa mereka dapat bekerja untuk elemen yang diganti, hanya mengatakan bahwa itu tidak "sepenuhnya mendefinisikan" bagaimana. Hal ini berkaitan dengan masalah bahwa elemen yang diganti diharapkan memiliki rendering visualnya sendiri, yang tidak dikontrol oleh CSS, sedangkan pseudo-elemen harus menambahkan sesuatu ke konten elemen. Spesifikasi menambahkan bahwa ini akan didefinisikan "secara lebih rinci" dalam spesifikasi yang akan datang, tetapi sejauh ini belum terjadi.

Vendor browser baru saja memutuskan untuk menghindari masalah dengan tidak mengimplementasikan elemen semu ini untuk beberapa elemen sama sekali.

Tidak jelas sama sekali apa artinya "elemen yang diganti", dan artinya tampaknya telah berubah. Hal ini sering diartikan sebagai makna yang sama dengan elemen kosong (elemen dengan EMPTYkonten yang dideklarasikan, yaitu elemen yang tidak dapat memiliki konten apa pun), tetapi CSS 2.1 sendiri menunjukkan contoh style sheet dengan selektor br:before(meskipun browser telah mengabaikan ini, menerapkannya brsendiri cara). Dapat dikatakan bahwa semakin banyak elemen telah pindah ke lingkup rendering CSS, setidaknya sebagian. Misalnya, inputelemen (termasuk font, warna, dll.) Sebagian besar dapat dikontrol dengan CSS di browser modern.

Browser saat ini (Firefox, IE, Chrome) tampaknya tidak mendukung :afterdan :beforepseudo-elemen untuk elemen kosong selain hr. Untuk hr, IE dan Chrome menempatkan konten yang dihasilkan di dalam kotak berbatasan, yang merupakan implementasi dari hr; konten membuat kotak lebih tinggi. Firefox menempatkan konten dari kedua elemen pseudo (!) Setelah aturan horizontal yang diimplementasikan hr. Variasi ini menggambarkan jenis masalah "interaksi" yang dirujuk dalam CSS 2.1.

Sering diklaim bahwa elemen semu ini tidak dapat digunakan untuk elemen kosong karena definisi HTML-nya tidak mengizinkan konten apa pun. Ini adalah kesalahan kategori. Aturan sintaks dari bahasa markup tidak membatasi apa yang dapat Anda lakukan di CSS

Untuk menyimpulkan, :afterdan :beforesaat ini tidak dapat digunakan untuk elemen kosong (kecuali sedikit untuk hr), tetapi ini terutama karena implementasi dan dapat berubah di masa mendatang.

Jukka K. Korpela
sumber
-1

Elemen yang tidak memiliki tag penutup adalah elemen kosong dan tidak dapat menampilkan konten di dalamnya:

https://www.w3.org/TR/html5/syntax.html#void-elements

Semua browser Blink, Webkit, dan Quantum memungkinkan Anda membuat elemen semu hanya pada kotak centang tetapi ini kontroversial karena tidak ada spesifikasi yang mengizinkan perilaku ini.

Berikut contohnya: https://codepen.io/equinusocio/pen/BOBaEM/

input[type="checkbox"] {
  appearance: none;
  color: #000;
  width: 42px;
  height: 24px;
  border: 1px solid currentColor;
  border-radius: 100px;
  cursor: pointer;
  transition: all 100ms;
  background-size: 30%;
  outline: none;
  position: relative;
  box-sizing: border-box;
  background-color: #eee;
  transition: background-color 200ms;

  &::before {
    content: '';
    position: absolute;
    left: 2px;
    top: 2px;
    bottom: 2px;
    height: 18px;
    width: 18px;
    border-radius: 50%;
    background-color: currentColor;
    will-change: transform;
    transition: transform 200ms cubic-bezier(.01,.65,.23,1);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  }

  &:checked {
    background-color: aquamarine;

    &::before {
      transform: translateX(100%);
    }
  }
}
Mattia Astorino
sumber
tidak akan bekerja di semua browser ... dan tidak ada spesifikasi yang menyatakan sekarang kita bisa .. jika sudah punya tolong bagikan karena tidak aman untuk mempertimbangkan elemen semu dengan input
Temani Afif
Ia bekerja di semua browser kecuali IE. Bahkan flexbox tidak didukung oleh IE 9 jadi di mana masalahnya. Solusi ini berfungsi di semua browser Blink, Webkit, dan Quantum dan dapat sangat berguna bagi orang-orang yang bekerja di lingkungan khusus webkit seperti Electron.
Mattia Astorino
Seperti yang Anda katakan dalam jawaban Anda, tidak ada spesifikasi untuk itu, jadi suatu hari mungkin akan berhenti bekerja. Ini bukan satu-satunya hal yang berperilaku dan berfungsi tanpa spesifikasi apa pun yang ditentukan, tetapi kita tidak boleh mengandalkan mereka dan mengatakan bahwa mereka berfungsi. ini seperti tag yang tidak jelas, mereka masih berfungsi tetapi kita harus berhenti menggunakannya karena suatu hari nanti tidak akan. Jadi ya ini bisa bermanfaat bagi orang-orang dan komentar saya juga berguna untuk memperingatkan orang-orang bahwa mereka harus waspada bahwa ini tidak resmi.
Temani Afif