Web技術系中心に割と何でも更新中

CSSとjQueryで縦横比を判別して画像表示サイズを最適化する方法

Programming Web

Web制作者

Web制作者
「画像サイズの最適化がうまくいかない」
「縦長の画像がスマホで見ると縦方向に伸びてしまうのを解消したい」

こういった要望にお答えします。

本記事の内容

  • CSSとjQueryを使った画像の縦横比を判別して画像サイズを最適化する方法

こんにちは、mineです。
Web制作歴は7年になります。

今や当たり前になったレスポンシブデザイン。
レスポンシブデザインを導入する上で、画像サイズの最適化が一つポイントとして挙げられます。

画像サイズ最適化サンプルCSS

@media screen and (max-width:768px) { 
	img{
		width: 100%;
		height: auto;
	}
}

上記のCSSはレスポンシブデザインにおける<img>タグのサイズの最適化の例です。

画面幅が768px以下の時は<img>タグに対して、横幅にだけwidth:100%;を指定してスマホやタブレットの画面いっぱいに広げて、高さはheight:auto;で自動的に最適化させます。

しかし、この方法だと画像のサイズが横幅に依存する形になり、縦の比率が高い画像は、スマホやタブレットで見たときにかなり縦に伸びてしまう場合があります。これを回避するには画像の縦幅にも最大値を設定する必要があります。

今回試みたのは、下記3点を満たす設定です。

最適化の条件

  • 縦と横で比率の大きい方に合わせて縦横比を保持したままサイズを最適化する
  • 横長画像の場合画像サイズを画面幅いっぱいにあわせる
  • 縦長の画像は最大縦幅を360px、横長の画像は最大横幅を480pxに設定する

CSSのみを使う方法とjQuery(JavaScript)を使う方法2通り試みました。

CSSのみで画像を最適化する方法

CSS

ウェブページに画像を表示する際に、目視で縦長or横長かを判断してそれに応じたクラスを付与して、付与したクラスに対してCSSで最適化させます。

CSSで画像サイズの最大値を設定する

<meta name="viewport" content="width=device-width,initial-scale=1.0" />

レスポンシブにするために、<head>内にviewportを設定します。

img {
	display: block;
	margin: 0 auto 20px;
}
@media screen and (max-width:768px) { 
	/*縦長の画像*/
	img.vertical{
		width:auto;
		max-height:360px;
	}
	/*横長の画像*/
	img.oblong{
		width:100%;
		max-width:480px;
	}
}
  • 横長のクラス:oblong
  • 縦長のクラス:vertical

1.画像の共通設定

display:block;に設定して画像下にマージン持たせています。

2.縦長の画像

<img>の最大縦幅を300pxに設定し、横幅はautoにして縦幅に合わせて最適化します。

3.横長の画像

<img>width:100%;を指定して基本は画面幅に合わせ、最大横幅を480pxに設定します。

CSSでの最適化によるメリット・デメリット

メリット

メリットとしては、縦長、横長を見てそれに対応するクラスを設定するだけという、設定が分かりやすい点です。

デメリット

デメリットは<img>タグ一つ一つにクラスを設定しなくてはならない点です。

例えば、上記の例でいうとoblong、verticalクラスを設定していない場合(最初は最適化されていなくて後に最適化する場合)、一つ一つ縦長横長を見て判断してクラスを設定する必要があります。<img>タグが既に大量に存在している場合などは、非常に効率が悪いです。

jQuery(JavaScript)で縦横比を判別して画像を最適化する方法

jQuery

「CSSのみで画像を最適化する方法」のデメリットの解消にも関係するのですが、クラスを設定する<img>タグが多すぎるなど、影響範囲が大きい場合はjQuery(JavaScript)で縦横の比率から縦長横長を判別して画像を最適化させる方法があります。

jQuery(JavaScript)で画像を最適化

<script type='text/javascript' src='//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js?ver=1.11.3'></script>

jQueryを<head>内に記述します。

// 1.ページを読み込み後に処理を行う
$(window).load(function (){
	// 2.imgタグに対して繰り返し処理を行う
	$('img').each(function(){
	// 3.各要素のサイズ設定
		// 3.1.表示状態の画像の大きさ
		var img_height = $(this).height();
		var img_width  = $(this).width();
		// 3.2.実際の画像の大きさ
		var img = new Image();
		img.src = $(this).attr('src');
		var _width = img.width;
		// 3.3.画面の横幅
		var device_width = $(window).width();
	// 4.縦長横長を判断する
		if((img_width / img_height) >= 1){
			// 4.1.横長の場合
			if(_width <= device_width){
				$(this).css("width", "auto");
			}else{
				$(this).css("width", "100%");
			}
			$(this).css("max-width", "480px");
		}else{
			// 4.2.縦長の場合
			$(this).css("max-height", "360px");
			if($(this).width() >= device_width){
				$(this).css("width", "100%");
			}else{
				$(this).css("width", "auto");
			}
		}
	});
});

1.ページを読み込み後に処理を行う

画像を全て読み込んだ後に、画像の最適化処理を行います。

2.<img>タグに対して繰り返し処理を行う

.each()で「<img>タグ」に対して繰り返し処理を行います。

3.各要素のサイズ設定

画像の最適化処理を行うにあたり、画像や画面幅などのサイズを取得します。

3.1.表示状態の画像の大きさ

$(this).height()$(this).width()で表示時の画像の縦幅横幅を取得します(元画像の大きさではない)。

3.2.実際の画像の大きさ

実際の画像の大きさ(元画像の大きさ)を取得します。

3.3.画面の横幅

$(window).width()でデバイスの画面の横幅を取得できます。

4.縦長横長を判断する

img_width(表示中画像の横幅)÷img_height(表示中画像の縦幅)が1以上なら横長1より小さかったら縦長です。

4.1.横長の場合

まずJavaScriptを実行する前の状態で、実際の画像サイズが画面幅よりも小さいか等しい場合は、.css()width:auto;を設定します(100%にしてしまうと、画像が粗く表示されてしまいます)。

実際の画像サイズが画面幅よりも大きい場合はwidth:100%で画面幅に合わせ、max-width:480pxを指定します。

4.2.縦長の場合

max-height:360px;を指定します。

画像の表示サイズが画面幅よりも大きいか等しい場合、width:100%で横幅を画面幅に合わせるようにします。

画像の表示サイズが画面幅よりも小さい場合、width:auto;で横幅を縦幅に合わせるようにします。

jQuery(JavaScript)による画像サイズ最適化によるメリット・デメリット

メリット

<img>タグ一つ一つに対して個別に設定を行う手間が省けます。

デメリット

どうしても画像をすべて読み込んだ後に画像に対して最適化処理を行うので、ページの読み込み時間がかかります。

また、最大横幅・縦幅の値を変えたいという場合はその都度CSS・jQuery(JavaScript)で設定を行う必要があります。

まとめ

基本はCSSで個別に指定する方法がjQuery(JavaScript)に比べてサイト表示は早く、最大幅の変更などはCSSでやるほうが楽です。

<img>タグの記述があまりにも多すぎて、一つ一つクラス指定するのが大変という場合は、jQuery(JavaScript)での処理が有効かなと思います。

おすすめ記事 【体験談】弁護士の退職代行で有給30日分を取得した話

おすすめ記事 「知らないから落ちる面接の4点減点法」で面接に挑んだ結果