129

I would like to have a text input field containing the "$" sign in the very beginning, and no matter what editing occurs to the field, for the sign to be persistent.

I would be good if only numbers were accepted for input, but that's just a fancy addition.

halfer
  • 19,824
  • 17
  • 99
  • 186
User3419
  • 1,716
  • 2
  • 14
  • 16

17 Answers17

117

Consider simulating an input field with a fixed prefix or suffix using a span with a border around a borderless input field. Here's a basic kickoff example:

.currencyinput {
    border: 1px inset #ccc;
}
.currencyinput input {
    border: 0;
}
<span class="currencyinput">$<input type="text" name="currency"></span>
Carlos Muñoz
  • 17,397
  • 7
  • 55
  • 80
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • 16
    additionally you could wrap the '$' inside a – Cohen Nov 20 '12 at 18:32
  • 2
    @Cohen Although a good idea, having more than one label [may cause problems with accessibility](http://stackoverflow.com/a/3992160/1094772). – rybo111 Sep 12 '15 at 11:06
85

Use a parent .input-icon div. Optionally add .input-icon-right.

<div class="input-icon">
  <input type="text">
  <i>$</i>
</div>

<div class="input-icon input-icon-right">
  <input type="text">
  <i>€</i>
</div>

Align the icon vertically with transform and top, and set pointer-events to none so that clicks focus on the input. Adjust the padding and width as appropriate:

.input-icon {
  position: relative;
}

.input-icon > i {
  position: absolute;
  display: block;
  transform: translate(0, -50%);
  top: 50%;
  pointer-events: none;
  width: 25px;
  text-align: center;
  font-style: normal;
}

.input-icon > input {
  padding-left: 25px;
  padding-right: 0;
}

.input-icon-right > i {
  right: 0;
}

.input-icon-right > input {
  padding-left: 0;
  padding-right: 25px;
  text-align: right;
}

Unlike the accepted answer, this will retain input validation highlighting, such as a red border when there's an error.

JSFiddle usage example with Bootstrap and Font Awesome

rybo111
  • 12,240
  • 4
  • 61
  • 70
  • I wanted this with a button in one neat line and had to add `float:left` to the `input-symbol` div – kluka Aug 01 '16 at 10:03
  • @rybo111 no, I meant a separate button that is outside of the `input-symbol` container – kluka Aug 01 '16 at 11:05
  • You're right, `float` is bad so I'm using `display:inline-block` combined with `vertical-align:bottom` now :) I cannot quickly make a fiddle though, there's too much other CSS going in my current example ;-) – kluka Aug 01 '16 at 15:50
  • 2
    I like this answer than the accepted one since this (as the author mentions) retains the validation behaviour of bootstrap which is great!, thanks for this help. – Vadiraj Nov 16 '19 at 17:55
  • Correct me if I'm wrong, but it seems you don't use any bootstrap in your JSFiddle (as it states in your link description) – Andrei Cleland Jan 25 '22 at 22:42
  • 1
    @AndreiCleland Click "Resources" on the left and you will see the CSS and JS files that are loaded. And if you mean I don't use any Bootstrap HTML - I'm using the form-* classes. – rybo111 Jan 26 '22 at 09:44
38

You can wrap your input field into a span, which you position:relative;. Then you add with :before content:"€" your currency symbol and make it position:absolute. Working JSFiddle

HTML

<span class="input-symbol-euro">
    <input type="text" />
</span>

CSS

.input-symbol-euro {
    position: relative;
}
.input-symbol-euro input {
    padding-left:18px;
}
.input-symbol-euro:before {
    position: absolute;
    top: 0;
    content:"€";
    left: 5px;
}

Update If you want to put the euro symbol either on the left or the right side of the text box. Working JSFiddle

HTML

<span class="input-euro left">
    <input type="text" />
</span>
<span class="input-euro right">
    <input type="text" />
</span>

CSS

 .input-euro {
     position: relative;
 }
 .input-euro.left input {
     padding-left:18px;
 }
 .input-euro.right input {
     padding-right:18px;
     text-align:end; 
 }

 .input-euro:before {
     position: absolute;
     top: 0;
     content:"€";
 }
 .input-euro.left:before {
     left: 5px;
 }
 .input-euro.right:before {
     right: 5px;
 }
Philipp Hofmann
  • 3,388
  • 26
  • 32
  • This is very close to what I want, but the input is not stationary upon page width and cannot use absolute. Relative also moves the symbol around. How can we set the position absolute/relative to the input top-left corner? – nwolybug May 26 '15 at 22:13
  • The euro currency is always shown on the right. You should put your symbol on the right instead of the left. – jadok Nov 02 '15 at 11:18
  • Im french and the price are always written like 2.50€ not €2.50 and im quite sure that the other country in the euro zone do the same. – jadok Nov 07 '15 at 18:52
  • 2
    @jadok I live in the Netherlands are here prices are written as €2,50. – Vincent Kok Feb 16 '16 at 11:49
  • 1
    @VincentKok After asking around it seems it depends on the country, latines europeans country (France, Spain, ...) will put it on the right and the north/east europeans country on the left, you can try it with amazone by example: www.amazone.fr, www.amazone.nl, ... – jadok Feb 22 '16 at 17:31
33

Since you can't do ::before with content: '$' on inputs and adding an absolutely positioned element adds extra html - I like do to a background SVG inline css.

It goes something like this:

input {
    width: 85px;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' version='1.1' height='16px' width='85px'><text x='2' y='13' fill='gray' font-size='12' font-family='arial'>$</text></svg>");
    padding-left: 12px;
}

It outputs the following:

svg dollar sign background css

Note: the code must all be on a single line. Support is pretty good in modern browsers, but be sure to test.

Jeff Callahan
  • 1,281
  • 12
  • 15
  • 4
    Nice solution. I ended up adding `background-repeat: no-repeat;` as the $ was repeating in the input box. – Hamid Tavakoli Feb 12 '18 at 02:03
  • As browsers can render input elements as "replaced elements" (e.g. as system native widgets) it means that `background-image` might not be supported, or the browser might render the widget itself instead of using the system-provided widgets. – Dai Mar 10 '19 at 19:40
  • I also used this idea for a percent sign, and added a data-type attribute to the input with an additional style tag on the embedded svg: `input[data-type='percentage'] { background-image: url("data:image/svg+xml;utf8,%"); background-repeat: no-repeat; }` – Tim Jan 20 '22 at 19:42
  • This worked great for me with a parent
    that cannot be positioned relative! Thanks!!
    – Cake Princess Dec 17 '22 at 20:26
7

I ended up needing the type to still remain as a number, so used CSS to push the dollar sign into the input field using an absolute position.

<div>
   <span style="position: absolute; margin-left: 1px; margin-top: 1px;">$</span>
   <input type="number" style="padding-left: 8px;">
</div>
Andy Garcia
  • 354
  • 4
  • 13
4

If you only need to support Safari, you can do it like this:

input.currency:before {
  content: attr(data-symbol);
  float: left;
  color: #aaa;
}

and an input field like

<input class="currency" data-symbol="€" type="number" value="12.9">

This way you don't need an extra tag and keep the symbol information in the markup.

Sebastian
  • 2,109
  • 1
  • 20
  • 15
  • 8
    :before and :after CSS pseudo selectors can be used only for container tags and does not work for input tag. http://stackoverflow.com/questions/2587669/css-after-pseudo-element-on-input-field – Venkatesh Nannan Jul 23 '13 at 01:33
2
 $<input name="currency">

See also: Restricting input to textbox: allowing only numbers and decimal point

Community
  • 1
  • 1
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • 1
    Yes, I actually want for the currency sign to be inside the field, but thanks for the input restriction link! – User3419 May 26 '10 at 16:19
2

Put the '$' in front of the text input field, instead of inside it. It makes validation for numeric data a lot easier because you don't have to parse out the '$' after submit.

You can, with JQuery.validate() (or other), add some client-side validation rules that handle currency. That would allow you to have the '$' inside the input field. But you still have to do server-side validation for security and that puts you back in the position of having to remove the '$'.

dnagirl
  • 20,196
  • 13
  • 80
  • 123
  • 1
    Thank you! I was aware of that, but I actually needed my currency sign to be inside the text field. There is a better answer below which I believe can be of help to many people. – User3419 May 26 '10 at 16:31
  • @Hristo: I'm glad you found a solution that suits. But for the record, the one you've marked as the answer does not put your $ **in** the input field. It only makes it **seem** to be there with styling. That said, it's definitely slick! – dnagirl May 26 '10 at 17:13
  • 1
    Yes, it visually solves the problem, while your suggestion is just pointing (yes, still in the right direction), but I wouldn't call it solution. Thank you very much again and remember I didn't mean to offend anybody here! – User3419 May 26 '10 at 20:00
2

Try This

<label style="position: relative; left:15px;">$</label>
<input type="text" style="text-indent: 15px;">
Merrin K
  • 1,602
  • 1
  • 16
  • 27
1

Another solution which I prefer is to use an additional input element for an image of the currency symbol. Here's an example using an image of a magnifying glass within a search text field:

html:

<input type="image" alt="Subscribe" src="/graphics/icons/search-button.png">
<input type="text" placeholder="Search" name="query">

css:

#search input[type="image"] {
background-color: transparent;
border: 0 none;
margin-top: 10px;
vertical-align: middle;
margin: 5px 0 0 5px;
position: absolute;
}

This results in the input on the left sidebar here:

https://fsfe.org

Sam Tuke
  • 317
  • 2
  • 9
0

For bootstrap its works

<span class="form-control">$ <input type="text"/></span>

Don't use class="form-control" in input field.

Jestin
  • 578
  • 5
  • 10
0

None of these answers really help if you are concerned with aligning the left border with other text fields on an input form.

I'd recommend positioning the dollar sign absolutely to the left about -10px or left 5px (depending whether you want it inside or outside the input box). The inside solution requires direction:rtl on the input css.

You could also add padding to the input to avoid the direction:rtl, but that will alter the width of the input container to not match the other containers of the same width.

<div style="display:inline-block">
 <div style="position:relative">
  <div style="position:absolute; left:-10px;">$</div>
 </div>
 <input type='text' />
</div>

or

<div style="display:inline-block">
 <div style="position:relative">
  <div style="position:absolute; left:5px;">$</div>
 </div>
 <input type='text' style='direction: rtl;' />
</div>

https://i.stack.imgur.com/9ieSm.png

Example: https://plnkr.co/edit/yshyuRMd06K1cuN9tFDv?p=preview

Ted Scheckler
  • 1,389
  • 4
  • 16
  • 34
  • 1
    None of the answers will help with that because that is not what the question requested. The symbol is supposed to be *inside* the input. – rybo111 May 22 '18 at 17:50
  • Technically the css answers aren't putting the dollar sign inside the input container, either. I think the accepted css solution is introducing a complicated alignment problem when applied to a typical form. As seen here: https://plnkr.co/edit/uhOfLw5WB6DIn2le9GZm?p=preview – Ted Scheckler May 23 '18 at 14:50
  • I've updated this solution to place the dollar sign inside the input: https://plnkr.co/edit/yshyuRMd06K1cuN9tFDv?p=preview (position absolute left 5px and set input direction to rtl) – Ted Scheckler May 23 '18 at 14:57
0

I just used :before with the input and passed $ as the content

input{ 
   margin-left: 20px;
 }
input:before {
  content: "$";
  position: absolute;
}
  • 1
    I can't reproduce this in Chrome. Can you post a working JSFiddle example? – Dai Sep 08 '19 at 04:01
  • inputs don't support pseudo elements in CSS3. In other words it's impossible with pure CSS. However if using jquery you can use $("input").after("$"); – turkinator Dec 28 '19 at 00:54
0

<style>
.currencyinput {
    border: 1px inset #ccc;
    
    border-left:none;
}
.currencyinput input {
    border: 0;
}
</style>
<!DOCTYPE html>
<html>
<head>

</head>
<body>

<input type="text" oninput="this.value = this.value.replace(/[^0-9]/.g, ''); this.value = this.value.replace(/(\..*)\./g, '$1');" style="text-align:right;border-right:none;outline:none" name="currency"><span class="currencyinput">%</span>
</body>
</html>

%

-1

.currencyinput {
    border: 1px inset #ccc;
    padding-bottom: 1px;//FOR IE & Chrome
}
.currencyinput input {
    border: 0;
}
<span class="currencyinput">$<input type="text" name="currency"></span>
  • Code without explanation does little to help the OP or future viewers of this answer. You should explain how this answers the question. – leigero Oct 19 '16 at 20:40
-1

Yes, if you are using bootstrap, this would work.

.form-control input {
    border: none;
    padding-left: 4px;
}

and

<span class="form-control">$ <input type="text"/></span>
-1
.currencyinput {
    border: 1px inset #ccc;

    border-left:none;
}
.currencyinput input {
    border: 0;`enter code here`
}

<input type="text" oninput="this.value = this.value.replace(/[^0-9]/.g, ''); this.value = this.value.replace(/(\..*)\./g, '$1');" style="text-align:right;border-right:none;outline:none" name="currency"><span class="currencyinput">%</span>
brooksrelyt
  • 3,925
  • 5
  • 31
  • 54