Skip to content

Instantly share code, notes, and snippets.

@moxie
Last active October 5, 2018 17:55
Show Gist options
  • Save moxie/5e99743fbb6e517b1ccf to your computer and use it in GitHub Desktop.
Save moxie/5e99743fbb6e517b1ccf to your computer and use it in GitHub Desktop.
module ResponsiveImageHelper
def responsive_image_tag(srcset, **options)
# Sort the images in the srcset by their value (Their pixel or '1x' width. Either should sort properly).
sorted_srcset = srcset.sort_by { |_, value| value }
# Use the smallest image in the given set as the image fallback. Might not be necessary with Picturefill.
options[:src] = image_path_or_url_for_string(sorted_srcset.first[0])
# Build the srcset attribute. Iterates through the given srcset hash, if a key contains '//' it
# is assumed to contain a URL and will not use Rails image_path.
options[:srcset] = sorted_srcset.map { |k, v| "#{image_path_or_url_for_string(k)} #{v}w" }.join(', ')
# Creates a little DSL for the sizes option. The gte_sm, gte_md, etc keys line up with
# Bootstraps default breakpoints. You could define your breakpoints somewhere else that
# makes sense and adapt this to your needs.
#
# Build the sizes attribute if necessary. If the sizes option is a string, just
# pass that through to the final img tag.
if options[:sizes].present? && options[:sizes].is_a?(Hash)
options[:sizes] = options[:sizes].map do |media_query, length|
if media_query.is_a? Symbol
case media_query
when :gte_sm
"(min-width: 768px) #{length}"
when :gte_md
"(min-width: 992px) #{length}"
when :gte_lg
"(min-width: 1200px) #{length}"
when :default
length.to_s
else
nil
end
else
"#{media_query} #{length}"
end
end.join(', ')
end
# Return the responsive image tag
tag(:img, options)
end
# Determines if a given string contains a URL or a path by checking
# for the presence of //.
def image_path_or_url_for_string(image_str)
image_str =~ /\/\// ? image_str : image_path(image_str)
end
end
@murdoch
Copy link

murdoch commented Oct 5, 2018

Nice. It's worth pointing out that Rails image_tag supports srcset now: https://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html#method-i-image_tag although your helper does add some neat features.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment