Dapatkah saya menggunakan: sebelum atau: setelah elemen semu pada bidang input?

685

Saya mencoba menggunakan :afterelemen pseudo-CSS pada suatu inputbidang, tetapi tidak berhasil. Jika saya menggunakannya dengan span, itu berfungsi OK.

<style type="text/css">
.mystyle:after {content:url(smiley.gif);}
.mystyle {color:red;}
</style>

Ini bekerja (menempatkan smiley setelah "buu!" Dan sebelum "lagi")

<span class="mystyle">buuu!</span>a some more

Ini tidak berfungsi - itu hanya warna someValue dalam merah, tetapi tidak ada smiley.

<input class="mystyle" type="text" value="someValue">

Apa yang saya lakukan salah? saya harus menggunakan pseudo-selector lain?

Catatan: Saya tidak bisa menambahkan spansekitar saya input, karena sedang dibuat oleh kontrol pihak ketiga.

matra
sumber
Jika Anda telah benar-benar tidak ada kontrol atas HTML, cobalah mengubah border-colordari inputsebaliknya. Saya merasa lebih menarik perhatian.
Blazemonger

Jawaban:

254

:afterdan :beforetidak didukung di Internet Explorer 7 dan di bawahnya, pada elemen apa pun.

Ini juga tidak dimaksudkan untuk digunakan pada elemen yang diganti seperti elemen bentuk (input) dan elemen gambar .

Dengan kata lain itu tidak mungkin dengan CSS murni.

Namun jika menggunakan jquery Anda bisa menggunakan

$(".mystyle").after("add your smiley here");

API docs pada .after

Untuk menambahkan konten Anda dengan javascript. Ini akan bekerja di semua browser.

Alex
sumber
Alex, saya menggunakan IE8 dan FF terbaru, jadi IE7 tidak menjadi masalah. Saya sedang mencari dokumentasi tentang pembatasan: setelah, tetapi tidak dapat menemukannya. w3.org/TR/CSS2/generate.html menyatakan, bahwa itu dimasukkan setelah simpul saat ini di pohon dokumen sehingga harus bekerja dalam kedua kasus.
matra
3
Kecuali Anda membangun halaman hanya untuk Anda gunakan sendiri, sebagian besar internet tetap menggunakan browser tersebut. Spesifikasi w3c mengatakan ini ya; tetapi seperti yang Anda ketahui, browser menerapkan interpretasi mereka sendiri atas spesifikasi tersebut. Menggunakan: setelah pada input hanya akan berfungsi di Opera 9+, tetapi tidak diterapkan di IE, FF, safari atau chrome karena cara mereka membangun DOM secara internal - sekali lagi itu tidak dapat dilakukan dengan CSS murni.
Alex
3
Saya tidak yakin apakah ini yang terjadi pada bulan April, tetapi Webkit mendukung :aftersecara umum, meskipun tidak mendukung input :beforeatau tidak :after.
coreyward
258
Sejauh yang saya mengerti elemen W3C :afterdan :beforepseudo, mereka hanya bisa memakai elemen kontainer. Mengapa? Karena mereka ditambahkan di dalam elemen tertentu. inputbukan wadah. buttonmisalnya karena itu Anda dapat memakainya. Bekerja seperti yang diharapkan. Spesifikasi sebenarnya mengatakan: sebelum dan sesudah isi pohon dokumen elemen Secara eksplisit mengatakan CONTENT . Jadi elemen harus menjadi wadah.
Robert Koritnik
29
Jawaban berikutnya adalah cara yang lebih baik .. Memberikan alasan sebenarnya daripada berbicara tentang IE 7 (siapa yang peduli) dan jQuery (ide buruk)
Rowan
1304

:beforedan :afterrender di dalam sebuah wadah

dan <input> tidak dapat mengandung elemen lain.


Elemen semu hanya dapat didefinisikan (atau lebih baik dikatakan hanya didukung) pada elemen kontainer. Karena cara mereka diberikan ada di dalam wadah itu sendiri sebagai elemen anak. inputtidak dapat mengandung elemen lain karena itu mereka tidak didukung. A buttondi sisi lain yang juga merupakan elemen bentuk mendukung mereka, karena itu adalah wadah sub-elemen lainnya.

Jika Anda bertanya kepada saya, jika beberapa browser yang tidak menampilkan dua pseudo-elemen ini pada elemen non-kontainer, itu bug dan kesesuaian non-standar. Spesifikasi langsung berbicara tentang konten elemen ...

Spesifikasi W3C

