Responsive and sustainable images in markdown

Responsive and sustainable images in markdownby Injenieroupdated 30 Jul 2025 · Sustainable Web

Markdown is a fantastic tool for creating and managing content on the web, however it doesn’t allow you to create certain advanced HTML attributes like srcset in a simple way. In this guide we conceptually introduce what responsive and sustainable images are on the web along with a possible solution based on the Haskell language with MMark library.

Introduction

One of the primary goals of Markdown is to be simple to read and write and ideally to separate the content layer from the publishing layer. However, depending on the use case, some authors prefer a little more control over publishing, such as defining certain attributes of an element inside a markdown file. Defining certain attributes in images is a typical example, especially if you want them to be responsive and sustainable.

The canonical way to create images in markdown is syntax:

MARKDOWN

![alt description](image.avif)

which is transformed into the HTML equivalent of:

HTML

<img alt="alt description" src="image.avif">

Something as simple as defining the size of an image is not possible in Markdown syntax. However, Markdown allows the creation of HTML directly and you just type:

MARKDOWN

Some paragraph text
<img alt="alt description" src="image.avif" width=300 height=300>
More text

However, what happens when you use strict Markdown libraries, which do not allow you to write direct HTML in the file, or you simply prefer not to add HTML but to use native Markdown syntax?

One solution is to use a Markdown variant (flavor) that allows such syntax. The problem with this is that you lose standardization 1, or it may be a non-viable option (the one who makes the decision is not the one who edits the files).

Another, simpler solution, which doesn’t involve changing Markdown variants or writing HTML in the markdown file, is to use CSS. A global rule can be defined as:

CSS

img {width:200px; height:200px;}

Which affects all images. Or you can define a rule for specific cases by identifying the element in question via CSS selectors.

For example:

CSS

p:nth-of-type(3) > img {width:200px; height:200px;}

It should be noted that a css rule can also be defined as:

CSS

img {width:100%; height:auto;}

which solves the responsiveness problem for one of the most common use cases, which is the case where you want the image to be smaller, but never exceed the original file size.

Although this solution is practical, with just one line of code, producing responsive images if viewed from the cell phone, it is not sustainable because it is not efficient. If the original file is 1200 x 600 pixels with file size of 1MB, when visiting that page from a mobile device with a resolution width of let’s say 600px, then the file will be displayed at most 600 x 300 pixels however 1MB will still be transferred.

A brief parenthesis of properties of a web image

It is important to note that different industries have different terms and nomenclature. Printers, photographers (and camera producers), hardware producers, and web designers can use the same word size or resolution to refer to different attributes or aspects of an image in different media and contexts (printed, in-camera, on a computer, on a screen).

The terms used in this article are for the web context, which may differ from the print context

  • pixel: It is the smallest possible element in a raster image that can be manipulated by software. Or in other words, it is a sample of an image where the more you sample, the more accurate the representation is. A pixel has no intrinsic size, but when printed or displayed then a pixel has a physical size (dimension) and a density (ppi).

  • dimensions of an image: It is the height by width in pixels. Example: an image of 200 x 200 pixels.

  • ppi pixel density: It is a measure of image quality, which is noticeable when viewing it in some medium (print, screen, etc). It is a measure of pixel density measured as “pixels per inch” (ppi) where the term inch refers to the actual size of the screen or medium. That is, two images of the same dimensions in pixels, for example 300 x 300, can have different ppi, one 150 ppi and the other of 75 ppi, which means that although both will look of the same dimension on the screen, one will have half the pixels making it look “pixelated” faster when zooming.

raster image: An image that can be digitally represented using pixels. From now on, when we refer to an image without indicating its type, we will refer to images of this type. This includes typical image formats on the web such as .jpg, .png, .jpeg, .webp, .avif, etc. It should be noted that .svg format images or so-called vector images, are not raster images and can change their dimensions without losing quality. Note that the process of transforming an image to svg is called vectorization and that the opposite (e.g. from svg to png) is called rasterization.

  • screen resolution: We refer to how many pixels of width and height a device or monitor supports. For example, a 1920 x 1080 pixel resolution monitor or one called 4K 3840×2160. We will also call it screen size or dimensions.

  • file size of an image: We will use the term file size as an indicator of how many bytes an image has. Kilobytes (KB), megabytes (MB), etc. Example: an image file size of 250KB.

  • Image compression: Methods of reducing the cost of storing and transporting a digital image. It can be “lossy” or “lossless”, where loss refers to differences from the original file before and after compression. For certain types of files, losses are acceptable (e.g. two pixels together that have a minimal color variant can be defined from the same color) which depending on the number of pixels is imperceptible to the human eye. JPEG is an example of a “lossy” algorithm and PNG is an example of a “lossless” algorithm. WEBP and AVIF are examples that can be used by both algorithms.

Responsive and sustainable images

By sustainable we mean that they are efficient in their compression and transfer, without needing to transfer more bytes than necessary for each consumption made by different devices. This involves using more efficient compression formats such as .avif and .webp on the one hand, and on the other optimizing the requests made by the browser by requesting smaller files when it makes sense, along with caching.

Responsive means, they are appropriately displayed according to the resolution and pixel density of the device from which they are viewed.

CSS has great responsiveness properties, being very interesting the property image-set() 1 that allows the browser to choose the appropriate CSS images from a defined set, especially useful for cases of mobile devices with high pixel density.

However, CSS images do not have ALT description losing SEO. Also defining the image files in the CSS we consider it as something for particular aesthetic design events (e.g. a background image on a certain page) and as exceptions rather than the norm. In fact, if you use markdown, it’s natural to define images as part of and within the content. For the same reason, we are interested in responsive attributes in HTML images.

It basically translates to the use of the HTML element <picture> and/or to the use of the srcset HTML attribute together with the loading attribute of the <img> element.

The HTML element <picture> is used to make a change of “art direction” which is nothing more than using modified or cropped images according to different screen sizes. A typical example is the case of a “wide” or “landscape” image in a full-width page header, where a cat appears in the middle. Users who see the image from desktop will not have problems, but from mobile it is possible that the cat will not be seen. The <picture> element solves the problem by delivering different versions of the image for different screen sizes. In turn, it saves bandwidth and improves page loading by loading the most appropriate image according to screen size. It should be noted that the <picture> element allows the programmer to define exactly what he wants and the browser must comply with this rule, unlike the srcset attribute in the <img> element that delivers “hints” to the browser where it is the browser who decides which file to display.

An interesting aspect from the point of view of web sustainability is to let the browser make certain optimization decisions because it has more information about the user such as bandwidth, type of connection, etc, being able to adapt effectively with less explicit code.

The srcset attribute allows the browser to have different file options for an image depending on variables such as screen size, connection width, pixel density capacity of the device among others. In turn, it allows the developer to influence this decision by using css “media queries” that set rules according to the size of the screen, via the use of another attribute of the <img> element called sizes. Due to both of these reasons, we will focus on using the srcset attribute along with sizes in the HTML <img> element as a simple way to achieve responsive and sustainable images on the web.

Example of an HTML image using srcset and sizes:

HTML

<img src="image.jpg" width="400" height="400" srcset="image_400.avif 400w, image_800.avif 800w, image_1000.avif 1000w" sizes="(max-width:600px) 90vw, (max-width:1200px) 45vw, 1000px">

In this example we are giving the following information to the browser: you have 3 files to choose from, where their intrinsic widths are 400px, 800px and 1000px respectively. When the screen width is less than 600px, the image should be displayed at 100% of the width of the device, when the screen width is between 600px and 1200px the image is displayed at 45% of the width of the device (for example in a 2-column layout), and finally when the width of the screen is greater than 1200px, the image is shown with a width of 1000px.

srcset defines a comma-separated list, being able to specify files according to their pixel density denoted by a letter x, or according to their intrinsic width denoted by the letter w. Using the srcset with pixel density is useful especially in case of using retina-type devices. On the other hand, by using width instead of density, it allows you to use the sizes attribute, giving more information to the browser who will be able to make intelligent decisions. In practice, this attribute is automatable, defining a set of image sizes for each image according to some business rule. For example, have sizes small, medium, large.

sizes optionally accepts CSS Media Queries that orient (but do not oblige) the browser when the size of the device’s screen is met and indicates the width that the image should occupy on the screen in question. It is also a comma-separated list. With this information, the browser can make more accurate and efficient decisions. It should be noted that this attribute is complex and depends on how the image is displayed on the device, which is only known for sure after it is rendered. For example, if the image is displayed in 2 columns on devices up to 800px, then the value of sizes could be (max-width:800px) 50vw. However, if there are margins or lateral padding, the value is less than 50vw. In addition, css is being added in the HTML which is an anti-pattern by not separating structure and style layer. However it is the way to deliver useful information to the browser before loading css and js files.

