Rendered pIxel width data for each character in a browser's font

10,013

Solution 1

This would not only be impossible to do server-side, it would also not make sense. You don't what browser your client will be using, and you don't know what font settings on the client side will override whatever styling information you assign to a piece of HTML. You might think that you're using absolute positioning pixels in your style properties, but the client could simply be ignoring those or using some plugin to zoom everything because the client uses a high-dpi screen.

Using fixed widths is generally a bad idea.

Solution 2

How about overflow: scroll?

Solution 3

Ext JS has a module to do just that

TextMetrics Provides precise pixel measurements for blocks of text so that you can determine exactly how high and wide, in pixels, a given block of text will be.

I am sure that there are other libraries available out there that do it as well.

Solution 4

Very very hard to do server-side. You can never know what fonts users have installed, and there are many things that affect the display of text.

Try this instead:

table-layout: fixed;

That'll make sure the table is never larger than the size you specified.

Solution 5

Here is my client-side solution that I came up with. It is pretty specific to my application but I am sharing it here in case someone else comes across the same problem.

It works a bit more quickly than I had expected. And it assumes the contents of the cells are text only - any HTML will formatting will be erased in the shortening process.

It requires jQuery.

function fixFatColumns() {
  $('table#MyTable td').each(function() {
    var defined_width = $(this).attr('width');
    if (defined_width) {
      var actual_width = $(this).width();
      var contents = $(this).html();
      if (contents.length) {
        var working_div = $('#ATempDiv');
        if (working_div.is('*')) {
          working_div.html(contents);
        } else {
          $('body').append('<div id="ATempDiv" style="position:absolute;top:-100px;left:-500px;font-size:13px;font-family:Arial">'+contents+'</div>');
          working_div = $('#ATempDiv');
        }

        if (working_div.width() > defined_width) {
          contents = working_div.text();
          working_div.text(contents);
          while (working_div.width() + 8 > defined_width) {
            // shorten the contents of the columns
            var working_text = working_div.text();
            if (working_text.length > 1) working_text = working_text.substr(0,working_text.length-1);
            working_div.text(working_text);
          }
          $(this).html(working_text+'...')
        }

        working_div.empty();
      }

    }
  });

}
Share:
10,013
Devon
Author by

Devon

Devon is a web application and cryptocurrency developer. He thinks he knows a little bit about back end and front end development. He is certain that he knows a lot about euro-style board games.

Updated on June 04, 2022

Comments

  • Devon
    Devon almost 2 years

    I have a table column that needs to be limited to a certain width - say 100 pixels. At times the text in that column is wider than this and contains no spaces. For example:

    a_really_long_string_of_text_like_this_with_no_line_breaks_makes_the_table_unhappy
    

    I would like to calculate the width of text server-side and add an ellipsis after the correct number of characters. The problem is that I don't have data about the rendered size of the text.

    For example, assuming the browser was Firefox 3 and the font was 12px Arial. What would be the width of the letter "a", the width of the letter "b", etc.?

    Do you have data showing the pixel width of each character? Or a program to generate it?

    I think a clever one-time javascript script could do the trick. But I don't want to spend time re-inventing the wheel if someone else has already done this. I am surely not the first person to come up against this problem.

  • Devon
    Devon over 15 years
    Ahh - I didn't consider kerning.
  • Devon
    Devon over 15 years
    This is a helpful solution because it doesn't break the table. But it doesn't show the ellipsis.
  • Dan
    Dan over 15 years
    It's really not easy to do that. The best I can come up with is a little JS function that would render an ellipsis in a new element, append a copy to each cell, and show/hide them depending on the scrollWidth/clientWidth of each.
  • Dan
    Dan over 15 years
    .. but that solution would require attaching events to onload, onresize, and anything else that may cause the table display to be affected, which is kinda heavy on the browser, so I really wouldn't recommend it.
  • Devon
    Devon over 15 years
    Interesting. Anyone know of a jQuery equivalent?
  • Devon
    Devon over 15 years
    Good idea. I think I'll try something like this in jQuery. It won't need to bind to resize events because the table is a fixed width.
  • Gordon Gustafson
    Gordon Gustafson over 13 years
    XD jquery has become so ubiquitous people always look for it first.
  • DS.
    DS. about 10 years
    This isn't server-side. For others searching, check out github.com/nodebox/opentype.js, which looks promising.