Awesome
jekyll_img
![Gem Version](https://badge.fury.io/rb/jekyll_img.svg)
Jekyll_img
is a Jekyll plugin that embeds images in HTML documents, with alignment options,
flexible resizing, default styling, overridable styling, an optional caption, an optional URL,
and optional fullscreen zoom on mouseover.
Muliple image formats are supported for each image. The user’s web browser determines the formats which it will accept. The most desirable formats that the web browser supports are prioritized.
For example, if an image is encloded in webp
, png
and gif
filetypes,
and the user’s web browser is relatively recent,
then webp
format will give the fastest transmission and look best.
Older browsers, which might not support webp
format,
would give best results for png
format.
Really old web browsers would only support the gif
file type.
Please read the next section for details.
I explain why the webp
image format is important in
Converting All Images in a Website to webp
Format.
That article also provides 2 bash scripts for converting existing images to and from <code>webp</code> format.
See demo/index.html for examples.
External Images
Images whose src
attribute starts with http
are not served from the Jekyll website.
The jekyll_img
plugin generates HTML for external images using an img
element with a src
attribute as you might expect.
Image Fallback
For local files (files served from the Jekyll website),
the jekyll_img
plugin generates HTML that falls back to successively less performant
formats.
This is made possible by using a
picture
element.
At least one version of every image are required.
Supported filetypes are:
svg
, webp
, apng
, png
, jpg
, jpeg
, jfif
, pjpeg
, pjp
, gif
, tif
, tiff
, bmp
, ico
and cur
.
For example, an image file might have the following verions: blah.webp
, blah.png
and blah.jpg
.
Given a tag invocation like {% img src='blah.webp' %}
,
the plugin would generate a picture
element that contains an img
sub-element with the given src
attribute,
and a source
element for each related image (blah.png
and blah.jpg
).
Conceptually, the generated HTML might look something like this:
<picture>
<source srcset="blah.png" />
<source srcset="blah.jpg" />
<img src="blah.webp" />
</picture>
If no filetype is given for the image, webp
is assumed.
For example, these two invocations yield the same result,
if blah.webp
exists on the Jekyll website:
{% img src="blah" %}
{% img src="blah.webp" %}
If both blah.webp
and blah.png
were available,
the above would fetch and display blah.webp
if the web browser supported webp
format,
otherwise it would fetch and display blah.png
.
If the browser did not support the picture
element,
the img src
attribute would be used to specify the image.
Supported Filetypes
The following are listed in order of priority. See MDN for more information.
Filetype | MIME type |
---|---|
svg | image/svg+xml |
avif | image/avif |
webp | image/webp |
apng | image/apng |
png | image/png |
jpg , jpeg , jfif , pjpeg , pjp | image/jpeg |
gif | image/gif |
tif , tiff | image/tiff |
bmp | image/bmp |
ico , cur | image/x-icon |
Because avif
is problematic as of 2024-01-08 on Firefox, Chrome and Safari, it is not supported yet.
Demo
Run the demo website by typing:
$ demo/_bin/debug -r
... and point your web browser to http://localhost:4011
Usage
{% img [Options] src='path' %}
Options
are:
attribution
Seejekyll_plugin_support
.align="left|inline|right|center"
Default value isinline
alt="Alt text"
Default value is thecaption
text, if providedcaption="A caption"
No default valueclasses="class1 class2 classN"
Extra <img> classes; default isrounded shadow
id="someId"
No default valuenofollow
Generatesrel='nofollow'
; only applicable whenurl
is specifiedsize='eighthsize|fullsize|halfsize|initial|quartersize|XXXYY|XXX%'
Defines width of image.initial
is the default behavior.eighthsize
,fullsize
,halfsize
, andquartersize
are relative to the enclosing tag's width.- CSS units can also be used, for those cases
XXX
is a float andYY
isunit
(see below)
style='css goes here'
CSS style for <img>; no defaulttarget='none|whatever'
Only applicable whenurl
is specified; default value is_blank
title="A title"
Default value iscaption
text, if providedurl='https://domain.com'
No default valuewrapper_class='class1 class2 classN'
Extra CSS classes for wrapper <div>; no default valuewrapper_style='background-color: black;'
CSS style for wrapper <div>; no default valuezoom
Fullscreen zoom on mouseover; presse escape or click outside image to dismiss
unit
is one of: Q
, ch
, cm
, em
, dvh
, dvw
, ex
, in
, lh
,
lvh
, lvw
, mm
, pc
, px
, pt
, rem
, rlh
, svh
, svw
, vb
,
vh
, vi
, vmax
, vmin
, or vw
.
CSS classes referenced by the jekyll_img
plugin are in
demo/assets/css/jekyll_img.css
and
demo/assets/css/jekyll_plugin_support.css
.
CSS marker classes are included, so CSS selectors can be used for additional styling.
Configuration
By default, errors cause Jekyll to abort.
You can allow Jekyll to halt by setting the following in _config.yml
:
img:
die_on_img_error: true
pry_on_img_error: true
Design
The most significant design issue was the decision that image size and formatting should not change
whether it had a caption.
HTML captions exist within a <figure />
element, which also surrounds the image.
I also wanted to ensure that captions would wrap text under an image, and would not be wider than the image they were associated with.
CSS behavior differs for <figure />
and <img />
.
For example, centering, floating right and left.
That means the CSS and where it would need to be applied are completely different for
naked <img />
and <figure />
tags.
Handling all possible situations of these two scenarios would significantly raise the complexity of the plugin code.
I know, because I went down that rabbit hole.
Wrapper <div />
To make the plugin code more manageable,
the plugin always encloses the generated HTML & CSS within a wrapper <div />
.
The wrapper allows for a simple, consistent approach regardless of whether a caption is generated or not.
The wrapper width is identical to the displayed image width.
Within the wrapper <div />
, the embedded <img />
is displayed with width=100%
.
If a caption is required, the generated <figure />
only makes the space taken by the generated HTML longer;
the image’s width and height are not affected.
The wrapper will not exceed the width of the tag that encloses it if the size
parameter has values
eighthsize
, fullsize
, halfsize
, initial
or quartersize
.
The wrapper's width can be defined independently of its enclosing tag by using
CSS units
for the size
parameter:
Q
, ch
, cm
, em
, dvh
, dvw
, ex
, in
, lh
,
lvh
, lvw
, mm
, pc
, px
, pt
, rem
, rlh
, svh
, svw
, vb
,
vh
, vi
, vmax
, vmin
, or vw
.
Using CSS units means that large enough values could cause the image to exceed the width of its enclosing tag.
Installation
Add this line to your Jekyll project's Gemfile, within the jekyll_plugins
group:
group :jekyll_plugins do
gem 'jekyll_img'
end
And then execute:
$ bundle
Additional Information
More information is available on Mike Slinn’s website.
Development
After checking out the repo, run bin/setup
to install dependencies.
You can also run bin/console
for an interactive prompt that will allow you to experiment.
To build and install this gem onto your local machine, run:
$ bundle exec rake install
jekyll_img 0.1.0 built to pkg/jekyll_img-0.1.0.gem.
jekyll_img (0.1.0) installed.
Examine the newly built gem:
$ gem info jekyll_img
*** LOCAL GEMS ***
jekyll_img (0.1.0)
Author: Mike Slinn
Homepage:
https://github.com/mslinn/jekyll_img
License: MIT
Installed at: /home/mslinn/.gems
Generates Jekyll logger with colored output.
Debugging
You can cause pry
to open when an ImgError
is raised by setting pry_on_img_error
in _config.yml
.
Pry_on_img_error
has priority die_on_img_error
.
jekyll_img:
die_on_img_error: false # Default value is false
pry_on_img_error: true # Default value is false
Testing
Examine the output by running:
$ demo/_bin/debug -r
... and pointing your web browser to http://localhost:4444/
Unit Tests
Either run rspec
from Visual Studio Code's Run and Debug environment
(<kbd>Ctrl</kbd>-<kbd>shift</kbd>-<kbd>D</kbd>) and view the Debug Console output,
or run it from the command line:
$ rspec
Build and Push to RubyGems
To release a new version,
-
Update the version number in
version.rb
. -
Commit all changes to git; if you don't the next step might fail with an unexplainable error message.
-
Run the following:
$ bundle exec rake release
The above creates a git tag for the version, commits the created tag, and pushes the new
.gem
file to RubyGems.org.
Contributing
- Fork the project
- Create a descriptively named feature branch
- Add your feature
- Submit a pull request
License
The gem is available as open source under the terms of the MIT License.