Giriş alanında a: before veya: after sözde elemanı kullanabilir miyim?


686

:afterBir inputalanda CSS sözde öğesi kullanmaya çalışıyorum , ama çalışmıyor. A ile kullanırsam span, sorun olmaz.

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

Bu işe yarar (suratı "buu!" Ve "biraz daha" önce koyar)

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

Bu işe yaramaz - sadece bazı renkleri renklendirirKırmızıyla değer, ancak gülen yüz yok.

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

Neyi yanlış yapıyorum? başka bir sözde seçici kullanmalı mıyım?

Not: Bir ekleyemezsiniz spanbenim etrafında inputbir üçüncü taraf denetimi tarafından oluşturuluyor çünkü.


HTML üzerinde kesinlikle kontrolünüz border-coloryoksa inputbunun yerine değiştirmeyi deneyin . Daha dikkat çekici buluyorum.
Blazemonger

Yanıtlar:


255

:afterve :beforehiçbir öğede Internet Explorer 7 ve altında desteklenmez.

Ayrıca form öğeleri (girişler) ve görüntü öğeleri gibi değiştirilmiş öğeler üzerinde kullanılması amaçlanmamıştır .

Başka bir deyişle , saf CSS ile imkansız .

Ancak jquery kullanıyorsanız kullanabilirsiniz

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

API sonrası .after

İçeriğinizi javascript ile eklemek için. Bu, tüm tarayıcılarda çalışır.


Alex, IE8 ve en son FF kullanıyorum, bu yüzden IE7 bir sorun değil. Aşağıdakilerle ilgili herhangi bir dokümantasyon için seraching yapıyordum: after, ancak bulamadım. w3.org/TR/CSS2/generate.html , belge ağacındaki geçerli düğümden sonra eklendiğini ve her iki durumda da çalışması gerektiğini belirtir.
matra

3
Eğer sayfayı sadece kendi kullanımınız için inşa etmedikçe, internetin büyük bir yüzdesi bu tarayıcıları hala kullanır. W3c spec bu evet diyor; ancak bildiğiniz gibi, tarayıcılar spesifikasyona ilişkin kendi yorumlarını uygularlar. Kullanımı: bir girişten sonra sadece Opera 9+ 'da çalışır, ancak DOM'u dahili olarak inşa etme şekilleri nedeniyle IE, FF, safari veya kromda uygulanmaz - yine saf CSS ile yapılamaz.
Alex

3
Nisan ayında durumun böyle olup olmadığından emin değilim, ancak Webkit :aftergenel olarak destekliyor , ancak girişleri :beforeveya :aftergirişleri desteklemiyor .
coreyward

258
W3C :afterve :beforesözde unsurları anladığım kadarıyla , sadece konteyner elemanlarına konabilirler. Neden? Çünkü o elementin içine eklenmişlerdir . inputbir kap değil. buttonmesela onları giyebilirsiniz. Beklendiği gibi çalışır. Spesifikasyon aslında şunu söylüyor: Bir öğenin belge ağacı içeriğinden önce ve sonra Açıkça CONTENT diyor . Öyleyse bir eleman bir kap olmalıdır.
Robert Koritnik

29
Bir sonraki cevap çok daha iyi .. IE 7 (kimin umurunda) ve jQuery (kötü fikir) hakkında konuşmak yerine gerçek bir sebep verir
Rowan

1305

:beforeve :afterbir kabın içinde

ve <input> başka öğeler içeremez.


Sözde elemanlar sadece konteyner elemanlarında tanımlanabilir (ya da daha iyisi daha iyi söylenebilir). Çünkü işlenme biçimleri içinde bir alt öğesi olarak kabın kendisi. inputbaşka öğeler içeremez, bu nedenle desteklenmez. Bir buttondiğer alt unsurların bir konteyner çünkü var diğer taraftan da bir form öğesi, onları destekliyor.

Bazı tarayıcı verirsem beni sorarsanız yapar dışı konteyner elemanlarında bu iki sözde öğeleri görüntülemek, bu bir hata ve standart olmayan bir uygunluk var. Şartname doğrudan eleman içeriği hakkında konuşuyor ...

W3C özellikleri

Spesifikasyonu dikkatlice okursak , aslında içeriye yerleştirildiklerini söyler bir elementin :

Yazarlar oluşturulan içeriğin stilini ve konumunu: before ve: after sözde elemanlarıyla belirtirler. Adlarının da belirttiği gibi,: before ve: after sözde öğeleri, bir öğenin belge ağacı içeriğinden önceki ve sonraki içeriğin konumunu belirtir. 'Pseudo-elements ile birlikte' content 'özelliği, eklenenleri belirtir.

