在HTML中对齐小数点

ijw*_*ijw 68 html css

我在一列中有一个包含十进制数的表.我希望以类似于文字处理器的"十进制选项卡"功能的方式对齐它们,以便所有点都位于垂直线上.

我目前有两种可能的解决方案,但我希望有更好的解决方案......

解决方案1:拆分HTML中的数字,例如

<td><div>1234</div><div class='dp'>.5</div></td>
Run Code Online (Sandbox Code Playgroud)

.dp { width: 3em; }
Run Code Online (Sandbox Code Playgroud)

(是的,这个解决方案不能完全正常工作.但是,这个概念是有效的.)

解决方案2:我发现了提及

<col align="char" char=".">
Run Code Online (Sandbox Code Playgroud)

根据参考页面,这是HTML4的一部分,但它在FF3.5,Safari 4或IE7中不起作用,这是我必须提供的浏览器.它还有一个问题,你不能将数字格式化为CSS(虽然,因为它影响整个列,我想这并不太令人惊讶).

那么,谁都有更好的主意?

Dan*_*plo 21

请参阅Krijn Hoetmer撰写的这篇文章,了解您的选择以及如何实现这一目标.这个解决方案的本质是使用CSS和JS来实现这个目的:

(function() {
  var currencies = /(\$|€|&euro;)/;
  var leftWidth = 0, rightWidth = 0;
  for(var tableCounter = 0, tables = document.getElementsByTagName("table");
      tableCounter < tables.length; tableCounter++) {
    if(tables[tableCounter].className.indexOf("fix-align-char") != -1) {
      var fCols = [], leftPart, rightPart, parts;
      for(var i = 0, cols = tables[tableCounter].getElementsByTagName("col"); i < cols.length; i++) {
        if(cols[i].getAttribute("char")) {
          fCols[i] = cols[i].getAttribute("char");
        }
      }
      for(var i = 0, trs = tables[tableCounter].rows; i < trs.length; i++) {
        for(var j = 0, tds = trs[i].getElementsByTagName("td"); j < tds.length; j++) {
          if(fCols[j]) {
            if(tds[j].innerHTML.indexOf(fCols[j]) != -1) {
              parts = tds[j].innerHTML.split(fCols[j]);
              leftPart = parts.slice(0, parts.length -1).join(fCols[j]);
              leftPart = leftPart.replace(currencies, "<span class='currency'>$1</span>");
              rightPart = fCols[j] + parts.pop();
              tds[j].innerHTML = "<span class='left'>" + leftPart + "</span><span class='right'>" + rightPart + "</span>";
            } else {
              tds[j].innerHTML = tds[j].innerHTML.replace(currencies, "<span class='currency'>$1</span>");
              tds[j].innerHTML = "<span class='left'>" + tds[j].innerHTML + "</span>";
            }
            tds[j].className = "char-align";
            var txt = document.createTextNode(tds[j].firstChild.offsetWidth);
            if(leftWidth < tds[j].firstChild.offsetWidth) {
              leftWidth = tds[j].firstChild.offsetWidth;
            }
            if(tds[j].childNodes[1]) {
              txt = document.createTextNode(tds[j].childNodes[1].offsetWidth);
              if(rightWidth < tds[j].childNodes[1].offsetWidth) {
                rightWidth = tds[j].childNodes[1].offsetWidth;
              }
            }
          }
        }
      }
    }
  }
  // This is ugly and should be improved (amongst other parts of the code ;)
  var styleText = "\n" +
      "<style type='text/css'>\n" +
      "  .fix-align-char td.char-align { width: " + (leftWidth + rightWidth) + "px; }\n" +
      "  .fix-align-char span.left { float: left; text-align: right; width: " + leftWidth + "px; }\n" +
      "  .fix-align-char span.currency { text-align: left; float: left; }\n" +
      "  .fix-align-char span.right { float: right; text-align: left; width: " + rightWidth + "px; }\n" +
      "</style>\n";
  document.body.innerHTML += styleText;
})();
Run Code Online (Sandbox Code Playgroud)
table {
  border-collapse: collapse;
  width: 600px;
}
th {
  padding: .5em;
  background: #eee;
  text-align: left;
}
td {
  padding: .5em;
}
#only-css td.char-align {
  width: 7em;
}
#only-css span.left {
  float: left;
  width: 4em;
  text-align: right;
}
#only-css span.currency {
  float: left;
  width: 2em;
  text-align: left;
}
#only-css span.right {
  float: right;
  width: 3em;
  text-align: left;
}
Run Code Online (Sandbox Code Playgroud)
<table id="only-css">
  <thead>
    <tr>
      <th>Number</th>
      <th>Description</th>
      <th>Costs</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td>Lorem ipsum dolor sit amet</td>
      <td class="char-align">
        <span class="left">
          <span class="currency">$</span>3
        </span>
        <span class="right">,99</span>
      </td>
    </tr>
    <tr>
      <td>2</td>
      <td>Consectetuer adipiscing elit</td>
      <td class="char-align">
        <span class="left">
          <span class="currency">$</span>13
        </span>
        <span class="right">,95</span>
      </td>
    </tr>
    <tr>
      <td>3</td>
      <td>Pellentesque fringilla nisl ac mi</td>
      <td class="char-align">
        <span class="left">
          <span class="currency">$</span>4
        </span>
        <span class="right"></span>
      </td>
    </tr>
    <tr>
      <td>4</td>
      <td>Aenean egestas gravida magna</td>
      <td class="char-align">
        <span class="left">
          <span class="currency">$</span>123
        </span>
        <span class="right">,999</span>
      </td>
    </tr>
  </tbody>
