Kann ich ein: vor oder: nach dem Pseudoelement in einem Eingabefeld verwenden?

685

Ich versuche, das :afterCSS-Pseudoelement für ein inputFeld zu verwenden, aber es funktioniert nicht. Wenn ich es mit a benutze span, funktioniert es OK.

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

Dies funktioniert (setzt den Smiley nach "buu!" Und vor "etwas mehr")

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

Dies funktioniert nicht - es färbt nur someValue in Rot, aber es gibt keinen Smiley.

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

Was mache ich falsch? soll ich einen anderen Pseudo-Selektor verwenden?

Hinweis: Ich kann keine spanum meine herum hinzufügen input, da diese von einem Steuerelement eines Drittanbieters generiert wird.

Matra
quelle
Wenn Sie absolut keine Kontrolle über HTML haben, versuchen Sie stattdessen, das border-colorvon zu ändern input. Ich finde es aufmerksamkeitsstarker.
Blazemonger

Antworten:

254

:afterund :beforewerden in Internet Explorer 7 und darunter für keine Elemente unterstützt.

Es ist auch nicht für ersetzte Elemente wie Formularelemente (Eingaben) und Bildelemente vorgesehen .

Mit anderen Worten, mit reinem CSS ist das unmöglich .

Wenn Sie jedoch jquery verwenden , können Sie verwenden

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

API-Dokumente auf .after

Zum Anhängen Ihrer Inhalte mit Javascript. Dies funktioniert in allen Browsern.

Alex
quelle
Alex, ich benutze IE8 und das neueste FF, also ist IE7 kein Problem. Ich suchte nach Unterlagen über die Einschränkung von: after, konnte sie aber nicht finden. w3.org/TR/CSS2/generate.html gibt an, dass es nach dem aktuellen Knoten im Dokumentbaum eingefügt wird, sodass es in beiden Fällen funktionieren sollte.
Matra
3
Sofern Sie die Seite nicht nur für Ihren eigenen Gebrauch erstellen, verwendet ein großer Prozentsatz des Internets diese Browser weiterhin. Die w3c-Spezifikation sagt dies ja; Wie Sie jedoch wissen, implementieren Browser ihre eigene Interpretation der Spezifikation. Die Verwendung von: after on a input funktioniert nur in Opera 9+, ist jedoch aufgrund der Art und Weise, wie das DOM intern erstellt wird, nicht in IE, FF, Safari oder Chrome implementiert. Auch dies ist mit reinem CSS nicht möglich.
Alex
3
Ich bin mir nicht sicher, ob dies im April der Fall war, aber Webkit unterstützt :afterim Allgemeinen, obwohl es weder :beforenoch :afterEingaben unterstützt.
Coreyward
258
Soweit ich W3C- :afterund :beforePseudo-Elemente verstehe , können sie nur auf Container-Elemente gesetzt werden. Warum? Weil sie innerhalb dieses bestimmten Elements angehängt werden . inputist kein Container. buttonZum Beispiel können Sie sie daher anziehen. Funktioniert wie erwartet. Die Spezifikation sagt tatsächlich: vor und nach dem Dokumentbauminhalt eines Elements. Sie sagt ausdrücklich INHALT . Ein Element muss also ein Container sein.
Robert Koritnik
29
Die nächste Antwort ist viel besser. Gibt den tatsächlichen Grund an, anstatt über IE 7 (wen interessiert das) und jQuery (schlechte Idee)
Rowan
1304

:beforeund :afterin einem Container rendern

und <Eingabe> darf keine anderen Elemente enthalten.


Pseudoelemente können nur auf Containerelementen definiert werden (oder besser gesagt nur unterstützt werden). Weil die Art und Weise, wie sie gerendert werden, als untergeordnetes Element im Container selbst liegt. inputkann keine anderen Elemente enthalten, daher werden sie nicht unterstützt. Ein buttonFormularelement, das auch ein Formularelement ist, unterstützt sie, da es sich um einen Container mit anderen Unterelementen handelt.

Wenn Sie mich fragen, ob einige Browser tut diese beiden Pseudo-Elemente auf Nicht-Container - Elemente angezeigt werden , ist es ein Fehler und ein Nicht-Standard - Konformität. Die Spezifikation spricht direkt über den Elementinhalt ...

W3C-Spezifikation

Wenn wir die Spezifikation sorgfältig lesen, heißt es tatsächlich, dass sie in ein enthaltendes Element eingefügt werden :

Autoren geben den Stil und die Position des generierten Inhalts mit den Pseudoelementen: before und: after an. Wie ihre Namen anzeigen, geben die Pseudoelemente: before und: after den Speicherort des Inhalts vor und nach dem Dokumentbauminhalt eines Elements an. Die Eigenschaft 'content' gibt in Verbindung mit diesen Pseudoelementen an, was eingefügt wird.

Sehen? ein Dokumentenbaum des Elements Inhalt . So wie ich es verstehe, bedeutet dies innerhalb eines Containers.

Robert Koritnik
quelle
119
+1 Viel besser als die akzeptierte Antwort. Vielen Dank für die klare Erklärung des Standards. Soviel zu [required]::before { content "*"; color: red; }: P
Kevin Peno
93
Tipp: Wenn Sie das Problem nur mit einer Übermittlungseingabe wie haben <input type="submit" value="Send"/>, verwenden Sie <button type="submit">Send</button>stattdessen. Die Präsentation ist identisch, aber das <button>ist ein Container und unterstützt :beforeund :after.
Grippe
15
Was ist mit <hr />? Ich dachte, es sei kein Containerelement, aber es könnte rendern :afterund :before jsfiddle.net/Uf88j/1
Deathlock
7
@deathlock: das ist ja interessant. Ich würde sagen, es muss eine Art Anomalie sein und ich würde mich nicht darauf verlassen, dass es browserübergreifend oder versionübergreifend funktioniert ... HR ist kein Containerelement, daher sollten keine Pseudoelemente berücksichtigt werden. Selbst der W3C-Standard sagt, dass er keinen Inhalt zulässt . Und wenn Sie nach ungültigen Elementen suchen, können Sie sehen, dass diese Elemente unter keinen Umständen Inhalt haben sollten. Pseudoelemente sind Inhalte. Erwarten Sie daher, dass die zukünftige Browserversion sie nicht anzeigt.
Robert Koritnik
5
" : vor und: nach dem Rendern in einem Container " Die: vor und: nach Pseudoelemente kommen " vor und nach dem Inhalt ". Nicht "am Anfang oder Ende" des Containers. In der Spezifikation wird kein Container erwähnt . Bei Tags wie pund h1befindet sich der Inhalt innerhalb des Tags, sodass auch Vorher / Nachher im Tag angezeigt wird. Mit Elementen wie inputund hr,: vor und: nach würde immer noch vor oder nach dem Inhalt erscheinen, aber es ist kein Container beteiligt (speziell für input). Eingabe: markiert: Vorher wird häufig verwendet, um Kontrollkästchen anzuzeigen, die über CSS aktiviert werden.
Radley Sustaire
60

Seltsamerweise funktioniert es mit einigen Arten von Eingaben. Zumindest in Chrome,

<input type="checkbox" />

funktioniert gut, genauso wie

<input type="radio" />

Es ist nur type=textund einige andere, die nicht funktionieren.

vals
quelle
1
@ ANeves, es hat bei mir in Chrom funktioniert, aber nicht in Firefox.
kcpr
45

Hier ist ein anderer Ansatz (vorausgesetzt, Sie haben die Kontrolle über den HTML-Code): Fügen Sie <span></span>direkt nach der Eingabe ein Leerzeichen hinzu und zielen Sie darauf ab, dass in 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>

Ich verwende diesen Ansatz in AngularJS, da .ng-invalidKlassen automatisch zu <input>Formularelementen und zum Formular hinzugefügt werden , nicht jedoch zum <label>.

Blazemonger
quelle
1
Es ermöglicht das Hinzufügen von Hover-Aktionen wie : input:hover+span:after{color: blue}. Upvote.
Krassowski
2
Warum hat diese Antwort so wenige positive Stimmen? Ich denke, theoretisches Wissen ist wichtig, aber das löst das Problem.
Jorgefpastor
Gute Option, um das Problem zu lösen.
Narr
39

:beforeund :afterwerden in einem Container angewendet, dh Sie können ihn für Elemente mit einem End-Tag verwenden.

Dies gilt nicht für selbstschließende Elemente.

Nebenbei bemerkt, Elemente, die sich selbst schließen (wie z. B. img / hr / input), werden auch als "Ersetzte Elemente" bezeichnet, da sie durch ihren jeweiligen Inhalt ersetzt werden. "Externe Objekte" für das Fehlen eines besseren Begriffs. Eine bessere Lektüre hier

CatalinBerta
quelle
Diese Antwort ist richtig, präzise und bietet einen wichtigen Kontext. Sollte oben sein, imo.
Paul
31

Ich habe das verwendet background-image, um den roten Punkt für die erforderlichen Felder zu erstellen.

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

Blick auf Codepen

Veiko Jääger
quelle
20

Sie können kein Pseudoelement in ein Eingabeelement einfügen, sondern ein Schattenelement wie einen Platzhalter!

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

Um es in anderen Browsern verwenden arbeiten :-moz-placeholder, ::-moz-placeholderund :-ms-input-placeholder in verschiedenen Selektoren . Die Selektoren können nicht gruppiert werden, da der Selektor die gesamte Anweisung ungültig macht, wenn ein Browser sie nicht erkennt.

UPDATE : Der obige Code funktioniert nur mit CSS-Vorprozessoren (SASS, WENIGER ...), ohne dass Vorprozessoren Folgendes verwenden:

input[type="text"]::-webkit-input-placeholder:before { // your code }
Shankar Cabus
quelle
3
Nett! Beachten Sie, dass das Platzhalter-Pseudoelement nur eine begrenzte Eigenschaftsunterstützung bietet: Farbe, Hintergrund, Wortabstand, Buchstabenabstand, Textdekoration, vertikale Ausrichtung, Texttransformation, Zeilenhöhe, Texteinzug, Deckkraft. Siehe css-tricks.com/almanac/selectors/p/placeholder
henry
Danke für den Tipp. Denken Sie daran, dass alles im Pseudoelement verschwindet, wenn das Eingabefeld vom Benutzer ausgefüllt wird. Das ist ein UX-Problem, wenn Sie wie ich nur ein glyphicon-searchMarkup anzeigen wollten, ohne es zu berühren.
Davi Lima
2
Einige Zusammenhänge, warum dies nicht mehr funktioniert: bugs.chromium.org/p/chromium/issues/detail?id=582301
Oliver Joseph Ash
17

Pseudoelemente wie :after, :beforesind nur für Containerelemente. Elemente, die an einer einzelnen Stelle wie usw. beginnen und schließen <input/>, <img>sind keine Containerelemente, und daher werden Pseudoelemente nicht unterstützt. Wenn Sie ein Pseudoelement auf ein Containerelement wie anwenden <div>und den Code überprüfen (siehe Bild), können Sie verstehen, was ich meine. Tatsächlich wird das Pseudoelement innerhalb des Containerelements erstellt. Dies ist bei <input>oder nicht möglich<img>

Geben Sie hier die Bildbeschreibung ein

Pons Purushothaman
quelle
15

Eine funktionierende Lösung in reinem CSS:

Der Trick besteht darin, anzunehmen, dass nach dem Textfeld ein dom-Element steht.

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

(*) Begrenzte Lösung:

  • Sie müssen hoffen, dass es ein folgendes dom-Element gibt:
  • Sie müssen hoffen, dass kein anderes Eingabefeld Ihrem Eingabefeld folgt.

In den meisten Fällen kennen wir unseren Code, sodass diese Lösung effizient und zu 100% aus CSS und zu 0% aus jQuery besteht.


quelle
2
input#myTextField ~ span:before {viel besser, aber span sollte eine Klasse haben, um wirklich expliziter zu sein wie .tickoder.icon
Val
13

Ich fand diesen Beitrag, da ich das gleiche Problem hatte. Dies war die Lösung, die für mich funktioniert hat. Im Gegensatz zum Ersetzen des Eingabewerts entfernen Sie ihn einfach und positionieren absolut einen Bereich dahinter, der dieselbe Größe hat. Auf den Bereich kann eine :beforePseudoklasse mit der Symbolschrift Ihrer Wahl angewendet werden.

<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
quelle
1
+1 - Diese Lösung funktioniert gut, wenn Sie ein Plugin oder Framework verwenden, das dem Element selbst automatisch Validierungsklassen hinzufügt, nicht jedoch der übergeordneten Bezeichnung.
Blazemonger
9

Das größte Missverständnis hier ist die Bedeutung der Wörter beforeund after. Sie beziehen sich nicht auf das Element selbst, sondern auf den Inhalt des Elements. Ist element:beforealso vor dem Inhalt und element:afterist nach dem Inhalt, aber beide befinden sich immer noch im ursprünglichen Element.

Das inputElement hat keinen Inhalt in der CSS-Ansicht und daher keinen :beforeoder :afterPseudoinhalt. Dies gilt für viele andere leere oder ersetzte Elemente.

Es gibt kein Pseudoelement, das sich außerhalb des Elements bezieht .

In einem anderen Universum könnten diese Pseudoelemente etwas anderes genannt worden sein, um diese Unterscheidung klarer zu machen. Und vielleicht hat jemand sogar ein Pseudoelement vorgeschlagen, das wirklich außerhalb des Elements liegt. Bisher ist dies in diesem Universum nicht der Fall.

Manngo
quelle
Ich verstehe vielleicht nicht, was du meinst, aber wenn ich das tue, funktionieren Pseudoelemente auf hr? jsfiddle.net/demetriad/o49yn5hq
Chris
1
@ Chris Das überrascht mich und einige andere beim Suchen. Ich denke, das ist eine Eigenart. hrwar aus CSS-Sicht immer mehrdeutig, obwohl Sie dies eher in der Diskussion über Farben sehen.
Manngo
5

Gemäß einem Hinweis in der CSS 2.1-Spezifikation definiert die Spezifikation „die Interaktion von: vorher und: nachher mit ersetzten Elementen (wie IMG in HTML) nicht vollständig. Dies wird in einer zukünftigen Spezifikation genauer definiert. “ Obwohl inputes sich nicht mehr wirklich um ein ersetztes Element handelt, hat sich die Grundsituation nicht geändert: Die Auswirkung von :beforeund :afterauf sie ist nicht spezifiziert und hat im Allgemeinen keine Auswirkung.

Die Lösung besteht darin, einen anderen Ansatz für das Problem zu finden, das Sie auf diese Weise angehen möchten. Das Einfügen von generiertem Inhalt in ein Texteingabesteuerelement wäre sehr irreführend: Für den Benutzer scheint es Teil des Anfangswertes im Steuerelement zu sein, es kann jedoch nicht geändert werden. Es scheint also etwas zu sein, das zu Beginn des Steuerelements erzwungen wurde Kontrolle, aber es würde nicht als Teil der Formulardaten übermittelt.

Jukka K. Korpela
quelle
3
Dies ist ein Kommentar, keine Antwort - ein ziemlich langer Kommentar, aber dennoch ein Kommentar.
Blazemonger
@Blazemonger, es ist nicht ganz klar, was die Frage war, aber auf jeden Fall behandelt diese Antwort das gleiche Problem wie die akzeptierte Antwort, aber auf korrektere Weise. Es ist nicht unmöglich , generierten Inhalt für inputElemente zu verwenden, nur nicht spezifiziert und browserabhängig.
Jukka K. Korpela
5

Wie andere erklärt, inputsind s irgendwie-ersetzt Leere Elemente, so werden die meisten Browser erlauben nicht , dass Sie zu generieren ::beforenoch ::afterpseudo-Elemente in ihnen.

Allerdings ist die CSS - Arbeitsgruppe unter Berücksichtigung ausdrücklich erlaubt ::beforeund ::afterfalls das inputhat appearance: none.

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

Safari und Chrome erlauben beide Pseudoelemente in ihren Formulareingaben. Andere Browser tun dies nicht. Wir haben versucht, dies zu entfernen, aber der Verwendungszähler zeichnet ~ 0,07% der Seiten auf, die ihn verwenden, was dem 20-fachen unserer maximalen Entfernungsschwelle entspricht.

Um Pseudoelemente für Eingaben zu spezifizieren, müsste die interne Struktur der Eingaben zumindest etwas spezifiziert werden, was wir noch nicht geschafft haben (und ich bin nicht sicher, ob wir das können). Aber Boris schlug in einem der Bugthreads vor, es beim Erscheinen zuzulassen: Keine Eingaben - im Grunde genommen werden sie nur in <div> s umgewandelt, anstatt "irgendwie ersetzte" Elemente.

Oriol
quelle
4

versuchen Sie es als nächstes:

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

Sie müssen eine Art Wrapper um die Eingabe haben, um ein Vorher- oder Nachher-Pseudoelement zu verwenden. Hier ist eine Geige, die ein Vorher auf dem Wrapper-Div einer Eingabe hat und dann das Vorher in die Eingabe einfügt - oder zumindest so aussieht. Offensichtlich ist dies eine Problemumgehung, aber zur Not effektiv und eignet sich für die Reaktion. Sie können dies leicht zu einem After machen, wenn Sie andere Inhalte einfügen müssen.

Geige arbeiten

Dollarzeichen in einer Eingabe als Pseudoelement : http://jsfiddle.net/kapunahele/ose4r8uj/1/

Der HTML:

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

Das 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
quelle
Netter Trick, aber Sie könnten ein Div stilisieren, um die Eingabe "fortzusetzen". Siehe diese Geige jsfiddle.net/ose4r8uj/31 Sie können es aber auch einfacher mit bootstrap machen: getbootstrap.com/css/#forms-control-validation Suchen Sie nach dem Teil "Mit optionalen Symbolen ". Dies hat jedoch nichts mit der ursprünglichen Frage zu tun.
Victor Ivens
1
Zu
Ihrer Information,
2

Wenn Sie versuchen, ein Eingabeelement mit: vor und: nach zu formatieren, versuchen Sie wahrscheinlich, die Auswirkungen anderer Bereiche, Bereiche oder sogar Elemente in Ihrem CSS-Stapel nachzuahmen.

In der Antwort von Robert Koritnik heißt es: Vorher und Nachher können nur auf Containerelemente angewendet werden, und Eingabeelemente sind keine Container.

In HTML 5 wurde jedoch das Schaltflächenelement eingeführt , das ein Container ist und sich wie ein Eingabeelement [type = "submit | reset"] verhält.

    <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
quelle
In HTML 4 wurde das <button> -Element eingeführt.
Herr Lister
1

Zusammenfassung

Es funktioniert nicht mit <input type="button">, aber es funktioniert gut mit <input type="checkbox">.

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

quelle
1

:beforeund :afterfunktioniert nur für Knoten, die untergeordnete Knoten haben können, da sie einen neuen Knoten als ersten oder letzten Knoten einfügen.

Juan Mendes
quelle
0

Ich habe festgestellt, dass Sie es so machen können:

Sie benötigen ein div-Elternteil, das die Auffüllung und das: after übernimmt. Das erste übergeordnete Element muss relativ sein und das zweite div sollte absolut sein, damit Sie die Position des After festlegen können.

Patrick
quelle
-1

Ich habe eine andere Idee, stattdessen dies zu verwenden:

<div>
<input type="text"></input>text can be entered here</div>
Dima Dulin
quelle
Der Autor der Frage gab ausdrücklich an, dass er das HTML-Markup nicht ändern kann. Diese Antwort macht keinen Sinn. Wahrscheinlich hätte es heruntergestuft anstatt bearbeitet werden sollen, @Morpheus.
Palec