Görmek? bir öğenin belge ağacı içeriği . Anladığım kadarıyla bu bir kap içinde anlamına gelir .


119
+1 Kabul edilen cevaptan çok daha iyi. Standardın kendisinin net açıklaması için teşekkürler. [required]::before { content "*"; color: red; }
Şunun

93
İpucu: Eğer sadece bir gibi girdi göndermek ile sorun yaşıyorsanız <input type="submit" value="Send"/>, kullanmak <button type="submit">Send</button>yerine. Sunum aynıdır, ancak <button>bir kap olup, böylece destek :beforeve :after.
grip

15
Ne olmuş <hr />? Bir kap öğesi olmadığını düşündüm, ancak oluşturabilir :afterve :before jsfiddle.net/Uf88j/1
deathlock

7
@deathlock: bu gerçekten ilginç. Ben bir tür bir anomali olmalı ve çapraz tarayıcı veya çapraz sürümleri çalışma güvenmek olmaz söyleyebilirim ... İK bir konteyner öğesi değildir, bu nedenle sözde öğeleri için izin vermemelidir. Hatta W3C standardı o izin verdiğini söylüyor hiçbir içerik. Ve void elemanını kontrol ederseniz , bu elemanların hiçbir koşulda herhangi bir içeriğe sahip olmaması gerektiğini görebilirsiniz . Sözde öğeler içeriktir, bu nedenle gelecekteki tarayıcı sürümünün bunları gösterememesini bekleyin.
Robert Koritnik

5
" : before ve: after bir container içinde render ":: before ve: after sözde elemanları " içerikten önce ve sonra " gelir. Konteynerin "başında veya sonunda" değil. Teknik özellik bir kaptan bahsetmiyor . Gibi etiketlerle pve h1içerik etiketi içinde, yani önce / sonra hem içeride görünür olduğunu. Gibi unsurlarla inputve hr,: before ve: hala içerikten önce veya sonra görünür, ancak (özellikle Vesait konteyneri mevcut olur sonra input). giriş: işaretli: önce, css yoluyla denetlenen onay kutularını belirtmek için yaygın olarak kullanılır.
Radley Sustaire

60

Garip bir şekilde, bazı girdi türleri ile çalışır. En azından Chrome'da,

<input type="checkbox" />

ile iyi çalışır

<input type="radio" />

Sadece type=textve bazıları işe yaramaz.


1
@Aneves, Chromium'da benim için çalıştı, ancak Firefox'ta çalışmadı.
kcpr

45

İşte başka bir yaklaşım (HTML üzerinde kontrolünüz olduğu varsayılarak): <span></span>girişten hemen sonra boş bir boşluk ekleyin ve bunu kullanarak CSS'de hedefleyininput.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>

AngularJS bu yaklaşımı kullanıyorum çünkü .ng-invalidotomatik olarak <input>form öğelerine ve forma sınıfları ekleyecek , ancak <label>.


1
Sanki, vurgulu eylemler eklemenizi sağlar: input:hover+span:after{color: blue}. Oyla.
krassowski

2
Bu cevabın neden bu kadar az oyu var? Teorik bilginin önemli olduğunu düşünüyorum, ama bu sorunu çözüyor.
jorgefpastor

Sorunu çözmek için gitmek için güzel bir seçenek.
Soytarı

39

:beforeve :afterbir kabın içine uygulanır, yani bir bitiş etiketi olan öğeler için kullanabilirsiniz.

Kendiliğinden kapanan elemanlar için geçerli değildir.

Yan notta, kendiliğinden kapanan elemanlar (img / hr / input gibi) ilgili içerikleriyle değiştirildikleri için 'Değiştirilen Öğeler' olarak da bilinir. Daha iyi bir terim olmaması nedeniyle "Dış Nesneler". Daha iyi bir okuma burada


Bu cevap doğru, özlü ve önemli bir bağlam sağlıyor. Üstte olmalı, imo.
Paul

32

background-imageGerekli alanlar için kırmızı nokta oluşturmak için kullandım .

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

Codepen'de görüntüle


20

Bir giriş öğesine sahte bir öğe koyamazsınız, ancak bir yer tutucu gibi gölge öğeyi koyabilirsiniz!

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

Diğer tarayıcılarda, kullanımda çalışmasını sağlamak için :-moz-placeholder, ::-moz-placeholderve :-ms-input-placeholder farklı seçicileri içinde . Seçiciler gruplandırılamıyor, çünkü bir tarayıcı seçiciyi tanımazsa ifadenin tamamını geçersiz kılar.

GÜNCELLEME : Yukarıdaki kod, ön işlemciler kullanmadan yalnızca CSS ön işlemcisi (SASS, LESS ...) ile çalışır:

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

