使用CSS格式化数字(小数位、千位分隔符、本地化等)

180

是否可以使用CSS格式化数字?包括小数位、小数点分隔符、千位分隔符等。


82
你不能这样做,但你真的应该能够这样做。毕竟,50,000或50000或50,000.00都是相同的“数据”,只是以不同的方式呈现,这就是CSS存在的意义。 - punkrockbuddyholly
4
@MrMisterMan: 这里有一些想法正在讨论:http://wiki.csswg.org/ideas/content-formatting#numbers 我可能会受到骚扰,并被指责引用“规范”,并让每个人都抱有希望。对于我来说,我很想知道这里如何处理非数字文本。 - BoltClock
3
虽然我同意这个想法很好,但是这个数字嵌入在一个本地化页面中。也就是说,页面的其余部分是英语、中文或其他语言,数字应该符合该本地化环境。为什么它们应该与页面的其余部分分开本地化呢? - deceze
1
使用Intl.NumberFormat添加JS选项 mdn-ref: - Joshua Baboo
1
@punkrockbuddyholly;还需要本地化。例如,۵۰٬۰۰۰(波斯语)和٥٠٬٠٠٠(阿拉伯语)是相同的数据(50,000)。 - Mir-Ismaili
显示剩余3条评论
16个回答

46

2
最现代和优雅的方法,目前仍无法通过CSS实现,应该是第一选择! - FMA
它在RTL布局上出现了问题。我在服务器端格式化数字并将它们放入标记中,以便它们作为(例如,两千五百)<span>2 500</span>传递到浏览器。在阿拉伯语版本(带有body.rtl_ { direction: rtl; }),这个例子突然变成了500 2 - Alex Naidovich
@AlexNaidovich 感谢您提供的信息。这似乎是一个错误。您应该报告它。如果您正在使用Chrome浏览器,它基于Chromium项目,您可以在此处报告错误 - CascadiaJS
@CascadiaJS 感谢回复,但我发现这实际上并不是一个 bug。RTL 布局本质上会改变单词顺序,因此它会相应地处理空格。所以在某些小的情况下(比如上面的例子),我需要显式设置 direction: ltr;。总之 - 我们正在评论的答案完全没有问题。 - Alex Naidovich

40

CSS工作组在2008年发布了有关内容格式化的草案,但目前并没有新的消息。


3
12年过去了,这仍然是有用的。 - vy32

24

嗯,在JavaScript中,我通常使用下面的代码来处理数字:

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();

如果你需要使用其他分隔符,例如逗号:

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

或者作为一个函数:

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

1
谢谢。不是纯CSS解决方案,但完成了任务! - Don
1
我喜欢它。但在替换之前,我需要将数字转换为字符串。你不能对数字执行替换操作。 - Mardok
在调用 _number.replace 之前,我们必须确保它是一个字符串,像这样:_number = typeof _number != "undefined" && _number > 0 ? String(_number) : "";否则你会得到一个错误 _number.replace 未定义或不是一个函数。 - Shalkam
6
为什么不直接使用 (123456789).toLocaleString('en-GB') 或类似的方法呢? - Joehannes

15

可能最好的方法是将一个带有表示您格式的类的标记设置为组合,然后在DOM加载时使用Jquery .each对这些标记进行格式化...


10

并非答案,但或许会引起兴趣。几年前,我向CSS工作组提出了一份建议。然而,目前还没有任何进展。如果他们(以及浏览器供应商)将此视为真正的开发者关注点,也许球就可以开始滚动了?


4
感谢您的贡献。我希望有一天它会变得流行起来。 - ADJenks

9
不,您必须在DOM中使用JavaScript或者通过您的服务器端语言(例如PHP / ruby / python等)格式化它。请参考此链接学习JavaScript的格式化方法。

8
数字的格式是一种内容问题,就像内容文本或其他符号问题(例如与语言相关的日期符号)。因此,数字格式化是本地化工作,并应在生成内容时处理。在JavaScript中进行格式化对于由JavaScript生成的部分内容是有意义的。 - Jukka K. Korpela
我完全同意。这就是为什么我在我的答案中写了它。可能应该更加强调它。 - mreq
它可以是内容或演示。以CSS rtl为例,它以不同的方式显示相同的内容:它是否也应该在服务器端处理? - Don

7

如果有帮助...

我使用PHP函数number_format()窄间隔不换行空格(&#8239;)。它经常被用作无歧义的千位分隔符。

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

因为IE8在渲染Narrow No-break Space时存在问题,所以我将其改为了SPAN。
echo "<span class='number'>".number_format(200000, 0, "", "<span></span>")."</span>";

.number SPAN{
    padding: 0 1px; 
}

不幸的是,这是服务器端的操作,会稍微占用一些CPU资源,我们需要一个HTML/CSS编辑遮罩能力。装饰和渲染应该在客户端完成,除非我们正在提供PDF文件? - mckenzm

6

使用纯CSS+HTML和伪类:lang()来实现另一种解决方案。

使用一些HTML标记将数值标记为thousands-separatordecimal-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>

使用伪类lang来格式化数字。
/* 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


3

我认为您无法做到。如果您使用PHP编程,可以使用number_format()。其他编程语言也有格式化数字的功能。


在“后端”为了显示目的而修改数据是不好的做法。 - Buffalo
将页面用西班牙语(或其他语言)提供并使用该语言格式化数字有什么问题?我认为这根本不是一个坏习惯。 - DanielBlazquez

2
您不能使用CSS来实现这个目的。如果适用的话,我建议使用JavaScript。请查看此链接以获取更多信息:JavaScript equivalent to printf/string.format 此外,正如Petr所提到的,您也可以在服务器端处理它,但完全取决于您的情况。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接