ブラウザのフォントの各文字のレンダリングされたピクセル幅データ
-
03-07-2019 - |
質問
特定の幅、たとえば100ピクセルに制限する必要があるテーブル列があります。時々、その列のテキストはこれより広く、スペースが含まれていません。例:
a_really_long_string_of_text_like_this_with_no_line_breaks_makes_the_table_unhappy
テキストサーバー側の幅を計算し、正しい文字数の後に省略記号を追加したいと思います。問題は、テキストのレンダリングサイズに関するデータがないことです。
たとえば、ブラウザがFirefox 3で、フォントが12px Arialであると仮定します。 <!> quot; a <!> quot;の文字幅、<!> quot; b <!> quot;の文字幅などはどうなりますか?
各文字のピクセル幅を示すデータはありますか?またはそれを生成するプログラムですか?
巧妙な1回限りのJavaScriptスクリプトがこのトリックを実行できると思います。しかし、他の誰かがすでにこれを行っている場合は、車輪の再発明に時間を費やしたくありません。この問題に最初に出会ったのは私ではないでしょう。
解決
これはサーバーサイドで行うことが不可能であるだけでなく、意味をなさないでしょう。クライアントがどのブラウザを使用するか、クライアント側のどのフォント設定がHTMLに割り当てるスタイリング情報をオーバーライドするかはわかりません。スタイルプロパティで絶対配置ピクセルを使用していると思うかもしれませんが、クライアントは単純にそれらを無視するか、プラグインを使用してすべてをズームすることができます。これは、クライアントが高dpi画面を使用するためです。
通常、固定幅を使用するのは悪い考えです。
他のヒント
オーバーフローはどうですか:スクロールしますか?
Ext JS には、そのためのモジュールがあります
TextMetrics 正確なピクセル測定を提供 あなたができるようにテキストのブロックのために 高さと幅を正確に決定し、 ピクセル単位で、指定されたテキストブロックは あります。
同様のことを行う他のライブラリもあると確信しています。
サーバーサイドでの実行は非常に困難です。ユーザーがどのフォントをインストールしたかを知ることはできません。また、テキストの表示に影響する多くのことがあります。
代わりにこれを試してください:
table-layout: fixed;
テーブルが指定したサイズより大きくならないようにします。
ここに、私が思いついたクライアント側のソリューションを示します。これは私のアプリケーションに非常に固有のものですが、誰かが同じ問題に遭遇した場合に備えてここで共有しています。
これは、予想よりも少し速く動作します。また、セルの内容はテキストのみであると想定しています-HTMLの書式設定は短縮プロセスで消去されます。
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();
}
}
});
}
これは、サーバー側で行うことは本質的に不可能です。異なるフォントがインストールされている人の問題に加えて、カーニング(<!> quot; f <!> quotという文字は、その隣に応じて異なるスペースを占有します)とフォントレンダリングオプションもあります。 (cleartypeはオンですか?<!> quot; large fonts <!> quot;?)。
それを計算するためにサーバー側でできることは何もありません。作業する必要があるのはブラウザ識別文字列だけです。これは、ユーザーのオペレーティングシステムとブラウザを正確に通知する場合としない場合があります。 <!> quot; ask <!> quot;もできます。 (フォントタグまたはCSSを介して)テキストを表示するために使用される特定のフォントの場合、ユーザーがそのフォントをインストールしているという保証はありません。それを超えて、ユーザーはオペレーティングシステムレベルで異なるDPI設定を使用したり、ブラウザのズーム機能でテキストを大きくしたり小さくしたり、独自のスタイルシートを使用したりすることができます。
テキストを目に見えない範囲に入れて、その幅にまたがって読むこともできますが、基本的には誰かがあなたのサイトを妨害しようとしているように見えるので、特定の長さより長い単語、たとえば30文字のない投稿を禁止することをお勧めしますスペース(リンクを長くすることができます!-)
-しかし、単純なアプローチは、table-cell内にブロック要素を配置することです:
<td><div style="width:100px;overflow:hidden">a_really_long_string_of_text_like_this_with_no_line_breaks_makes_the_ta ... </div></td>
これにより、テーブルが乱雑になりません!o]
これがFireFoxで機能しないことでよければ、なぜCSSを使用しないのですか?テーブルにtable-layout:fixedを設定し、問題の列にoverflow:hidden; text-overflow:ellipsis;を設定します。 white-space:nowrap。
http://www.css3.info/preview/text-overflow/
これはcss3の新しい関数です。
一部のユーザーは、デフォルトのフォント設定を大きくしたり小さくしたりします。サーバーでこれを行うことはできません。ブラウザでページがレンダリングされた後でのみ測定できます。
フォントサイズはブラウザ側で簡単に変更できるため、サーバー側の計算は非常に簡単に無効になります。
クライアント側の簡単な修正方法は、オーバーフロー属性を使用してセルをスタイルすることです。
td
{
overflow: scroll; /* or overflow: hidden; etc. */
}
より良い代替方法は、文字列サーバー側を切り捨てて、長いバージョンを表示できる簡単なjavascriptツールチップを提供することです。 <!> quot; expand <!> quot;ボタンは、オーバーレイdivに結果を表示するのにも役立ちます。
欲しいのは<!> lt; wbr <!> gt;タグ。これは、ラップが必要な場合にここで単語を分割しても問題ないことをブラウザに伝える特別なHTMLタグです。データをどこに/どのように表示するかとデータを結合しているため、永続ストレージのテキストに挿入しません。ただし、ビューを中心としたコード(JSPタグを使用したり、場合によってはコントローラー内)にタグサーバー側を挿入することは完全に受け入れられます。それは私がそれをする方法です。正規表現を使用して、X文字より長い単語を見つけ、X文字ごとにこのタグをそのような単語に挿入します。
更新:いくつか調べてみたところ、すべてのブラウザでwbrがサポートされていないようです。最も注目すべきは、IE8です。私はこれを自分でテストしていません。おそらく、overflow:hiddenをバックアップなどとして使用できます。