3
Güzel! Yer tutucu sözde öğesinin sınırlı özellik desteğine sahip olduğunu unutmayın: renk, arka plan, sözcük aralığı, harf aralığı, metin süslemesi, dikey hizalama, metin dönüşümü, satır yüksekliği, metin girintisi, opaklık. Bkz. Css-tricks.com/almanac/selectors/p/placeholder
henry

İpucu için teşekkürler. Giriş kutusu kullanıcı tarafından doldurulduğunda sözde öğenin içindeki her şeyin kaybolacağını unutmayın. Benim gibi istediğin tek şey glyphicon-searchişaretlemeye dokunmadan görüntüleniyorsa bu bir UX problemi .
Davi Lima

2
Bunun neden işe yaramadığına
Oliver Joseph Ash

17

Pseudo elements, gibi :after, :beforesadece konteyner elemanları içindir. Başlangıç ve benzerleri gibi tek bir yerde, kapama elemanları <input/>, <img>vb muhafaza elemanı ve bu nedenle sahte öğeleri desteklenmez değildir. Bir konteyner elemanına sözde eleman uyguladığınızda <div>ve kodu incelerseniz (resme bakın) ne demek istediğimi anlayabilirsiniz. Aslında sözde öğe, konteyner öğesinin içinde oluşturulur. Bu <input>veya<img>

resim açıklamasını buraya girin


15

Saf CSS'de çalışan bir çözüm:

İşin püf noktası, metin alanından sonra bir dom öğesi olduğunu varsayalım.

