LoginSignup
9
7

More than 5 years have passed since last update.

image_tagでsrcset属性を使いたいときのTips(carrierwave)

Last updated at Posted at 2018-02-21

image_tagで画像を表示させる際の話。
ディスプレイがretinaの場合、画像のサイズによっては画像がぼやけて表示されます。

その時に登場するのがsrcsetです。

retinaに対応させた画像表示の方法はcssやjsを使った方法もありますが、今回はhtml側で呼び出す画像を選別できるようにします。

今回はその中でも2パターン詳解します。
一つ目は、carrierwaveによる画像投稿をしていて、app/public/uploads 配下に画像が配置されている場合
二つ目は、ハードコーディングで画像リンクを明記し、app/assets/images 配下に画像が配置されている場合

carrierwaveを使って画像の投稿をしているパターン

例えば縦100px横200pxの画像を表示するとします。
まず、carrierwaveのimage_uploader.rbにversionを追加します。
versionの名前は適当でも良いですが、画像サイズが明記されていたほうが管理しやすいです。

image_uploader.rb

require 'carrierwave/processing/mime_types'
class ImageUploader < CarrierWave::Uploader::Base
  include CarrierWave::MiniMagick
  include CarrierWave::MimeTypes
  process :set_content_type

  version :size_100_200 do
    process resize_to_fill: [100, 200]
  end

  version :size_100_200_for_retina do
    process resize_to_fill: [200, 400]
  end
// 省略
end

resize_to_fillやresize_to_fillとはなんぞや!?という方はこちらの記事を参考にしてください。

これにより画像が2種類生成されるようになります。

呼び出し時は区別するために、画像のリンクの末尾に画面サイズを表す2xを付与します。

retinaのときは
srcset="hogehoge.jpg 2x"
と記述します。

呼び出し時に毎回書くのは面倒なのでhelperメソッドを呼び出すことにします。

image_helper.rb
  def img_2x(url)
    "#{url} 2x"
  end

呼び出しの記述に移りましょう。

_product.html.haml
= image_tag(product.image_url(:size_100_200), srcset: img_2x(product.image_url(:size_100_200_for_retina), alt: product.title)

これで自動的にブラウザが判別してくれるようになります。
どちらも呼び出してその分ダウンロードに時間がかかる、ということは起きないです。
ありがたいですね〜〜

ファイル名を指定して呼び出すパターン

あまり考えずに書くと、下のようになりますね。

= image_tag('japan.jpg', srcset: "japan@2x.jpg 2x", alt: 'japan')

先程のパターンだとsrcsetを記述すれば、簡単に実現できそうですが、うまく行きませんでした。

調べた所、この記事が参考になりました。
https://gist.github.com/mrreynolds/4fc71c8d09646567111f

これを先程のimage_helper.rbに追記します。

image_helper.rb

def img_2x(url)
    "#{url} 2x"
end

def image_set_tag(source, srcset = {}, options = {})
  srcset = srcset.map { |src, size| "#{path_to_image(src)} #{size}" }.join(', ')
  image_tag(source, options.merge(srcset: srcset))
end

呼び出しの記述に移ります。

_product.hmtl.haml
= image_set_tag('japan.jpg', "japan@2x.jpg" => "2x", alt: 'japan')

これですっきり書けました。

まとめ

retinaが普及して以来、実装側も画像サイズを複数枚用意することも増えました。
ユーザーは美しい画像が表示されるのを当り前のように期待しているので、期待に添うような画像表示ができると良いですね!

9
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7