17

Just playing with :before and :after.

It seems I can't use them on/with an input button? Thought I could potentially use it do display an asterisk for required fields. Not necessarily what I will do, just an option

input {
    position: relative;
}
input:after {
    content: ''; 
    background: url(accept.png) 0 0 no-repeat; 
    height: 16px; 
    position: absolute; 
    right: -20px; 
    top: 5px; 
    width: 16px;
}

Same code works fine on an li

li {
    clear: both; 
    margin: 0 0 10px; 
    position: relative;
}
li:after {
    content: ''; 
    background: url(accept.png) 0 0 no-repeat; 
    height: 16px; 
    position: absolute; 
    right: -20px; 
    top: 5px; 
    width: 16px;   
}
JohnK
  • 6,865
  • 8
  • 49
  • 75
user508605
  • 261
  • 1
  • 3
  • 8

5 Answers5

16

I've also thought that the same thing would be useful, but alas, the simplest way I have been able to get the before/after pseudo elements to work reliably is by wrapping the input in a SPAN tag and applying a class to that.

This discussion provides some insight as to why input:after doesn't work: http://forums.mozillazine.org/viewtopic.php?f=25&t=291007&start=0&st=0&sk=t&sd=a

You can do something like:

.required:after {
    content: "REQUIRED";
    color: orange;
    margin-left: 1em; /* space between the input element and the text */
    padding: .1em;
    background-color: #fff;
    font-size: .8em;
    border: .1em solid orange;
}

<span class="required"><input id="foo" /></span>
Tim M.
  • 53,671
  • 14
  • 120
  • 163
7

An essentially identical question has been asked here that has a great explanation: https://stackoverflow.com/a/4660434/749227

To summarize, inputs are not containers and cannot have children. The content inserted by the :before and :after pseudo-elements normally can't therefore be inserted into inputs.

Note that rather than using <input type="submit|button"> you can use <button> which can have children, so for that input there's a 'workaround' (well, if you have control over the markup ;)

Community
  • 1
  • 1
jinglesthula
  • 4,446
  • 4
  • 45
  • 79
2

I just looked into the same thing - only I wanted to use it to display accesskeys:

*[accesskey]:after {
     content:' [' attr(accesskey) ']';
}

Not so keen on having to write the accesskey value more than one place cause that usually adds the risk of not keeping the values the same and that would be terible UE-wise =0/

aliceraunsbaek
  • 625
  • 7
  • 18
1

This answer (the text below the line) doesn't work (for text-based inputs anyway), but it's being left in situ on the off-chance it saves someone else the bother of trying to achieve the same end-result by the same means. The only way to do this is, as @Tim notes, in his answer, to wrap the input (or other) elements in another element, such as a span, and then style that with the :after pseudo-element.

JS Fiddle demo of a working example.


Um, they seem to work quite okay JS Fiddle demo, except that, without the position: absolute the :after content appears within the element itself (inside the buttons, or checkboxes and so on).

html:

<button class="req">button</button>
<input class="req" type="text" />
<input class="req" type="radio" />
<input class="req" type="checkbox" />
<textarea class="req"></textarea>

css:

input,
textarea {
    display: block;
}
.req {
    position: relative;
}

.req:after {
    content: "*";
    margin: 0 0 0 0.5em;
    position: absolute;
    top: 0;
    right: -1em;
}
Community
  • 1
  • 1
David Thomas
  • 249,100
  • 51
  • 377
  • 410
  • The asterisk only shows up for the button on Firefox 3.6 on my Mac, whether `position: absolute` is there or not. – BoltClock Dec 06 '10 at 19:02
  • @David - In Chrome 8, the two text elements do not have the pseudo element inserted after them in your JSFiddle demo. The other elements do. – Tim M. Dec 06 '10 at 19:04
  • @Tim, you're absolutely right (somehow I'd missed that...oops); @BoltClock, that behaviour's replicated in FF 3.6.12 on Win XP, too. Sigh. – David Thomas Dec 06 '10 at 19:10
  • Thanks for knocking that example together. A backgrounnd image only displays on the button, not input and textarea. Put this together: http://jsbin.com/unumo4/2 Am I missing anything obvious as to why it won't work on input? Appreciate it may not be possible but just covering all base's :) – user508605 Dec 06 '10 at 19:31
  • @user508605, I'm afraid I don't know why the text-based inputs won't accept the `:after` pseudo-class; I suspect it's either something to with the way they're rendered, or designed as some kind of security measure, but I honestly don't know. =/ – David Thomas Dec 06 '10 at 19:39
  • It's ok David, it's not your fault :) Some thing just aren't meant to be. For the time being I've used background image(s) on the fields. Works well. – user508605 Dec 06 '10 at 19:47
  • @David - you were able to show that it DOES work for checkboxes, buttons, and radio buttons (in Chrome, at least). I wasn't aware that any element worked. Maybe in the future there will be full support. – Tim M. Dec 06 '10 at 20:45
  • @Tim, you make a good point, thank you kindly! =) – David Thomas Dec 06 '10 at 21:18
  • @David Thomas, @Tim: This is why I hate the existence of different web browsers. – BoltClock Dec 06 '10 at 21:20
  • @BoltClock, but it *does* mean that there's alternatives to IE. Which has to be a good thing. Almost worth all the pain. – David Thomas Dec 06 '10 at 21:22
0

I needed to do this with inputs, but did not have access to change the html, which was generated by Wordpress and Jquery. Well, maybe I could but it would have been a long workaround. Same reason: accessibility.

So, one possible fix you can use:

#comment-form input[type=text],
#comment-form input[type=email],
#comment-form input[type=url],
#comment-form input[type=password] {
width:40%; margin-right:60%; }

If the error message comes after, it can no longer fit on same line & gets bumped. Of course you'd need to consider whether you can support percentage widths in your layout, but you get the idea.

Jen
  • 1,663
  • 1
  • 17
  • 34