Jika kita hati-hati membaca spesifikasi itu sebenarnya mengatakan bahwa mereka dimasukkan ke dalam elemen yang mengandung:

Penulis menentukan gaya dan lokasi konten yang dihasilkan dengan: sebelum dan: setelah elemen semu. Seperti namanya, elemen-elemen: before dan: after pseudo menentukan lokasi konten sebelum dan sesudah konten hierarki dokumen elemen. Properti 'konten', bersama dengan elemen pseudo ini, menentukan apa yang dimasukkan.

Lihat? konten hierarki dokumen elemen . Seperti yang saya pahami, ini berarti di dalam sebuah wadah.

Robert Koritnik
sumber
119
+1 Jauh lebih baik daripada jawaban yang diterima. Terima kasih atas penjelasan yang jelas tentang standar itu sendiri. Begitu banyak untuk [required]::before { content "*"; color: red; }: P
Kevin Peno
93
Kiat: Jika Anda mengalami masalah hanya dengan mengirim masukan suka <input type="submit" value="Send"/>, gunakan <button type="submit">Send</button>saja. Presentasi identik tetapi <button>wadah dan dengan demikian mendukung :beforedan :after.
Flu
15
Bagaimana dengan <hr />? Saya pikir itu bukan elemen wadah, tetapi bisa membuat :afterdan :before jsfiddle.net/Uf88j/1
deathlock
7
@deathlock: itu memang menarik. Saya akan mengatakan itu harus semacam anomali dan saya tidak akan bergantung pada itu bekerja lintas browser atau versi lintas ... HR bukan elemen wadah maka dari itu tidak boleh memungkinkan untuk elemen semu. Bahkan standar W3C mengatakan bahwa itu tidak memungkinkan konten. Dan jika Anda memeriksa elemen batal Anda dapat melihat bahwa elemen-elemen ini seharusnya tidak memiliki konten dalam keadaan apa pun. Elemen pseudo adalah konten sehingga diharapkan versi peramban di masa depan gagal menampilkannya.
Robert Koritnik
5
" : sebelum dan: setelah dirender di dalam sebuah wadah " The: before and: after pseudo Elements datang " sebelum dan sesudah konten ". Bukan "di awal atau akhir" wadah. Spesifikasi tidak menyebutkan wadah . Dengan tag suka pdan h1, konten ada di dalam tag, jadi sebelum / sesudah muncul di dalamnya juga. Dengan elemen seperti inputdan hr,: sebelum dan: setelah akan tetap muncul sebelum atau setelah konten, tetapi tidak ada wadah yang terlibat (terutama untuk input). input: dicentang: sebelumnya banyak digunakan untuk menunjukkan kotak centang sedang diperiksa melalui css.
Radley Sustaire
60

Anehnya, ia bekerja dengan beberapa jenis input. Paling tidak di Chrome,

<input type="checkbox" />

berfungsi dengan baik, sama seperti

<input type="radio" />

Hanya saja type=textdan sebagian lainnya tidak berfungsi.

vals
sumber
1
@ ANeves, itu berfungsi di Chromium untuk saya, tetapi tidak di Firefox.
kcpr
45

Berikut ini pendekatan lain (dengan asumsi Anda memiliki kendali atas HTML): tambahkan <span></span>hak kosong setelah input, dan targetkan itu menggunakan CSSinput.mystyle + span:after

.field_with_errors {
  display: inline;
  color: red;
}
.field_with_errors input+span:after {
  content: "*"
}
<div class="field_with_errors">Label:</div>
<div class="field_with_errors">
  <input type="text" /><span></span> 
</div>

Saya menggunakan pendekatan ini di AngularJS karena akan menambahkan .ng-invalidkelas secara otomatis untuk <input>membentuk elemen, dan ke formulir, tetapi tidak ke <label>.

Blazemonger
sumber
1
Hal ini memungkinkan untuk menambahkan tindakan hover, seperti: input:hover+span:after{color: blue}. Suara positif.
krassowski
2
Mengapa jawaban ini memiliki sedikit upvote? Saya pikir pengetahuan teoritis itu penting, tetapi ini memecahkan masalah.
jorgefpastor
Opsi yang bagus untuk menyelesaikan masalah.
Jester
39

:beforedan :afterditerapkan di dalam wadah, yang berarti Anda dapat menggunakannya untuk elemen dengan tag akhir.

Itu tidak berlaku untuk elemen yang menutup sendiri.

Di samping catatan, elemen yang menutup sendiri (seperti img / jam / input) juga dikenal sebagai 'Elemen Diganti', karena mereka diganti dengan konten masing-masing. "Objek Eksternal" karena kurangnya istilah yang lebih baik. Lebih baik baca di sini

