Выравнивание десятичных знаков в HTML
у меня есть таблица, содержащая десятичные числа в одном столбце. Я ищу, чтобы выровнять их таким образом, как функция "десятичная вкладка" текстового процессора, так что все точки сидят на вертикальной линии.
у меня есть два возможных решения на данный момент, но я надеюсь на что-то лучшее...
Решение 1: разделить числа в HTML, например
<td><div>1234</div><div class='dp'>.5</div></td>
С
.dp { width: 3em; }
(Да, это решение не совсем работает как есть. Концепция, впрочем, допустимо.)
решение 2: я нашел упоминание о
<col align="char" char=".">
Это часть HTML4 согласно справочной странице, но она не работает в FF3.5, Safari 4 или IE7, которые являются браузерами, которые я должен передать. У него также есть проблема, что вы не можете вытащить числовое форматирование в CSS (хотя, поскольку это влияет на весь столбец, я полагаю, что это не слишком удивительно).
таким образом, у кого-нибудь есть идея получше?
10 ответов:
посмотреть эта статья Krijn Hoetmer для ваших вариантов и как этого добиться. Суть этого решения заключается в использовании CSS и JS для достижения этого:
(function() { var currencies = /($|€|€)/; 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'></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'></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; })();
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; }
<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>
чит; преимущество этого решения: также работает для пропорциональных шрифтов. Есть один дополнительный столбец и разделить целую часть от десятичного разделителя и десятичные дроби. Затем используйте этот css:
table{border-collapse:collapse;} td{padding:0px;margin:0px;border:0px;} td+td{text-align:right;} td,td+td+td{text-align:left;}
объединить два столбца в строке заголовков:
<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>
Я поиграл с jquery и придумал это...
html
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>
javascript
$(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); }) })
css
.right { text-align: left; } .left { float:left; text-align: right; width:10em; }
казалось, что это работает
другой способ форматирования числа будет выглядеть так:
35<span style="color:transparent">.000</span>
. То есть, запишите его с полным десятичным расширением, но запишите конечные десятичные знаки невидимыми чернилами. Таким образом, вам не придется беспокоиться о ширине запятой.
можете ли вы просто напечатать числа так, чтобы они всегда имели одинаковое количество десятичных знаков, и выровнять их по правому краю?
Я люблю короткие ответы, хотя длинные тоже важны, поэтому мне понравилось;
35<span style="color:transparent">.000</span>
и просто хочу добавить:
<TD><div style='float:right;'><?php echo number_format($totalAmount,2); ?></div></TD>
просто бросить php в микс. Многое зависит от фиксированной ширины шрифтов, но последний работает для меня. Поскольку данные часто уже табличные, добавление другой таблицы в ячейку просто слишком много ввода и трудно поддерживать.
тысячи лет назад (или 2-3) я написал jQuery shim, который эмулирует align="char", который все еще работает. Он использует CSS-заполнение и учитывает colspans, поэтому он умеренно умный, но это действительно не очень красивый код (я тогда только начинал в javascript). Я бы хотел, чтобы кто-то переписал его (и взял на себя всю ответственность).
в то же время, смотрите, если это поможет вам: https://gist.github.com/inanimatt/f27ffd25c174e9d8a0907455395d147d
Общая информация: причина, по которой браузеры неправильно поддерживают стили столбцов, заключается в том, что таблицы являются 2D-структурами данных, а DOM (на котором работают Javascript и CSS и как определяется HTML5) является чисто иерархическим и поэтому не может представлять как столбцы, так и строки. Вместо этого он просто определяет строки и ячейки, а не представляет столбцы вообще.
Если числа моноширинные, javascript может быть использован для настройки заполнения ячейки (в ems), в зависимости от количества цифр перед десятичной точкой. В противном случае, это может быть сложно.
функции, сделанные Krijn Hoetmer мешает prettyPhoto ( http://www.no-margin-for-errors.com/projects/prettyphoto-jquery-lightbox-clone/ ), поэтому я сделал jQuery версии. Валютная часть удаляется, так как она должна быть сделана динамической вместо замены строк на основе предопределенных валют.
необходима пустая функция от phpjs:http://phpjs.org/functions/empty:392 .
используемый jQuery-это версия 1.6.
/* This function will align table columns on the char if in the col from the * colgroup has the property 'align="char"' and a attribute 'char'. The alignment * is done on the first occurence of the specified char. * * The function is inspired from: * * http://krijnhoetmer.nl/stuff/javascript/table-align-char/ * http://stackoverflow.com/questions/1363239/aligning-decimal-points-in-html */ function alignNumbers() { var table; /* This will store the table currently working on . */ var i = 0; /* Every column can have it's own width, the counter makes the class name unique. */ /* Get all tables for which the alignment fix must be done. * * Note: this could even be further optimized by just looking for tables where * there is a a col with 'align="char"'. */ $('table.fix-align-char').each(function(index) { table = $(this); /* All table columns are fetched to have a correct index, without it it's * hard to get the correct table cells. */ $(this).find('col').each(function(index) { /* Only those table cells are changed for which the alignment is set to * char and a char is given. */ if ($(this).prop('align') == 'char' && !empty($(this).attr('char'))) { /* Variables for storing the width for the left and right part (in pixels). */ var left_width = 0, right_width = 0; var col, left_part, right_part, parts, new_html; i++; /* Increase the counter since we are working on a new column. */ col = $(this); /* For the col index + 1 (nth-child starts counting at 1), find the table * cells in the current table. */ table.find('> tbody > tr > td:nth-child('+ (index + 1) +')').each(function(index) { /* Split the html on the specified char. */ parts = $(this).html().split(col.attr('char')); new_html = ''; /* The first element is always the left part. The remaining part(s) are * the right part. Should there be more chars in the string, the right * parts are rejoined again with the specified char. */ left_part = parts.shift(); right_part = parts.join(','); /* Add a left part to the new html if the left part isn't empty*/ if (!empty(left_part)) { new_html = new_html + '<span class="left">' + left_part + '</span>'; } /* Add the specified char and the right part to the new html if * the right part isn't empty*/ if (!empty(right_part)) { new_html = new_html + col.attr('char') + '<span class="right">' + right_part + '</span>'; } /* If there is a new html, the width must be determined and a class is * added. * * Note: outerWidth is used instead of width so padding, margin and * borders are taken into account. */ if (!empty(new_html)) { $(this).html(new_html); /* Set the new html. */ $(this).addClass('char-align-' + i); /* Add a class to the table cell. */ /* Get the left span to determine its outer width. */ leftSpan = $(this).children('.left'); if (!empty(leftSpan) && left_width < leftSpan.outerWidth()) { left_width = leftSpan.outerWidth(); } /* Get the right span to determine its outer width. */ rightSpan = $(this).children('.right'); if (!empty(rightSpan) && right_width < rightSpan.outerWidth()) { right_width = rightSpan.outerWidth(); } } }); /* Only if any width is larger then 0, add a style. */ if (left_width > 0 || right_width > 0) { style_text = '<style type="text/css">.fix-align-char td.char-align-' + (i) + ' span.left { float: left; text-align: right; width: ' + (left_width) + 'px; }\n.fix-align-char td.char-align-' + (i) + ' span.right { float: right; text-align: left; width: ' + right_width + 'px; }</style>'; $('head').append(style_text); } } }); }); } $(document).ready(function(){ alignNumbers(); });
Я использовал JavaScript, чтобы исправить эту проблему... Это мой HTML.
<body> <table id="nadis"> </tr> </table> </body>
Это мой JavaScript.
var numarray = ["1.1", "12.20", "151.12", 1000.23,12451]; var highetlen = 0; for(var i=0; i<numarray.length; i++){ var n = numarray[i].toString(); var res= n.split("."); n = res[0]; if(highetlen < n.length){ highetlen = n.length; } } for(var j=0; j<numarray.length; j++){ var s = numarray[j].toString(); var res= s.split("."); s = res[0]; if(highetlen > s.length){ var finallevel = highetlen - s.length; var finalhigh = ""; for(k=0;k<finallevel;k++){ finalhigh = finalhigh+ '  '; } numarray[j] = finalhigh + numarray[j]; } var nadiss = document.getElementById("nadis"); nadiss.innerHTML += "<tr><td>" + numarray[j] + "</td></tr>"; }