Defining the sizes attribute is complex, with a not insignificant incorrect usage rate, according to some web statistics made by Web Almanac (recommended reading) Statistics of use of images and attributes on the web, and there are some utilities to correctly determine the values. However, our recommendation is to simplify the layout of the pages and establish rules that make sense for most cases on each page. For example, the site’s blog of https://web.dev uses the ‘(max-width: 840px) 100vw, 856px’ rule which says that all images on screens smaller than 840px are displayed at full device width, and that when the screen width is greater than 840px, the image is displayed at 856px width. Worth mentioning that the blog CSS Tricks follows a similar “spirit” of “simplifying web development” defining 96vw instead of 100vw as “telling the browser is almost full width but with some margins”.

Finally, it is worth mentioning that the loading attribute of the <img> element with a value “lazy” is an excellent ally for sustainable images but that it should be used depending on the initial visibility of the image.

  • If the image is above the fold (i.e. what is seen before scrolling), using loading="lazy" is an anti-pattern making loading slower, and therefore this attribute should not be added for such images. Depending on the use case, you can add the attribute fetchpriority="high" indicating that you want to load said asset with a certain priority (such as in the case that it is the largest element in the initial load).

  • If the image is below the fold, i.e. to see them the user must scroll, then it is recommended to add the attribute loading="lazy" that tells the browser not to load the images until necessary, which translates into being sufficiently close to the “viewport” (visible view of the browser) according to the implementation of each browser. In other words, let the browser make decisions based on context to avoid loading an image unnecessarily.

Using srcset and sizes in conjunction with lazy and fetchpriority properly, is an effective way to achieve responsive and sustainable images.

How to use srcset, sizes, and lazy in Markdown?

Markdown allows within its specification to use HTML so it is enough to write HTML directly with the aforementioned attributes to obtain sustainable and responsive images. However, there may be the following reasons why you prefer to use another alternative to direct HTML in Markdown:

  • Simpler syntax preferred (original idea of Markdown, easy to write)
  • You want to separate the content layer from the publishing layer as much as possible (original idea of Markdown, that is easy to read)
  • The markdown system or library used does not allow HTML to be added
  • Increase the level of security (an attack vector is eliminated or reduced) by limiting syntax

There are a considerable number of Markdown variants (flavors) and libraries in different programming languages, so the solution often involves selecting a flavor that has this syntax as a configurable option. However, by using a different syntax than regular Markdown, you may have errors or incompatibility with other Markdown libraries or systems.

At Injeniero we believe that using CommonMark 2 has a greater potential for sustainability as it tries to be a standard effort that allows us to develop libraries that precisely define syntax errors 3. It should be noted that as it is standard, its discussion is slow and non-trivial 4.

So how to achieve responsive and sustainable images in Markdown without using direct HTML and using CommonMark-compatible libraries?

One possible solution is to use a library that allows you to create extensions. In particular, we’ll show an example of how, using Markdown’s strict library MMmark 5 in the Haskell language that uses CommonMark specification: How to Create Responsive and Sustainable Images in Markdown Using Haskell MMark Library

Conclusion

Images are the main content that should be optimized for web sustainability. It is possible to do in Markdown files using the HTML attributes of an <img> element such as srcset, sizes, fetchpriority, and loading. This allows for a practical way to get responsive and sustainable images when writing Markdown. We introduced some challenges in the syntax and linked a possible implementation solution using a strict Haskell library.

At Injeniero it is our core to create sustainable sites and systems using responsive and sustainable images by default, with content creation process that uses CommonMark

Notes

  1. The lack of unambiguous syntax definition and the lack of “syntax error” led to the creation of CommonMark, as a standard candidate for the Markdown language specification.

References

  1. ^ Css image-set() Mozilla Foundation image-set
  2. ^ CommonMark commonmark.org
  3. ^ CommonMark Spec commonmark spec
  4. ^ CommonMark discussion about audio and video elements syntaxis embedded audio and video
  5. ^ MMark Haskell Library, Mark Karpov Announcing MMark
Copyright © 2025 Injeniero