</table>
Run Code Online (Sandbox Code Playgroud)

  • 有用.他的文章有一个演示版,允许您测试<COL>解决方案和JS以使其工作.总之,JS将单元格内容逐个划分为跨度,测量DP侧,然后在样式表中使用它来指定跨度宽度.这是一个解决方法的黑客攻击,但它确实做了必要的工作,并且表明没有合适的方法让浏览器正确地完成它. (3认同)

Dav*_*pik 16

格式化数字的另一种方法是这样的: 35<span style="visibility: hidden">.000</span>.也就是说,用完整的十进制扩展写出来,但是用隐形墨水写下尾随小数.这样您就不必担心小数点的宽度.

  • `visibility:hidden`会更好 (7认同)
  • 我花了8年时间,但我改变了从使用透明度到可见性的答案.(最初我没有更改它,因为我没有在足够的浏览器中测试过.) (6认同)

小智 10

作弊; 此解决方案的好处:也适用于比例字体.有一个额外的列并从小数分隔符和小数分割整数部分.然后用这个css:

table {border-collapse:collapse;}
td {padding:0px;margin:0px;border:0px;}
td+td {text-align:right;}
td, td+td+td {text-align:left;}
Run Code Online (Sandbox Code Playgroud)

在标题行中合并两列:

<table>
    <tr><th>Name</th><th colspan=2>Height</th></tr>
    <tr><td>eiffeltower</td> <td>324</td> <td></td></tr>
    <tr><td>giraffe</td> <td>5</td> <td>,30</td></tr>
    <tr><td>deer</td> <td>1</td> <td></td></tr>
    <tr><td>mouse</td> <td>0</td> <td>,03</td></tr>
</table>
Run Code Online (Sandbox Code Playgroud)

  • 蒂姆伯纳斯 - 李如果死了就会在他的坟墓里旋转.但是,这是一个答案. (22认同)
  • @AVProgrammer因为牺牲了什么是传达的值(例如这里的数字)的语义凝聚力.十进制标记左侧与右侧的数字分别为<td>.虽然可视化渲染的输出可能与所需的匹配,但可访问性,连续文本选择性,<title>能力和类似的东西完全被忽略.因此,人们不能称之为符合标准,因为标准确实处理的问题不仅仅是规定格式良好,可视化可渲染的标记. (14认同)
  • @AVProgrammer和屏幕阅读器会讨厌你. (8认同)
  • 为什么Tim Berners-Lee会关心这个?这看起来像是一种聪明,强大且符合标准的方式来实现OP所追求的目标. (3认同)

小智 8

我和jquery一起玩,想出了这个......

HTML

$(document).ready(function() {
  $('.aBDP').each(function() {
    var wholePart, fractionPart;
    wholePart = Math.floor($(this).text()-0);
    fractionPart = Math.floor(($(this).text() % 1)*10000 + 0.5) / 10000 + "";
    html  = '<span class="left">' + wholePart + '.' + '</span>';
    html += '<span class="right">' + fractionPart.substring(2) + '</span>';
    $(this).html(html); 
  })
})
Run Code Online (Sandbox Code Playgroud)

JavaScript的

.right {
    text-align: left;
}
.left {
    float:left;
    text-align: right;
    width:10em;
}
Run Code Online (Sandbox Code Playgroud)

CSS

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js" type="text/javascript"></script>

<table width="600" border="1">  
  <tr><th></th><th>Aligned Column</th></tr>
  <tr><th>1st Row</th><td class='aBDP'>1.1</td></tr>
  <tr><th>2nd Row</th><td class='aBDP'>10.01</td></tr>  
  <tr><th>3rd Row</th><td class='aBDP'>100.001</td></tr>  
  <tr><th>4th Row</th><td class='aBDP'>1000.0001</td></tr>
</table>
Run Code Online (Sandbox Code Playgroud)

它似乎工作


Tob*_*bia 7

我很惊讶在这个问题的 10 年答案中,没有人提到过 Unicode 字符“FIGURE SPACE”(U+2007, &#8199;

它是一个空白字符(由字体作者,如果他们遵循标准)设计为与数字相同的宽度并保持其间距,就像它更著名的表亲 No-Break Space 一样。您可以使用它在左侧或右侧将数字填充到特定的字符串大小,注意在同一侧对齐列或 div。

示例,左对齐和左填充图形空间:

<p style="font-family: sans-serif">
  10000 <br>
  &#8199;&#8199;123.4 <br>
  &#8199;&#8199;&#8199;&#8199;3.141592
</p>

<p style="font-family: serif">
  10000 <br>
  &#8199;&#8199;123.4 <br>
  &#8199;&#8199;&#8199;&#8199;3.141592
</p>
Run Code Online (Sandbox Code Playgroud)


Rob*_*sor 5

您能仅打印数字以使它们始终具有相同的小数位数,然后将它们右对齐吗?

  • 实际上,任何体面字体中的数字都是等距的 (12认同)
  • @Eric体面!=美丽 (3认同)
  • @Eric并非所有数字都一样:http://practicaltypography.com/grids-of-numbers.html (3认同)