×

CSSとjQuery(JavaScript)で画像の表示サイズを縦長or横長を判断して最適化してみた

2017年1月8日 コーディング

四角

今や常識となったレスポンシブデザイン。

レスポンシブデザインは、メンテナンスのしやすさやGoogleの推奨するデザインということもあり、導入しているサイトも多いですね。

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

画像に対して、横幅にだけwidth:100%を指定してスマホやタブレットの画面いっぱいに広げて、高さは自動調整するというやり方が一番シンプルなやり方です。

レスポンシブデザインにおける画像(imgタグ)サイズの最適化というと、下記のような例があります。

@media screen and (min-width:320px) { 
    img{
        width:100%;
        max-width:480px;
    }
}

この場合、画面幅が320pxより大きい場合、画像幅を画面いっぱいにして、最大幅を480pxにするという設定をしています。

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

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

【最適化の条件】

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

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

CSSのみで目視で縦長横長を判断して画像を最適化する方法

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

下記DEMO1をクリックして、デモページで表示を確認してください。

DEMO1

スマホ、タブレット、PCなどの各種デバイスで確認できます。
※PCだったら各ブラウザのデベロッパーツールなどでスマホ・タブレットでの表示を確認できます。

CSSで画像サイズを最適化


レスポンシブにするためにviewportを設定します。


/*1.画像の共通設定*/
img {
    display: block;
    margin: 0 auto 20px;
}
/*2.縦長の画像*/
img.vertical{
    width:auto;
    max-height:300px;
}
/*3.横長の画像*/
img.oblong{
    width:100%;
    max-width:480px;
}
  • 横長のクラス:oblong
  • 縦長のクラス:vertical

1.画像の共通設定
displayプロパティをblockに設定して画像下にマージン持たせています。

2.縦長の画像
縦の最大幅を300pxに設定し、横幅はautoにして縦幅に合わせるようにします。

3.横長の画像
widthプロパティに100%を指定して画面幅に合わせ、横の最大幅を480pxに設定します。

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

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

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

例えば、上記の例でいうとoblong、verticalクラスを設定していないimgタグが既に大量に存在している場合、一つ一つ縦長横長を見て判断してクラスを設定する必要があります。

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

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

下記DEMO2をクリックして、デモページで表示を確認してください。

DEMO2

スマホ、タブレット、PCなどの各種デバイスで確認できます。
※PCだったら各ブラウザのデベロッパーツールなどでスマホ・タブレットでの表示を確認できます。

jQuery(JavaScript)で画像を最適化


jQueryを読み込みます。

// 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", "300px");
            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:300pxを指定します。

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

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

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

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

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

まとめ

基本はCSSで個別に指定する方法がjQuery(JavaScript)に比べて読み込み時間も少ないし、最大幅の変更などはCSSでやるほうが楽です。

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

関連記事