Related
<input type="text" style="width:90px" value="This is a text for student with code: 30001"/></br>
<input type="text" style="width:90px" value="This is a text for student with code: 30002"/></br>
<input type="text" style="width:90px" value="This is a text for student with code: 30003"/></br>
I have several inputs with limited width containing some text which last letters of texts are more important to be visible.
How can I make my inputs to show last words?
I tried:
input{
text-align:right
}
But it was not helpful.
Please see this ample code.
Simply add style="direction: rtl;" to the input tag if you don't mind letters start appearing from the right.
You can do this using Javascript.
I use a helper function that will determine the width of text using its font-type, font-size and the text string. We get these using getComputedStyle(), this allows you to get the style directly from the CSS without having to add it statically and then pass those into the function. Apply the outcome of this function to a variable called textWidth.
Use this along with the input elements getComputedStyle(e.target).width set in CSS in a conditional and set it to elWidth. Then we run our main function displayText() through an eventListener and listen for the event, use the event.target to get the inputs width and run these through a conditional to see if the textWidth is greater than the elWidth.
const inputs = document.querySelectorAll('input')
const units = ['em', 'px', 'cm', 'mm', 'in', 'pt', 'pc', '%', 'rem']
function determineTextWidth(txt, family, size) {
if (determineTextWidth.c === undefined) {
determineTextWidth.c = document.createElement('canvas');
determineTextWidth.ctx = determineTextWidth.c.getContext('2d');
}
const fontspec = `${size} ${family}`;
if (determineTextWidth.ctx.font !== fontspec)
determineTextWidth.ctx.font = fontspec;
return determineTextWidth.ctx.measureText(txt).width;
}
function displayText(e) {
const fontSize = getComputedStyle(e.target).fontSize
const fontFamily = getComputedStyle(e.target).fontFamily
const textWidth = determineTextWidth(e.target.value, fontFamily, fontSize)
const elWidth = getComputedStyle(e.target).width
units.forEach(unit=>{
if(elWidth.includes(unit)){
textWidth > elWidth.split(unit)[0] ?
e.target.nextElementSibling.innerText = e.target.value : e.target.nextElementSibling.textContent = null
}
})
}
inputs.forEach(input => {
input.addEventListener('keyup', displayText)
})
.input {
font-size: 12pt;
width: 150px;
font-family: sans-serif;
}
.display {
margin-left: 1rem;
display: inline-block;
background-color: lightgreen;
color: darkgreen;
}
Enter input: <input class="input" type="text"> <span class="display"></span>
I have an HTML text field that is 3 characters. If the user types 4 characters, I want the font size to shrink so that the four characters will fit.
Acrobat has this behavior for forms. I want this behavior in HTML.
That is, if I have a text field with 3 characters:
And the user types a 4, I want the text to shrink:
You need to use javascript.
This works by checking if the input can scroll, and if it can, it means that the content has overflowed, in which case the font size should get smaller.
Hope this helps!
function changefontsize() {
var myInput = document.getElementById('myInput');
if(isOverflown(myInput)) {
while (isOverflown(myInput)){
currentfontsize--;
myInput.style.fontSize = currentfontsize + 'px';
}
}else {
currentfontsize = 13;
myInput.style.fontSize = currentfontsize + 'px';
while (isOverflown(myInput)){
currentfontsize--;
myInput.style.fontSize = currentfontsize + 'px';
}
}
}
function isOverflown(element) {
return element.scrollWidth > element.clientWidth;
}
#myInput {
padding:5px;
border-radius:3px;
font-family:Arial;
width:100px;
font-size:13px;
height:20px;
}
Type Here -> <input type="text" id="myInput" onkeypress="changefontsize()" onchange="changefontsize()">
This is not possible with HTML/CSS - this solution uses JS+JQuery
Found this: https://github.com/vxsx/jquery.inputfit.js
Demo: http://vxsx.github.io/jquery.inputfit.js/
<input type="text" name="younameit" id="input">
<script type="text/javascript">
$('#input').inputfit();
</script>
I think what you want can be done with some very simple javascript methods. But, unfortunately there is no method of doing this in html or css. This next code is something I found, made by u/adactio. On github.
<script>
window.fitText( document.getElementById("responsive_headline") );
</script>
window.fitText( document.getElementById("responsive_headline"), 1.2 );
// turn the compressor up (font will shrink a bit more aggressively)
window.fitText( document.getElementById("responsive_headline"), 0.8 );
// turn the compressor down (font will shrink less aggressively)
Make sure to edit the 'responsive_headline' out!
Cheers!
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 no idea what this is even called so not sure where to start, hoping you all are able to point me in the right direction. I am trying to create something like this:
The idea being that when a user types something in and then separates with a comma, their input into this form field will turn into a little tag-like box that they can then delete with the x.
Any ideas on where to start?
Thanks!
Here is simple example: http://jsfiddle.net/9tzb4/
HTML:
<form>
Tags:
<div class="tag_field">
<input type="text">
<input type="hidden" name="tags">
</div>
<br>
<input type="submit" value="Submit">
</form>
CSS:
.tag_buttons {
position: absolute;
}
.tag_buttons div {
display:inline-block;
margin: 2px;
border: 1px solid #666;
padding: 1px;
}
.tag_field input[type=text] {
padding: 5px;
width: 300px;
border: 1px solid #666;
}
JavaScript:
$(".tag_field").each(function() {
var buttons = $("<div/>");
var input = $(this).find("input[type=text]");
var output = $(this).find("input[type=hidden]");
var update_padding = function() {
input.css("padding-left", buttons.width() + 2);
};
setInterval(update_padding, 300);
$(this).prepend(buttons);
buttons.addClass("tag_buttons");
buttons.css({ left: input.offset().left + 1,
top: input.offset().top + 2 });
input.bind("keyup change paste", function() {
var i = input.val().indexOf(",");
if (i >= 0) {
var new_tag = input.val().substr(0, i);
input.val(input.val().substr(i+1));
buttons.append("<div id='button'><span class='value'>"+new_tag+"</span> <span class='close'>(x)</span></div>");
}
});
var form = $(this).closest("form");
if (form.length > 0) {
form.submit(function() {
var v = [];
form.find(".tag_buttons div").each(function() {
v.push($(this).find(".value").html());
});
output.val(v.join(","));
return false;
});
}
});
$(document).on("click", ".tag_buttons span.close", {}, function(e) {
$(e.target).closest("div").detach();
});
Check this out. http://davidwalsh.name/dw-content/jquery-chosen.php This is the things I guess will perfectly suite your application.
Check out the amazing jQuery chosen, which - among other things - does exactly what you're looking for.
select2 is a similar plugin, and it also allows you to add your own tags (as well as use an AJAX source).
Update from the select2 docs:
Note that when tagging is enabled the user can select from pre-existing tags or create a new tag by picking the first choice which is what the user has typed into the search box so far.
You may find the jQuery Tags Input Library helpful. It gives you something like this
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: