Don
Don

Reputation: 17636

Formatting numbers (decimal places, thousands separators, localization, etc) with CSS

Is it possible to format numbers with CSS? That is: decimal places, decimal separator, thousands separator, etc.

Upvotes: 192

Views: 296567

Answers (16)

sh1
sh1

Reputation: 4763

Formatting numbers can go pretty deep and down all sorts of wrong paths. For example, you can end up with tools which will change the output between $ and £ depending on who's reading it, even though at least one of those outputs must be false.

However, if the only thing you're worried about is the readability of a number with thousand separators without the confusion over which thousand separators to use, it might be best to just follow international standards and ignore user preference. Insert thin spaces every three digits, and don't fuss over whether your decimal separator is . or ,.

If that's all you want to do, then one approach is to patch the font that you're using, and to use CSS to activate specific font features to format the font in a more friendly way.

I wanted to try this out, so using the Numderline font patcher as a kicking-off point, I made a tool to enable this.

You simply mark numbers with a CSS font feature setting indicating that you want it formatted with digit grouping:

font-feature-settings: "dgsp";

Now, in theory the font should be able to automatically adapt its behaviour according to the current language setting, inserting dots or commas or whatever as appropriate. That was my original intent, but while I was learning how to do it I found discussion explaining that this is discouraged, and the design philosophy is to make the feature available but let the application pass in additional settings to use according to user preference and/or locale.

Consequently, the tool offers alternative feature names dgco to use commas instead of spaces, and dgdo to use dots instead of spaces (which interacts poorly with dots as decimal separators, so there's dgdc to understand decimal comma).

Upvotes: 5

robotik
robotik

Reputation: 2017

as for thousand separators this is what I found on Wikipedia, in the code of this page. Below is the number 149597870700 with .15em margins as thousand separators:

<span style="white-space:nowrap">
    149
    <span style="margin-left:.15em;">597</span>
    <span style="margin-left:.15em;">870</span>
    <span style="margin-left:.15em;">700</span>
</span>

Upvotes: -3

kaiser
kaiser

Reputation: 22373

Example as inline-JavaScript in an input[type=number]-Html field, using Intl vanilla JS:

<input class="form-number" 
       type="number"
       id="bar"
       name="foo"
       value=""
       step="any"
       min="0"
       size="20"
       onfocusout="this.value = (new Intl.NumberFormat('de-DE').format(this.value));">

Upvotes: 1

Code4R7
Code4R7

Reputation: 2968

The closest thing I could find is the <input type="number" /> tag, which does do formatting in plain HTML but is also an input field. To make it look like plain text, you could use a bit of CSS.

Unfortunately I don't know how to fix the right margin without JavaScript or using a monospace font and set the width attribute server side.

HTML:

<p>In <input type="number" value="1.223" readonly="readonly" size="1" /> line</p>

CSS:

p {font-family: verdana;}
input {
  font-family: verdana;
  font-size: 16px;
}
input[readonly] {
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 3em;
  font-size: 16px; 
}
/* Chrome, Safari, Edge, Opera */
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
/* Firefox */
input[type=number] {
  -moz-appearance: textfield;
}

Upvotes: 0

vacsati
vacsati

Reputation: 567

Another js solution to improve the work of Skeeve:

<input type="text" onkeyup="this.value=this.value.toString().replaceAll(/[^\d]/g, '').replaceAll(/(\d)(?=(?:\d\d\d)+$)/g, '$1\u202f')" pattern="[0-9\s]*">

Upvotes: 1

DanielBlazquez
DanielBlazquez

Reputation: 1055

Another solution with pure CSS+HTML and the pseudo-class :lang().

Use some HTML to mark up the number with the classes thousands-separator and decimal-separator:

<html lang="es">
  Spanish: 1<span class="thousands-separator">200</span><span class="thousands-separator">000</span><span class="decimal-separator">.</span>50
</html>

Use the lang pseudo-class to format the number.

/* Spanish */
.thousands-separator:lang(es):before{
  content: ".";
}
.decimal-separator:lang(es){
  visibility: hidden;
  position: relative;
}
.decimal-separator:lang(es):before{
  position: absolute;
  visibility: visible;
  content: ",";
}

/* English and Mexican Spanish */
.thousands-separator:lang(en):before, .thousands-separator:lang(es-MX):before{
  content: ",";
}

Codepen: https://codepen.io/danielblazquez/pen/qBqVjGy

Upvotes: 6

CascadiaJS
CascadiaJS

Reputation: 2515

Unfortunately, it's not possible with CSS currently, but you can use Number.prototype.toLocaleString(). It can also format for other number formats, e.g. latin, arabic, etc.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString

Upvotes: 51

Mohammad Javed
Mohammad Javed

Reputation: 338

You could use Jstl tag Library for formatting for JSP Pages

JSP Page
//import the jstl lib
<%@ taglib uri="http://java.sun.com/jstl/fmt" prefix="fmt" %>

<c:set var="balance" value="120000.2309" />
<p>Formatted Number (1): <fmt:formatNumber value="${balance}" 
        type="currency"/></p>
<p>Formatted Number (2): <fmt:formatNumber type="number" 
        maxIntegerDigits="3" value="${balance}" /></p>
<p>Formatted Number (3): <fmt:formatNumber type="number" 
        maxFractionDigits="3" value="${balance}" /></p>
<p>Formatted Number (4): <fmt:formatNumber type="number" 
        groupingUsed="false" value="${balance}" /></p>
<p>Formatted Number (5): <fmt:formatNumber type="percent" 
        maxIntegerDigits="3" value="${balance}" /></p>
<p>Formatted Number (6): <fmt:formatNumber type="percent" 
        minFractionDigits="10" value="${balance}" /></p>
<p>Formatted Number (7): <fmt:formatNumber type="percent" 
        maxIntegerDigits="3" value="${balance}" /></p>
<p>Formatted Number (8): <fmt:formatNumber type="number" 
        pattern="###.###E0" value="${balance}" /></p>

Result

Formatted Number (1): £120,000.23

Formatted Number (2): 000.231

Formatted Number (3): 120,000.231

Formatted Number (4): 120000.231

Formatted Number (5): 023%

Formatted Number (6): 12,000,023.0900000000%

Formatted Number (7): 023%

Formatted Number (8): 120E3

Upvotes: 2

Anton Y. Reuchenko
Anton Y. Reuchenko

Reputation: 443

Well, for any numbers in Javascript I use next one:

var a = "1222333444555666777888999";
a = a.replace(new RegExp("^(\\d{" + (a.length%3?a.length%3:0) + "})(\\d{3})", "g"), "$1 $2").replace(/(\d{3})+?/gi, "$1 ").trim();

and if you need to use any other separator as comma for example:

var sep = ",";
a = a.replace(/\s/g, sep);

or as a function:

function numberFormat(_number, _sep) {
    _number = typeof _number != "undefined" && _number > 0 ? _number : "";
    _number = _number.replace(new RegExp("^(\\d{" + (_number.length%3? _number.length%3:0) + "})(\\d{3})", "g"), "$1 $2").replace(/(\d{3})+?/gi, "$1 ").trim();
    if(typeof _sep != "undefined" && _sep != " ") {
        _number = _number.replace(/\s/g, _sep);
    }
    return _number;
}

Upvotes: 24

DanielBlazquez
DanielBlazquez

Reputation: 1055

If it helps...

I use the PHP function number_format() and the Narrow No-break Space (&#8239;). It is often used as an unambiguous thousands separator.

echo number_format(200000, 0, "", "&#8239;");

Because IE8 has some problems to render the Narrow No-break Space, I changed it for a SPAN

echo "<span class='number'>".number_format(200000, 0, "", "<span></span>")."</span>";
.number SPAN{
    padding: 0 1px; 
}

Upvotes: 7

itpastorn
itpastorn

Reputation: 2995

Not an answer, but perhpas of interest. I did send a proposal to the CSS WG a few years ago. However, nothing has happened. If indeed they (and browser vendors) would see this as a genuine developer concern, perhaps the ball could start rolling?

Upvotes: 12

Ross
Ross

Reputation: 1679

Probably the best way to do so is combo of setting a span with a class denoting your formatting then use Jquery .each to do formatting on the spans when the DOM is loaded...

Upvotes: 15

Yoann
Yoann

Reputation: 5097

The CSS working group has publish a Draft on Content Formatting in 2008. But nothing new right now.

Upvotes: 44

Florin Frătică
Florin Frătică

Reputation: 587

I don't think you can. You could use number_format() if you're coding in PHP. And other programing languages have a function for formatting numbers too.

Upvotes: 3

Qorbani
Qorbani

Reputation: 5905

You cannot use CSS for this purpose. I recommend using JavaScript if it's applicable. Take a look at this for more information: JavaScript equivalent to printf/string.format

Also As Petr mentioned you can handle it on server-side but it's totally depends on your scenario.

Upvotes: 2

mreq
mreq

Reputation: 6542

No, you have to use javascript once it's in the DOM or format it via your language server-side (PHP/ruby/python etc.)

Upvotes: 9

Related Questions