Related
I have a table containing decimal numbers in one column. I'm looking to align them in a manner similar to a word processor's "decimal tab" feature, so that all the points sit on a vertical line.
I have two possible solutions at the moment but I'm hoping for something better...
Solution 1: Split the numbers within the HTML, e.g.
<td><div>1234</div><div class='dp'>.5</div></td>
with
.dp { width: 3em; }
(Yes, this solution doesn't quite work as-is. The concept is, however, valid.)
Solution 2: I found mention of
<col align="char" char=".">
This is part of HTML4 according to the reference page, but it doesn't work in FF3.5, Safari 4 or IE7, which are the browsers I have to hand. It also has the problem that you can't pull out the numeric formatting to CSS (although, since it's affecting a whole column, I suppose that's not too surprising).
Thus, anyone have a better idea?
See this article by Krijn Hoetmer for your options and how to achieve this. The essence of this solution is to use CSS and JS to achieve this:
(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'>$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;
})();
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>
Another way to format a number would be like this: 35<span style="visibility: hidden">.000</span>. That is, write it out with the full decimal expansion, but write the trailing decimals in invisible ink. That way you don't have to worry about the width of the decimal point.
I'm surprised that in 10 years of answers to this question, nobody ever mentioned the Unicode character 'FIGURE SPACE' (U+2007, )
It's a whitespace character that is designed (by font authors, if they follow the standard) to be the same width as digits and to keep its spacing, like its more famous cousin the No-Break Space. You can use it to pad numbers to a certain string size, either on the left or on the right hand side, taking care of aligning the column or div on the same side.
Examples, both left-aligned and left-padded with figure spaces:
<p style="font-family: sans-serif">
10000 <br>
123.4 <br>
3.141592
</p>
<p style="font-family: serif">
10000 <br>
123.4 <br>
3.141592
</p>
Cheat; benefit of this solution: also works for proportional fonts. Have one extra column and split the integer part from the decimal separator and the decimals. Then use this css and combine two columns in the header row:
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>
Caveat: It isn't guaranteed to work. For example, on Safari 14 in 2021:
I played around with jQuery & came up with this...
$(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);
})
})
.right {
text-align: left;
}
.left {
float:left;
text-align: right;
width:10em;
}
<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>
It seemed to work.
can you just print the numbers so that they always have the same number of decimal places, and right align them?
Thousands of years ago (or 2-3) I wrote a jQuery shim that emulates align="char" which still seems to work. It uses CSS padding and accounts for colspans, so it's moderately clever, but it's really not very pretty code (I was just starting out in javascript back then). I'd love for someone to rewrite it (and take all the credit).
In the mean time, see if this helps you: https://gist.github.com/mattattui/f27ffd25c174e9d8a0907455395d147d
Trivia: The reason that browsers don't properly support column styles is that tables are 2D data structures and the DOM (which is what Javascript and CSS operate on, and how HTML5 is defined) is purely hierarchical and therefore can't represent both columns and rows. Instead it simply defines rows and cells, and doesn't represent columns at all.
I love short answers, even though the long ones are important too, so I liked;
35<span style="color:transparent">.000</span>
and would just like to add;
<TD><div style='float:right;'><?php echo number_format($totalAmount,2); ?></div></TD>
just to throw php into the mix. Much depends on fixed width fonts, still, but the latter works for me. Since data oft is already tabular, adding another table within a cell is just too much typing and hard to maintain.
If the numbers are monospaced, javascript could be used to adjust the padding on the cell (in ems), depending on the number of digits before the decimal point. Otherwise, it could be tricky.
The function made by Krijn Hoetmer interferes with prettyPhoto ( http://www.no-margin-for-errors.com/projects/prettyphoto-jquery-lightbox-clone/ ) so I made a jQuery version. The currency part is removed as it should be made dynamic instead of replacing strings based on predefined currencies.
Needed is the empty function from phpjs: http://phpjs.org/functions/empty:392 .
The jQuery used, is version 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();
});
I have used JavaScript to fix this issue...
This is my HTML.
<body>
<table id="nadis">
</tr>
</table>
</body>
This is my 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>";
}
A serious trouble in the previous approaches, is that only think in visual, but do not in other needs or uses of tables as sorting or filtering, where pure data is important.
Unfortunately CSS4 are not available yet. Then a valid solution could be pass the value and units or type unit in data attributes on td cell.
<!-- HTML-->
<table>
<tbody>
<tr>
<td data-value="1876.67542" data-unit="USD"></td>
</tr>
</tbody>
</table>
If a cell have a data value, it must read with javascript and updated to the decimal numbers that we requires.
// Javascript
let $td_value = document.querySelectorAll( 'td[data-item]' );
Array.from( $td_value ).forEach( $r => {
$r.textContent = parseFloat( $r.getAttribute('data-value') ).toFixed(2);
});
At the end, when we have normalized data, they will looks great with mono fonts and with their units placed using css selectors as before or after.
/* CSS */
td[data-value]{
font-family: monospace;
text-align: right;
}
td[data-unit]::after{
content: attr(data-unit]);
font-size: 85%;
padding-left: .2em;
opacity: .6;
}
I put an extended example in: https://jsfiddle.net/jam65st/wbo63xpu/12/
Ugly workaround but will save you from writing a lot of code:
You can find the max number in the array (list) of prices, then you can take the number of its digits and set inline style "width": (maxNumberDigits * 10)px - this is the ugly part!
And the container of this data (cell if its table) should have additionally
display:flex;
justify-content: flex-end;
Result:
I have a php element that I would like to center. At the moment I can only have it either to the right or the left of the page.
<style="text-align: left;"><?php PopupContact(); ?></style>
Is there a simple way of getting this element to sit in the center of the page?
Try this:
<div style="width:300px; margin:auto;"><?php PopupContact(); ?></div>
Where 300px is the width of your popup.
Try setting the text-align to center:
<style="text-align:center;"><?php PopupContact();?></style>
Try this..
You can also use the stylesheet properties like
margin-left:25px; margin-bottom:25px; margin-top:25px; margin-right:25px;
You can change the size of the pixels according to your requirement.
Edit your code exactly for the code which you want to center using:
<center></center>
Edit code which is perhaps with
<?php ?>
As the code in header.php you might need to center only the given code which you want to be centered: Thus giving the exact to use of more <?php codes in the code. Just by centering near exact code by this example:
<center><?php
$code = "code1 to be centered";
?></center>
<?php
$code2 = "code2 which is not centered";
?>
<center><?php
$code3 = "code3 again centered";
?></center>
So perhaps you want to just put into the top of the header.php to be centered with this example:
<center><?php
$code1 "code1 to be centered";
?></center>
<?php
how to add (please wait) on time counter javascript
<script language="javascript">
var timeout,interval
var threshold = <?php global $opt_themes; if($opt_themes['timer_active_']) { ?><?php echo $opt_themes['timer_fake_download']; ?>000<?php } else { ?>3000<?php } ?>;
var secondsleft=threshold;
window.onload = function()
{
startschedule();
}
function startChecking()
{
secondsleft-=1000;
document.querySelector(".div").innerHTML = "<span style=\"padding: 10px 30px;font-size: 40px; display:block;text-align:center;\">" + Math.abs((secondsleft/1000))+" </span>";
if(secondsleft == 0)
{
//document.getElementById("clickme").style.display="";
clearInterval(interval);
document.querySelector(".div").style.display="none";
document.querySelector(".div2").style.display="";
}
}
function startschedule()
{
clearInterval(interval);
secondsleft=threshold;
document.querySelector(".div").innerHTML = "<span style=\"padding: 10px 30px;font-size: 40px; display:block;text-align:center;\"> " + Math.abs((secondsleft/1000))+" </span>";
interval = setInterval(function()
{
startChecking();
},1500)
}
function resetTimer()
{
startschedule();
}
</script>
Facebook button is not working on IE8 at starting it is coming like in screenshot and after 45 seconds it disappears automatically with error
fb:login_button failed to resize in 45s
2 more error getting while opening page are:
FB.init has already been called - this could indicate a problem.
The "fb-root" div has not been created, auto-creating.
even after refreshing the page button is not coming.
after deleting browser history button again shows like in attached image and on click and
after entering Facebook login credentials again it is getting disappears and not working as it
should.
following is javascript code.
function initialize_fb(p_config) {
config = p_config;
window.fbAsyncInit = function () {
FB.init({
appId: config.appId,
channelUrl: config.channelURL,
status: true,
cookie: true,
xfbml: true
});
};
(function (d, debug, config) {
//console.log(config);
var js, id = "facebook-jssdk",
ref = d.getElementsByTagName("script")[0];
if (d.getElementById(id)) {
return;
}
js = d.createElement("script");
js.id = id;
js.async = true;
js.src = "//connect.facebook.net/en_US/all" + (debug ? "/debug" : "") + ".js#xfbml.js=1&appId=" + config.appId;
ref.parentNode.insertBefore(js, ref);
}(document, false, config));
}
function fshowuser(p_image, p_name, p_url, p_function, p_uid) {
var inner_htm;
showUserFunction = p_function;
if (p_name == "") {
isModify = false;
inner_htm = "<fb:login-button show-faces='false' width='100' max-rows='1' onlogin='{2}' id='buttonFBConnect'>{3}</fb:login-button>";
} else {
isModify = true;
if(! isRemoveRequired) {
inner_htm = "<table><tr><td rowspan='2'><img src='{0}' alt='{1}' id='fbModify'></td><td id='fbFrndName'>{1}</td></tr><tr><td><fb:login-button show-faces='false' width='100' max-rows='1' onlogin='{2}'>{4}</fb:login-button></td></tr></table>";
}else{
inner_htm = "<table><tr><td rowspan='2'><img src='{0}' alt='{1}' id='fbModify'></td><td id='fbFrndName'>{1}</td></tr></table>";
}
if (p_uid != undefined && p_uid != null && p_uid != "") {
inner_htm += "<input type='hidden' name='fb_uid' id='fb_uid' value='" + p_uid + "'>";
}
inner_htm += "<input type='hidden' name='fb_access_token' id='fb_access_token' value='" + accessToken + "'>";
}
$("#" + config.divId).html(inner_htm.format(p_image, p_name, p_function, config.connectText, config.modifyText, config.delinkText));
FB.XFBML.parse(document.getElementById(config.divId));
}
and following is html tag
<html xmlns:fb="http://www.facebook.com/2008/fbml" xmlns:og="http://opengraphprotocol.org/schema/" >
and it seems like button is not rendering correctly following is html code after button
gets disappears which is not completed:
<iframe name="f17348a353fff43" width="100" height="1000" title="fb:login_button Facebook Social Plugin" src="https://www.facebook.com/plugins/login_button.php?login_text=Connect&show_faces=false&max_rows=1&width=100&app_id=645653312120915&locale=en_US&sdk=joey&channel=https%3A%2F%2Fs-static.ak.facebook.com%2Fconnect%2Fxd_arbiter.php%3Fversion%3D25%23cb%3Df257016bf55bb8c%26origin%3Dhttps%253A%252F%252Flocalhost%253A7003%252Ffda8d5ab9fe0b6%26domain%3Dlocalhost%26relation%3Dparent.parent" frameBorder="0" scrolling="no" style="border-bottom: medium none; border-left: medium none; visibility: visible; border-top: medium none; border-right: medium none;" allowTransparency="allowtransparency">
I have tried to Google allot but nothing is working.
code is working fine in Google chrome and Firefox browsers.
so anybody knows solution?
Matt Bower from Facebook developer's forum gave this temporary solution:
#fb_login_button {
width: 80px;
}
#fb_login_button span,
#fb_login_button iframe {.
width: 80px! important;
height: 25px! important;
}
Facebook Dev's are working to fix this error.
I encountered the same issue. I had conflicting CSS selectors.
I had to change:
class="menu-icon"
to
class="mysite-menu-icon"
I recommend going through all your class and id attributes and test any common names you see. Note that you need to test the HTML attributes not your CSS selectors.
I have the same problem,
fb:like_box failed to resize in 45s
I have fixed this problem temporary
Please add this CSS,
.fb-like-box iframe{width:250px !important;height:200px !important;}
i hope this will help.
If this is happening in Chrome, disable all of your extensions, even the ones that could not possibly be the problem. Reload the page and see if that resolved it.
In my site template I want to place an image code which re-sizes images with a width larger than 910px down to 910px, but leaves those with a width smaller than 910px. If the image is resized it should offer a show original image option.
I would like to implement something like this http://www.mangareader.net/94-8-3/bleach/chapter-1.html
This is the code I have so far:
HTML:
<img src="http://localhost/manga2anime/upload/Bleach/1/03.png" class="resize">
CSS:
.resize {
max-width: 910px;
max-height : auto;
}
Easiest would be if you also stored the img's width in your database. If that's the case, something like this will do:
<?php
// Connect to DB etc.
$result = mysql_query("SELECT 'img_path', 'width' FROM table");
if(mysql_row_count($result) != 0){
while($row = mysql_fetch_array($result)){
$img = "<img src='" . $row['img_path'] . "'";
if($row['width'] > 910){
$img .= " class='resize'";
// OR
// $img .= " width='910'";
echo "<a onclick='showOriginal()'>Show Original</a>";
}
$img .= " >";
echo $img;
}
}else{
echo "No images found.";
}
?>
If the img is already loaded and your php isn't that handy, you can also adjust it with jQuery:
function adjustImage(){
if($('img#needed_img').width() > 910){
$(this).addClass('resize');
// OR
// $(this).attr('width', '910');
$('#show_original_button').show();
}
}
And just call the above function when the document loads (so not in combination with the jQuery ready function). I dont know what your HTML looks like, so its hard to also come up with a working 'show original' function.. but i think something like a lightbox or modal would be most useful in your case to show the original img, for it wont alter your template and just 'sit on top of it'.
I have a table containing decimal numbers in one column. I'm looking to align them in a manner similar to a word processor's "decimal tab" feature, so that all the points sit on a vertical line.
I have two possible solutions at the moment but I'm hoping for something better...
Solution 1: Split the numbers within the HTML, e.g.
<td><div>1234</div><div class='dp'>.5</div></td>
with
.dp { width: 3em; }
(Yes, this solution doesn't quite work as-is. The concept is, however, valid.)
Solution 2: I found mention of
<col align="char" char=".">
This is part of HTML4 according to the reference page, but it doesn't work in FF3.5, Safari 4 or IE7, which are the browsers I have to hand. It also has the problem that you can't pull out the numeric formatting to CSS (although, since it's affecting a whole column, I suppose that's not too surprising).
Thus, anyone have a better idea?
See this article by Krijn Hoetmer for your options and how to achieve this. The essence of this solution is to use CSS and JS to achieve this:
(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'>$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;
})();
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>
Another way to format a number would be like this: 35<span style="visibility: hidden">.000</span>. That is, write it out with the full decimal expansion, but write the trailing decimals in invisible ink. That way you don't have to worry about the width of the decimal point.
I'm surprised that in 10 years of answers to this question, nobody ever mentioned the Unicode character 'FIGURE SPACE' (U+2007, )
It's a whitespace character that is designed (by font authors, if they follow the standard) to be the same width as digits and to keep its spacing, like its more famous cousin the No-Break Space. You can use it to pad numbers to a certain string size, either on the left or on the right hand side, taking care of aligning the column or div on the same side.
Examples, both left-aligned and left-padded with figure spaces:
<p style="font-family: sans-serif">
10000 <br>
123.4 <br>
3.141592
</p>
<p style="font-family: serif">
10000 <br>
123.4 <br>
3.141592
</p>
Cheat; benefit of this solution: also works for proportional fonts. Have one extra column and split the integer part from the decimal separator and the decimals. Then use this css and combine two columns in the header row:
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>
Caveat: It isn't guaranteed to work. For example, on Safari 14 in 2021:
I played around with jQuery & came up with this...
$(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);
})
})
.right {
text-align: left;
}
.left {
float:left;
text-align: right;
width:10em;
}
<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>
It seemed to work.
can you just print the numbers so that they always have the same number of decimal places, and right align them?
Thousands of years ago (or 2-3) I wrote a jQuery shim that emulates align="char" which still seems to work. It uses CSS padding and accounts for colspans, so it's moderately clever, but it's really not very pretty code (I was just starting out in javascript back then). I'd love for someone to rewrite it (and take all the credit).
In the mean time, see if this helps you: https://gist.github.com/mattattui/f27ffd25c174e9d8a0907455395d147d
Trivia: The reason that browsers don't properly support column styles is that tables are 2D data structures and the DOM (which is what Javascript and CSS operate on, and how HTML5 is defined) is purely hierarchical and therefore can't represent both columns and rows. Instead it simply defines rows and cells, and doesn't represent columns at all.
I love short answers, even though the long ones are important too, so I liked;
35<span style="color:transparent">.000</span>
and would just like to add;
<TD><div style='float:right;'><?php echo number_format($totalAmount,2); ?></div></TD>
just to throw php into the mix. Much depends on fixed width fonts, still, but the latter works for me. Since data oft is already tabular, adding another table within a cell is just too much typing and hard to maintain.
If the numbers are monospaced, javascript could be used to adjust the padding on the cell (in ems), depending on the number of digits before the decimal point. Otherwise, it could be tricky.
The function made by Krijn Hoetmer interferes with prettyPhoto ( http://www.no-margin-for-errors.com/projects/prettyphoto-jquery-lightbox-clone/ ) so I made a jQuery version. The currency part is removed as it should be made dynamic instead of replacing strings based on predefined currencies.
Needed is the empty function from phpjs: http://phpjs.org/functions/empty:392 .
The jQuery used, is version 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();
});
I have used JavaScript to fix this issue...
This is my HTML.
<body>
<table id="nadis">
</tr>
</table>
</body>
This is my 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>";
}
A serious trouble in the previous approaches, is that only think in visual, but do not in other needs or uses of tables as sorting or filtering, where pure data is important.
Unfortunately CSS4 are not available yet. Then a valid solution could be pass the value and units or type unit in data attributes on td cell.
<!-- HTML-->
<table>
<tbody>
<tr>
<td data-value="1876.67542" data-unit="USD"></td>
</tr>
</tbody>
</table>
If a cell have a data value, it must read with javascript and updated to the decimal numbers that we requires.
// Javascript
let $td_value = document.querySelectorAll( 'td[data-item]' );
Array.from( $td_value ).forEach( $r => {
$r.textContent = parseFloat( $r.getAttribute('data-value') ).toFixed(2);
});
At the end, when we have normalized data, they will looks great with mono fonts and with their units placed using css selectors as before or after.
/* CSS */
td[data-value]{
font-family: monospace;
text-align: right;
}
td[data-unit]::after{
content: attr(data-unit]);
font-size: 85%;
padding-left: .2em;
opacity: .6;
}
I put an extended example in: https://jsfiddle.net/jam65st/wbo63xpu/12/
Ugly workaround but will save you from writing a lot of code:
You can find the max number in the array (list) of prices, then you can take the number of its digits and set inline style "width": (maxNumberDigits * 10)px - this is the ugly part!
And the container of this data (cell if its table) should have additionally
display:flex;
justify-content: flex-end;
Result: