A markdown-it plugin to set aspect-ratio of responsive images, make them lazy loading, async decoding, and to make videos responsive.


Responsive images can create cumulative layout shifts (CLS) when loaded, because it´s difficult to get their height correct when their width is flexible. Check „Setting Height And Width On Images Is Important Again“ to get a comprehensive view about the problem. The CSS property aspect-ratio is around the corner and will help solving the CLS problem for responsive images.

The markdown-it-fitmedia plugin makes use of aspect-ratio by analyzing each of your referenced images, determining its dimensions, and setting the aspect-ratio based on the dimensions of the image. By default, the plugin will also add the loading="lazy" and decoding="async" html attributes to your images.


![Image of Spitfire tool](/img/spitfire/spitfire.jpg)

will become

<img alt="Image of Spitfire tool" src="/img/spitfire/spitfire.jpg" loading="lazy" decoding="async" style="aspect-ratio:750/388;" width="750" height="388">

Also, html in your markdown, like for example

<img alt="" src="/img/spitfire/spitfire.jpg" >
<figcaption>Image of Spitfire tool</figcaption>

will be transformed into

<img alt="" src="/img/spitfire/spitfire.jpg" loading="lazy" decoding="async" style="aspect-ratio:750/388;" width="750" height="388">
<figcaption>Image of Spitfire tool</figcaption>

Wrapping media

markdown-it-fitmedia carries an adoption of the original fit-vids script to make iframe and video tags responsive. Embedded videos are not automatically responsive or fluid. They come with a fixed setting for width and height. To make them responsive while keeping aspect ratio, they are embedded into a wrapper element. The wrapper receives some clever padding and positioning, and as a last step the fixed dimensions are removed from the video. The technique has been described by Thierry Koblentz in his A List Apart article “Creating Intrinsic Ratios for Video” in 2009.

For example, this

<iframe src="" width="600" height="338"></iframe>

will become

<div class="fit-media" style="position:relative; height:0; padding-bottom:56.333333333333336%;aspect-ratio:600/338;">
<iframe src="" style="position:absolute; top:0; left:0; width:100%; height:100%;">


npm i markdown-it-fitmedia


var markdownIt = require('markdown-it');
var markdownItFitMedia = require('markdown-it-fitmedia');

html: true
.use(markdownItFitMedia, { //default options
imgDir: '',
lazyLoad: true,
decoding: 'async',
aspectRatio: true,
imgSizeHint: true,
fitWrapElements: ['iframe', 'video']