話題の記事

文字列を省略して「…」を付与する方法 – CSS/jQuery

2012.02.29

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

通常、設計・デザインの段階であらかじめ表示する文字数の上限を決めておき、PHPやRuby、Javaなどサーバサイドで表示する文字列を加工することが多いかと思います。

しかし、この方法だと動的に変化する領域を基準に表示する文字数を制限する場合や、文字サイズや表示領域のサイズに合わせて上限を算出する場合に限界があります。

そこで、クライアントサイドで表示領域から文字列がはみ出す場合、文字列を省略して省略記号「…」をつける方法を紹介してみたいと思います。 実現方法として以下の2つの方法があります。

  • text-overflowプロパティを使う
  • jQueryで表示領域の幅・高さに合わせて文字列を加工する

text-overflowプロパティを使う

text-overflowプロパティを用いると、文字列が表示領域からはみ出してしまった場合、はみ出した文字列を省略記号「…」で省略することができます。 尚、text-overflowプロパティを有効にするには、widthプロパティより横幅を指定し、overflowプロパティにvisible以外white-spaceにnowrapを指定する必要があるそうです。

早速サンプルです。

HTML

<h5>text-overflow: ellipsis;</h5>
<p class="textOverflowTest1">
<strong>text-overflow</strong>プロパティを用いると、文字列が表示領域からはみ出してしまった場合、はみ出した文字列を省略記号「…」で省略することができます。
尚、<strong>text-overflow</strong>プロパティを有効にするには、<strong>widthプロパティより横幅を指定</strong>し、<strong>overflowプロパティにvisible以外</strong>、<strong>white-spaceにnowrap</strong>を指定する必要があるそうです。
</p>

<h5>text-overflow: clip;</h5>
<p class="textOverflowTest2">
<strong>text-overflow</strong>プロパティを用いると、文字列が表示領域からはみ出してしまった場合、はみ出した文字列を省略記号「…」で省略することができます。
尚、<strong>text-overflow</strong>プロパティを有効にするには、<strong>widthプロパティより横幅を指定</strong>し、<strong>overflowプロパティにvisible以外</strong>、<strong>white-spaceにnowrap</strong>を指定する必要があるそうです。
</p>

CSS

.textOverflowTest1, .textOverflowTest2 {
	overflow: hidden;
	border: 1px solid #ccc;
	padding: 10px;
	width: 400px;
	background: #eee;
	line-height: 1.0;
	white-space: nowrap;
}

.textOverflowTest1 {
	text-overflow: ellipsis;
	-webkit-text-overflow: ellipsis; /* Safari */
	-o-text-overflow: ellipsis; /* Opera */
}

.textOverflowTest2 {
	text-overflow: clip;
	-webkit-text-overflow: clip; /* Safari */
	-o-text-overflow: clip; /* Opera */
}

実行結果

text-overflow: ellipsis;

text-overflowプロパティを用いると、文字列が表示領域からはみ出してしまった場合、はみ出した文字列を省略記号「…」で省略することができます。 尚、text-overflowプロパティを有効にするには、widthプロパティより横幅を指定し、overflowプロパティにvisible以外white-spaceにnowrapを指定する必要があるそうです。

text-overflow: clip;

text-overflowプロパティを用いると、文字列が表示領域からはみ出してしまった場合、はみ出した文字列を省略記号「…」で省略することができます。 尚、text-overflowプロパティを有効にするには、widthプロパティより横幅を指定し、overflowプロパティにvisible以外white-spaceにnowrapを指定する必要があるそうです。

text-overflowプロパティは値としてellipsis、またはclipが設定できます。ellipsisを指定すると、はみ出した文字列を省略記号「…」で省略します。clipは、はみ出した文字列を切り取るだけで省略記号は付与されません。

また、text-overflowプロパティは、IE6~、Firefox7.0~、Opera9.0~(-o-text-overflow)、Safari1.3~、Chrome1.0~で対応しているそうです。詳細はText-overflow - MDNで詳しく記載されています。 余談ですがtext-overflowプロパティはIE6から独自仕様として誕生し、CSS3の仕様に組み込まれたらしいです。

しかし、この方法だと1つ問題があります。上記ソースを見てお気づきかもしれませんが、このプロパティ、複数行には対応していません

jQueryで表示領域の幅・高さに合わせて文字列を加工する

そこで困った時のjQuery先生の登場です。複数行で表示される文字列に対して省略記号「…」で省略する場合は、以下の処理を行います。

  1. 対象となる要素を、heightにautoを指定し、絶対配置+非表示で複製する
  2. 複製した要素の文字列の末尾から任意の文字数を削除し、省略記号「…」を付与
  3. 指定した高さに収まれば終了。収まらなければ2へ

サンプルは以下の通りです。

HTML

<h5>jQuery版</h5>
<p class="textOverflowTest3">
<strong>text-overflow</strong>プロパティを用いると、文字列が表示領域からはみ出してしまった場合、はみ出した文字列を省略記号「…」で省略することができます。
尚、<strong>text-overflow</strong>プロパティを有効にするには、<strong>widthプロパティより横幅を指定</strong>し、<strong>overflowプロパティにvisible以外</strong>、<strong>white-spaceにnowrap</strong>を指定する必要があります。
</p>

CSS