CatalinBerta
sumber
Jawaban ini benar, singkat dan memberikan konteks penting. Harus di atas, imo.
Paul
31

Saya menggunakan background-imageuntuk membuat titik merah untuk bidang yang diperlukan.

input[type="text"][required] {
  background-image: radial-gradient(red 15%, transparent 16%);
  background-size: 1em 1em;
  background-position: top right;
  background-repeat: no-repeat
}

Lihat di Codepen

Veiko Jääger
sumber
20

Anda tidak bisa memasukkan elemen pseudo di elemen input, tetapi bisa memasukkan elemen shadow, seperti placeholder!

input[type="text"] {   
  &::-webkit-input-placeholder {
    &:before {
      // your code
    }
  }
}

Untuk membuatnya bekerja di browser lain, gunakan :-moz-placeholder, ::-moz-placeholderdan :-ms-input-placeholder di pemilih yang berbeda . Tidak dapat mengelompokkan pemilih, karena jika browser tidak mengenali pemilih akan membatalkan seluruh pernyataan.

UPDATE : Kode di atas hanya berfungsi dengan pra-prosesor CSS (SASS, KURANG ...), tanpa menggunakan pra-prosesor:

input[type="text"]::-webkit-input-placeholder:before { // your code }
Shankar Cabus
sumber
3
Bagus! Perhatikan bahwa elemen pseudo placeholder memiliki dukungan properti yang terbatas: warna, latar belakang, spasi kata, spasi huruf, dekorasi teks, penyelarasan vertikal, transformasi teks, tinggi baris, indentasi teks, opacity. Lihat css-tricks.com/almanac/selectors/p/placeholder
henry
Terima kasih atas petunjuknya. Ingatlah bahwa semua yang ada di dalam elemen pseudo akan hilang ketika kotak input diisi oleh pengguna. Itu masalah UX jika semua yang Anda inginkan, seperti saya, menampilkan glyphicon-searchmarkup tanpa menyentuh.
Davi Lima
2
Beberapa konteks mengapa ini tidak lagi berfungsi: bugs.chromium.org/p/chromium/issues/detail?id=582301
Oliver Joseph Ash
17

Elemen pseudo seperti :after, :beforehanya untuk elemen kontainer. Elemen-elemen yang memulai dan menutup di satu tempat seperti <input/>, <img>dll , bukanlah elemen kontainer dan karenanya elemen pseudo tidak didukung. Setelah Anda menerapkan elemen pseudo ke elemen wadah seperti <div>dan jika Anda memeriksa kode (lihat gambar), Anda dapat memahami apa yang saya maksud. Sebenarnya elemen pseudo dibuat di dalam elemen kontainer. Ini tidak mungkin dalam kasus <input>atau<img>

masukkan deskripsi gambar di sini

Pons Purushothaman
sumber
15

Solusi yang berfungsi dalam CSS murni:

Caranya adalah dengan mengira ada elemen dom setelah bidang teks.

/*
 * The trick is here:
 * this selector says "take the first dom element after
 * the input text (+) and set its before content to the
 * value (:before).
 */
input#myTextField + *:before {
  content: "👍";
} 
<input id="myTextField" class="mystyle" type="text" value="someValue" />
<!--
  There's maybe something after a input-text
  Does'nt matter what it is (*), I use it.
  -->
<span></span>

(*) Solusi terbatas, meskipun:

  • Anda harus berharap bahwa ada elemen dom berikut,
  • Anda harus berharap tidak ada bidang input lain yang mengikuti bidang input Anda.

Tetapi dalam kebanyakan kasus, kita tahu kode kita sehingga solusi ini tampak efisien dan 100% CSS dan 0% jQuery.


sumber
2
input#myTextField ~ span:before {jauh lebih baik, tetapi rentang harus memiliki kelas yang benar-benar lebih eksplisit seperti .tickatau.icon
Val
13

Saya menemukan posting ini karena saya mengalami masalah yang sama, ini adalah solusi yang bekerja untuk saya. Berbeda dengan mengganti nilai input, hapus saja dan posisikan rentang di belakangnya dengan ukuran yang sama, rentang tersebut dapat memiliki :beforekelas pseudo yang diterapkan dengan font font pilihan Anda.

<style type="text/css">

form {position: relative; }
.mystyle:before {content:url(smiley.gif); width: 30px; height: 30px; position: absolute; }
.mystyle {color:red; width: 30px; height: 30px; z-index: 1; position: absolute; }
</style>

<form>
<input class="mystyle" type="text" value=""><span class="mystyle"></span>
</form>
Morgan Feeney
sumber
1
+1 - Solusi ini berfungsi baik jika Anda menggunakan plugin atau kerangka kerja yang secara otomatis menambahkan kelas validasi ke elemen itu sendiri, tetapi tidak ke label induk.
Blazemonger
9

Kesalahpahaman terbesar di sini adalah makna kata-kata beforedan after. Mereka tidak merujuk ke elemen itu sendiri, tetapi ke konten di dalam elemen. Begitu element:beforejuga sebelum konten, dan element:aftersetelah konten, tetapi keduanya masih di dalam elemen asli.

The inputelemen memiliki konten dalam tampilan CSS, dan sehingga tidak memiliki :beforeatau :afterkonten semu. Hal ini berlaku untuk banyak elemen yang dibatalkan atau diganti.

Tidak ada elemen pseudo yang merujuk ke luar elemen.

Di alam semesta yang berbeda, elemen pseudo ini mungkin disebut sesuatu yang lain untuk membuat perbedaan ini lebih jelas. Dan seseorang bahkan mungkin telah mengusulkan elemen palsu yang benar-benar di luar elemen tersebut. Sejauh ini, ini bukan kasus di alam semesta ini.

Manngo
sumber
Saya mungkin tidak mengerti apa yang Anda maksud, tetapi jika saya lakukan, elemen pseudo bekerja pada jam? jsfiddle.net/demetriad/o49yn5hq
Chris
1
@ Chris Itu mengejutkan saya, dan saat mencari, untuk beberapa orang lain. Saya pikir itu adalah kekhasan. hrselalu ambigu dari sudut pandang CSS, meskipun Anda melihat lebih banyak dalam membahas warna.
Manngo
5

Menurut catatan dalam spesifikasi CSS 2.1, spesifikasi “tidak sepenuhnya menentukan interaksi antara: sebelum dan: setelah dengan elemen yang diganti (seperti IMG dalam HTML). Ini akan didefinisikan secara lebih rinci dalam spesifikasi masa depan. " Meskipun inputsebenarnya bukan elemen yang diganti lagi, situasi dasar tidak berubah: efek dari :beforedan :afterdi atasnya tidak ditentukan dan umumnya tidak memiliki efek.

Solusinya adalah menemukan pendekatan yang berbeda untuk masalah yang Anda coba atasi dengan cara ini. Menempatkan konten yang dihasilkan ke dalam kontrol input teks akan sangat menyesatkan: bagi pengguna, itu akan tampak sebagai bagian dari nilai awal dalam kontrol, tetapi tidak dapat dimodifikasi - sehingga akan tampak seperti sesuatu yang dipaksakan pada awal kontrol, tetapi belum akan dikirim sebagai bagian dari data formulir.

Jukka K. Korpela
sumber
3
Ini adalah komentar, bukan jawaban - komentar yang agak panjang, namun demikian komentar.
Blazemonger
@ Blazemonger, tidak terlalu jelas apa pertanyaannya, tetapi dalam hal apa pun, jawaban ini membahas masalah yang sama dengan jawaban yang diterima, tetapi dengan cara yang lebih benar. Bukan tidak mungkin untuk menggunakan konten yang dihasilkan untuk inputelemen, hanya tidak ditentukan dan tergantung pada browser.
Jukka K. Korpela
5

Seperti yang dijelaskan orang lain, inputs adalah elemen kosong yang diganti, sehingga sebagian besar browser tidak akan mengizinkan Anda untuk membuat ::beforeatau ::aftermemalsukan elemen di dalamnya.

Namun, Kelompok Kerja CSS sedang mempertimbangkan untuk secara eksplisit mengizinkan ::beforedan ::afterjika inputada appearance: none.

Dari https://lists.w3.org/Archives/Public/www-style/2016Mar/0190.html ,

Safari dan Chrome keduanya memungkinkan elemen semu pada input formulir mereka. Peramban lain tidak. Kami melihat ke menghapus ini, tetapi penghitung penggunaan merekam ~ .07% dari halaman menggunakannya, yaitu 20x ambang penghapusan maksimal kami.

Sebenarnya menentukan pseudo-elemen pada input akan membutuhkan menentukan struktur internal input setidaknya agak, yang kita belum berhasil lakukan (dan saya tidak yakin kita * dapat * melakukan). Tapi Boris menyarankan, di salah satu bugthreads, membiarkannya pada tampilan: tidak ada input - pada dasarnya hanya mengubahnya menjadi <div>, daripada elemen "agak diganti".

Oriol
sumber
4

coba selanjutnya:

label[for="userName"] {
  position: relative;
}

label[for="userName"]::after {
  content: '[after]';
  width: 22px;
  height: 22px;
  display: inline-block;
  position: absolute;
  right: -30px;
}
<label for="userName">
	Name: 
	<input type="text" name="userName" id="userName">
	</label>

Alex Ovchinkin
sumber
3

Anda harus memiliki semacam pembungkus di sekitar input untuk menggunakan elemen pseudo sebelum atau sesudah. Berikut biola yang memiliki sebelum pada pembungkus div dari input dan kemudian menempatkan sebelum di dalam input - atau setidaknya sepertinya itu. Jelas, ini adalah pekerjaan tetapi efektif dalam keadaan darurat dan cocok untuk menjadi responsif. Anda dapat dengan mudah membuat ini setelah Anda perlu menaruh beberapa konten lainnya.

Biola yang Bekerja

Dolar masuk ke dalam input sebagai elemen pseudo: http://jsfiddle.net/kapunahele/ose4r8uj/1/

HTML:

<div class="test">
    <input type="text"></input>
</div>

CSS:

input {
    margin: 3em;
    padding-left: 2em;
    padding-top: 1em;
    padding-bottom: 1em;
    width:20%; 
}


.test {
    position: relative;
    background-color: #dedede;
    display: inline;
}

.test:before {
    content: '$';
    position: absolute;
    top: 0;
    left: 40px;
    z-index: 1;
}
Kapunahele Wong
sumber
Trik yang bagus, tetapi Anda bisa membuat div dengan gaya untuk "melanjutkan" input. Lihat ini jsfiddle.net/ose4r8uj/31 biola Tapi Anda juga bisa melakukannya lebih mudah menggunakan bootstrap: getbootstrap.com/css/#forms-control-validation mencari bagian "Dengan ikon opsional". Meskipun demikian, ini tidak ada hubungannya dengan pertanyaan awal.
Victor Ivens
1
FYI tidak baik untuk: fokus
,:
2

Jika Anda mencoba mendesain elemen input dengan: sebelum dan: setelah, kemungkinan Anda mencoba untuk meniru efek span, div, atau bahkan elemen lain di stack CSS Anda.

Seperti yang ditunjukkan oleh jawaban Robert Koritnik,: sebelum dan: sesudah hanya dapat diterapkan pada elemen wadah dan elemen input bukan wadah.

NAMUN, HTML 5 memperkenalkan elemen tombol yang merupakan wadah dan berperilaku seperti elemen input [type = "submit | reset"].

    <style>
    .happy:after { content:url(smiley.gif); }
    </style>

    <form>
    <!-- won't work -->
    <input class="happy" type="submit" value="Submit" />

    <!-- works -->
    <button class="happy">Submit</button>
    </form>
Kevin Conroy
sumber
HTML 4 sebenarnya memperkenalkan elemen <button>.
Tn. Lister
1

Ringkasan

Itu tidak bekerja dengan <input type="button">, tetapi bekerja dengan baik <input type="checkbox">.

Fiddle : http://jsfiddle.net/gb2wY/50/

HTML :

<p class="submit">
    <input id="submit-button" type="submit" value="Post">
    <br><br>
    <input id="submit-cb" type="checkbox" checked>
</p>

CSS :

#submit-button::before,
#submit-cb::before {
    content: ' ';
    background: transparent;
    border: 3px solid crimson;
    display: inline-block;
    width: 100%;
    height: 100%;
    padding: 0;
    margin: -3px -3px;
}

sumber
1

:beforedan :afterhanya berfungsi untuk node yang dapat memiliki node anak karena mereka memasukkan simpul baru sebagai simpul pertama atau terakhir.

Juan Mendes
sumber
0

Saya menemukan bahwa Anda dapat melakukannya seperti ini:

Anda harus memiliki div induk yang mengambil bantalan dan: setelah. Orang tua pertama harus relatif dan div kedua harus absolut sehingga Anda dapat mengatur posisi setelahnya.

Patrick
sumber
-1

Saya punya ide lain untuk menggunakannya:

<div>
<input type="text"></input>text can be entered here</div>
Dima Dulin
sumber
Penulis pertanyaan secara eksplisit menyatakan bahwa mereka tidak dapat mengubah markup HTML. Jawaban ini tidak masuk akal. Mungkin ini seharusnya diturunkan daripada diedit, @Morpheus.
Palec