/*
 * 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>

(*) Sınırlı çözüm olsa da:

  • aşağıdaki dom öğesinin olduğunu ummak zorundasınız,
  • giriş alanınızdan başka bir girdi alanı gelmediğini ummalısınız.

Ancak çoğu durumda, kodumuzu biliyoruz, bu nedenle bu çözüm verimli ve% 100 CSS ve% 0 jQuery görünüyor.


2
input#myTextField ~ span:before {çok daha iyi, ama span gerçekten daha açık olması için bir sınıfa sahip olmalıdır .tickveya.icon
Val

13

Bu konuyu aynı sorunu yaşadığım için buldum, bu benim için işe yarayan çözümdü. Girişin değerini değiştirmenin aksine, sadece onu kaldırın ve kesinlikle aynı boyutta bir açıklık yerleştirin, yayılma :beforealanı, seçtiğiniz simge yazı tipiyle uygulanan bir sözde sınıfa sahip olabilir .

<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>

1
+1 - Bu çözüm, öğenin kendisine otomatik olarak doğrulama sınıfları ekleyen ancak üst etikete eklemeyen bir eklenti veya çerçeve kullanıyorsanız iyi çalışır.
Blazemonger

9

Buradaki en büyük yanlış anlama kelimelerin anlamı beforeve after. Onlar do değil elemanın kendisi bakın, bunlarla içerik öğesi. Yani element:beforeiçerikten önce ve içerikten element:aftersonra, ama her ikisi de hala orijinal öğenin içinde.

inputÖğesi CSS görünümde bir içeriğine sahiptir ve böylece herhangi bir yer alır :beforeya da :afterpsödo içeriği. Bu, diğer birçok boşluk veya değiştirilmiş eleman için geçerlidir.

Öğenin dışına atıfta bulunan bir sözde öğe yoktur .

Farklı bir evrende, bu sözde unsurlara bu ayrımı daha net hale getirmek için başka bir şey denmiş olabilir. Ve birisi gerçekten de öğenin dışında olan bir sahte öğe bile önerebilirdi. Şimdiye kadar, bu evrende durum böyle değil.


Ne demek istediğini anlamayabilirim ama eğer yaparsam, sözde öğeler saat üzerinde çalışır? jsfiddle.net/demetriad/o49yn5hq
Chris

1
@Chris Bu benim için ve arama yaparken başkalarına bir sürpriz olarak geliyor. Bence bu bir tuhaflık. hrdaha çok rengi tartışırken görseniz de, CSS açısından her zaman belirsiz olmuştur.
Manngo

5

CSS 2.1 spesifikasyonundaki bir nota göre , “spesifikasyon: ile değiştirilen elemanlarla (öncesi ve sonrası) etkileşimini tam olarak tanımlamaz (HTML'deki IMG gibi). Bu, gelecekteki bir spesifikasyonda daha ayrıntılı olarak tanımlanacaktır. ” Her ne kadar inputgerçekten artık temel durum değişmemiştir bir yerini öğesi değil: etkisi :beforeve :aftergenel olarak belirtilmemiş bunun üzerine ve hiçbir etkisi olmaz.

Çözüm, bu şekilde çözmeye çalıştığınız soruna farklı bir yaklaşım bulmaktır. Oluşturulan içeriği bir metin giriş kontrolüne koymak çok yanıltıcı olacaktır: kullanıcıya, kontroldeki başlangıç ​​değerinin bir parçası gibi görünecektir, ancak değiştirilemez - bu nedenle, ancak form verilerinin bir parçası olarak gönderilmez.


3
Bu bir yorum, cevap değil - oldukça uzun bir yorum ama yine de bir yorum.
Blazemonger

@Blazemonger, sorunun ne olduğu tam olarak belli değil, ancak her durumda, bu cevap kabul edilen cevapla aynı sorunu ele alıyor, ancak daha doğru bir şekilde. Oluşturulan içeriği öğeler için kullanmak imkansız değil input, sadece belirtilmemiş ve tarayıcıya bağlı.
Jukka K. Korpela

5

Diğerlerinin açıkladığı gibi, inputs, biraz değiştirilmiş geçersiz öğelerdir, bu nedenle çoğu tarayıcı, ::beforene ::afteronları ne de sahte öğeleri oluşturmanıza izin vermez .

Ancak, CSS Çalışma Grubu açıkça dikkate izin veriyor ::beforeve ::afterbu durumda inputbulunmaktadır appearance: none.

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

Safari ve Chrome, form girişlerinde sözde öğelere izin verir. Diğer tarayıcılarda yoktur. Bunu kaldırmaya baktık, ancak kullanım sayacı, maksimum kaldırma eşiğimizin 20 katı olan bunu kullanan sayfaların ~% 0,07'sini kaydediyor.

Aslında girişler üzerinde sözde elemanların belirtilmesi, girişlerin iç yapısının en azından bir şekilde belirtilmesini gerektirecektir, ki henüz yapmayı başaramadık (ve * yapabileceğimizden emin değilim). Ancak Boris, bugthreads'den birinde, görünüme izin verdiğini öne sürdü: hiçbir girdi - temelde onları "tür değiştirildi" öğeleri yerine <div> s haline getiriyor.


4

sonra dene:

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>


3

Yalancı öğeden önce ya da sonra kullanmak için girdinin etrafında bir tür sarıcı olması gerekir. İşte bir girdinin sarıcı divında daha önce olan ve daha önce girişi girdinin içine yerleştiren bir keman - veya en azından ona benziyor. Açıkçası, bu bir çalışmadır ama bir çimdik içinde etkilidir ve cevap vermeye kendini verir. Başka bir içerik koymanız gerekiyorsa bunu kolayca yapabilirsiniz.

Çalışma keman

Bir sözde eleman olarak bir girdinin içindeki dolar işareti: 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;
}

Güzel hile, ama giriş "devam" stilize bir div yapabilirsiniz. Bu keman jsfiddle.net/ose4r8uj/31 bakın Ancak bootstrap kullanarak bunu daha kolay yapabilirsiniz: getbootstrap.com/css/#forms-control-validation "İsteğe bağlı simgelerle" bölümünü arayın. Yine de, bunun orijinal soru ile ilgisi yoktur.
Victor Ivens

1
Bilginize iyi için: odak,: Üst elemanı vurgulu vb girişinin hedef olamaz çünkü
jordanb

2

Bir giriş öğesini şu şekilde stilize etmeye çalışıyorsanız: before ve: after, olasılıklar diğer yayılma, div ve hatta CSS yığınınızdaki öğelerin etkilerini taklit etmeye çalışıyorsunuzdur .

Robert Koritnik'in cevabının işaret ettiği gibi: önce ve: sonra sadece konteyner elemanlarına uygulanabilir ve giriş elemanları konteyner değildir.

ANCAK HTML 5 , bir kap olan ve girdi [type = "gönder | sıfırla"] elemanı gibi davranan düğme elemanını tanıttı .

    <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>

HTML 4 aslında <düğmesi> öğesini tanıttı.
Bay Lister

1

özet

İle çalışmıyor <input type="button">, ama iyi çalışıyor <input type="checkbox">.

Keman : 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;
}

1

:beforeve :afteryalnızca ilk veya son düğüm olarak yeni bir düğüm ekledikleri için alt düğümleri olabilen düğümler için çalışır.


0

Bunu böyle yapabileceğinizi buldum:

Dolguyu alan bir div ebeveyniniz ve: after olması gerekir. İlk ebeveynin göreli olması ve ikinci div'in mutlak olması gerekir, böylece sonrakinin konumunu ayarlayabilirsiniz.


-1

Bunun yerine başka bir fikrim var:

<div>
<input type="text"></input>text can be entered here</div>

Sorunun yazarı, HTML işaretlemesini değiştiremediklerini açıkça belirtti. Bu cevap mantıklı değil. Muhtemelen, @Morpheus yerine düzenlenmesi gerekiyordu.
Palec
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.