/* overflow:hidden、heightは必ず指定する */
.textOverflowTest3 {
	overflow: hidden;
	border: 1px solid #ccc;
	padding: 10px;
	width: 400px;
	height: 80px;
	background: #eee;
}

JavaScript

jQuery(function($) {
	$('.textOverflowTest3').each(function() {
		var $target = $(this);

		// オリジナルの文章を取得する
		var html = $target.html();

		// 対象の要素を、高さにautoを指定し非表示で複製する
		var $clone = $target.clone();
		$clone
			.css({
				display: 'none',
				position : 'absolute',
				overflow : 'visible'
			})
			.width($target.width())
			.height('auto');

		// DOMを一旦追加
		$target.after($clone);

		// 指定した高さになるまで、1文字ずつ消去していく
		while((html.length > 0) && ($clone.height() > $target.height())) {
			html = html.substr(0, html.length - 1);
			$clone.html(html + '...');
		}

		// 文章を入れ替えて、複製した要素を削除する
		$target.html($clone.html());
		$clone.remove();
	});
});

実行結果

jQuery版

そこで困った時のjQuery先生の登場です。複数行で表示される文字列に対して省略記号「…」で省略する場合は、以下の処理を行います。 そこで困った時のjQuery先生の登場です。複数行で表示される文字列に対して省略記号「…」で省略する場合は、以下の処理を行います。

これで複数行に対応することができますが、注意点としては文字数があまりにも多いとブラウザ側の処理が重くなってしまいます。サーバサイドで文字数を制限するなどといった対策は必ずしておきましょう!

参考までに、この処理をプラグインにしてみました。探していた方は、是非使ってみてください!

尚、プラグインのご使用は自由ですが、このプラグインを使用して何かしらのトラブルが発生しても、責任を負うことは一切ありませんので、使用する場合は自己責任でお願いします!

jquery.textOverflowEllipsis.js

(function($) {
	$.fn.textOverflowEllipsis = function(config) {
		var defaults = {
			resize: true,
			numOfCharactersToReduce : 1,
			suffix: '...'
		};

		var options = $.extend(defaults, config);

		var TextOverflowEllipsis = {
			init : function($target) {
				$target
					.addClass('textOverflowEllipsis')
					.css({
						overflow: 'hidden'
					});

				// オリジナルの文章を取得・保持する
				var html = $target.attr('data-original', html);
				if (! html) {
					html = $target.html();
					$target.attr('data-original', html);
				}

			},
			execute : function($target) {
				var html = $target.attr('data-original', html);

				// 対象の要素を、高さにautoを指定し非表示で複製する
				var $clone = $target.clone();
				$clone
					.html(html)
					.css({
						display : 'none',
						position : 'absolute',
						overflow : 'visible'
					})
					.width($target.width())
					.height('auto');

				// 複製した要素を一旦追加
				$target.after($clone);

				// 指定した高さになるまで、1文字ずつ消去していく
				while((html.length > 0) && ($clone.height() > $target.height())) {
					html = html.substr(0, html.length - options.numOfCharactersToReduce);
					$clone.html(html + options.suffix);
				}

				// 文章を入れ替えて、複製した要素を削除する
				$target.html($clone.html());
				$clone.remove();
			}
		};

		return this.each(function(index) {
			var $target = $(this);

			TextOverflowEllipsis.init($target);

			TextOverflowEllipsis.execute($target);

			if (options.resize) {
				// ウィンドウリサイズに追従する
				var timerId = null;
				$(window).resize(function() {
					if (timerId) {
						clearTimeout(timerId);
					}

					timerId = setTimeout(function() {
						TextOverflowEllipsis.execute($target);
					}, 100);
				});
			}
		});
	};
})(jQuery);

HTML

<h5>jquery.textOverflowEllipsis.js</h5>
<p class="textOverflowTest4">
jquery.textOverflowEllipsis.jsのサンプルです。jquery.textOverflowEllipsis.jsのサンプルです。jquery.textOverflowEllipsis.jsのサンプルです。jquery.textOverflowEllipsis.jsのサンプルです。jquery.textOverflowEllipsis.jsのサンプルです。
</p>

CSS

/* overflow:hidden、heightは必ず指定する */
.textOverflowTest4 {
	overflow: hidden;
	border: 1px solid #ccc;
	padding: 10px;
	height: 80px;
	background: #eee;
}

JavaScript

$(function() {
	$('.textOverflowTest4').textOverflowEllipsis({
		resize: true, // ウィンドウリサイズ時に追従するか
		numOfCharactersToReduce : 1, // 高さ計算するときに削る文字数
		suffix: '...' // 省略記号
	});
});

実行結果

jquery.textOverflowEllipsis.js

jquery.textOverflowEllipsis.jsのサンプルです。jquery.textOverflowEllipsis.jsのサンプルです。jquery.textOverflowEllipsis.jsのサンプルです。jquery.textOverflowEllipsis.jsのサンプルです。jquery.textOverflowEllipsis.jsのサンプルです。jquery.textOverflowEllipsis.jsのサンプルです。jquery.textOverflowEllipsis.jsのサンプルです。jquery.textOverflowEllipsis.jsのサンプルです。jquery.textOverflowEllipsis.jsのサンプルです。jquery.textOverflowEllipsis.jsのサンプルです。

参考