mmistakes / minimal-mistakes

:triangular_ruler: Jekyll theme for building a personal site, blog, project documentation, or portfolio.
https://mmistakes.github.io/minimal-mistakes/
MIT License
12.24k stars 25.36k forks source link

Responsive header overlay images (srcset etc.) #1303

Closed ohadschn closed 6 years ago

ohadschn commented 6 years ago

Header images tend to be very large, often measuring several megabytes in size. Using responsive images, they can be reduced by significant factors for smaller displays (which tend to have slower connection too), potentially to the tune of 90%.

Support for this could be added by something like

header:
  overlay_image: /assets/images/unsplash-image-1.jpg
  overlay_image_mid: /assets/images/unsplash-image-1-mid.jpg
  overlay_image_small: /assets/images/unsplash-image-1-small.jpg

(Of course if mid/small aren't specified, the behavior would stay the same as it is now)

mmistakes commented 6 years ago

I'm with you that responsive images are an important optimisation to make. I do this with my own site.

Just not convinced the added complexity is worth it for the theme since there is really no good way to do it without a plugin or extra tooling. YAML variables go down the path of extra maintenance for the user to.

I'm really into Gatsby a newish static site generator that uses React. It has some really nice transformer plugins that take care of writing img elements with the appropriate srcset markup and generating sized images with Sharp.

It's smart enough to do this for all images in your Markdown content which is the holy Grail as far as I'm concerned. Something I haven't seen done with Jekyll yet. Unless you count custom Liquid tags which isn't all that elegant and pollutes the source content making it less portable.

ohadschn commented 6 years ago

I agree that automatic generation would be the holy grail, but like you said Jekyll doesn't support it yet and extra plugins or tooling might complicate things.

What I'm suggesting is a manual approach where the user adds the YAML variables I mentioned above, and creates the scaled image sets himself. Sure that adds a bit more maintenance, but users who don't use this feature will not be affected.

My use case, which should be a fairly common one going by the WordPress theme, is a single header image that's present in all blog pages. It would be a simple one-time matter to create a few scaled versions of it and configure them in the YAML.

mmistakes commented 6 years ago

I'm probably starting to sound like a broken record with all these requests, but I'm trying to balance a lot of things. Every new feature or enhancement has a cost, and this one is fairly high in my book.

Sure adding some extra YAML variables seems like the lowest cost of the bunch as it can be opt'd in. But doing so introduces a mess of Liquid spaghetti code for something I really don't think many people will go to the trouble of using.

Not to mention it'll be a messy solution as srcset is used for img elements. You're asking for support to the "overlay image" which doesn't use an img element at all. The images are added via inline CSS which uses a completely different syntax for supporting "background" responsive images.

And once it is advertised that the theme can support "responsive" header images, the expectation would be to do that elsewhere... and rightfully so.

I'd be up for supporting responsive images that were triggered via a Jekyll plugin that did all the heavy lifting as far as image generation and possibly markup are concerned. The issue there is I've used all of the available solutions and they all kind of stink and have drawbacks in their own way.

I've done a lot of research and experimenting with responsive images on Jekyll powered sites over the years, and it's a shit show. Nothing comes close to what Gatsby is doing with its modern toolset and I'm not one for adding half-baked features into my projects.

This is another one of those features that Wordpress has spoiled people as you can pretty much set it and forget... something that just isn't the case with Jekyll. I think that's were the friction I'm facing comes from with the theme. Features like this are more of a framework slash infrastructure thing versus something at the theme level. Jekyll has the hooks to do it, but the plugins aren't really there to support it. And I know zero about Ruby to help in that regard.

mmistakes commented 6 years ago

You could also use a service like Cloudinary (they have a free tier) to serve up responsive images. Without modifying the theme you could load their Javascript, point it at the feature image class and it'll automatically generate responsive images.

ohadschn commented 6 years ago

The only thing I disagree with is your all-or-nothing approach. If you have a low hanging fruit case you can handle (don't know if header images can be classified as such) I think it's totally cool, and no further "expectations" have to be assumed or accepted on your part.

Cloudinary looks really cool, I will check it out. I knew CloudFlare were doing this but not on the free tier. Looks like a bunch of Israeli guys too, maybe I'll get special treatment ;)

ohadschn commented 6 years ago

So in case anyone is interested, here's how you use Cloudinary with header (hero) images:

  1. Sign up to Cloudinary and upload your image of choice (highest quality you have)
  2. Remove existing header image definitions from your _config.yml
  3. Add the following to your _config.yml:
    footer_scripts:
    - /assets/js/main.min.js
    - https://cdnjs.cloudflare.com/ajax/libs/cloudinary-core/2.3.0/cloudinary-core-shrinkwrap.min.js
    - /assets/js/images.js
  4. Create /assets/js/images.js with the following content:
    
    var cl = cloudinary.Cloudinary.new({cloud_name: "YOUR_CLOUD_NAME"});
    var img = cl.image("YOUR_IMAGE_NAME", 
    { 
    width: "auto", 
    dpr: "auto", 
    responsive: "true",
    crop: "scale", 
    responsive_placeholder: "blank"
    });
    $(img).addClass("page__hero-image");

$heroDiv = $('

'); $heroDiv.append(img); $heroDiv.insertAfter(".masthead");

cl.responsive();


(substituting `YOUR_CLOUD_NAME` and `YOUR_IMAGE_NAME` with the proper Cloudinary values)

@mmistakes looks OK?
stale[bot] commented 6 years ago

This issue has been automatically marked as stale because it has not had recent activity.

If this is a bug and you can still reproduce this error on the master branch, please reply with any additional information you have about it in order to keep the issue open.

If this is a feature request, please consider whether it can be accomplished in another way. If it cannot, please elaborate on why it is core to this project and why you feel more than 80% of users would find this beneficial.

This issue will automatically be closed in 7 days if no further activity occurs. Thank you for all your contributions.