The shorthand for embedding an image in Markdown is the following:
![descriptive text goes here](example.jpg)
This works for rendering an image in the same way a skateboard is a minimum viable replacement for car; it rolls, but not fast. To render an image responsibly in modern times you need a handful more properties than src
and alt
; namely height
, width
, loading
, and decoding
attributes.
<img src="example.jpg"
alt="descriptive text goes here"
height="400"
width="300"
decoding="async"
loading="lazy">
Here’s a quick summary of what those other attributes do and why you should have them:
height
+width
- The HTML spec changed slightly and now setting a height and width draws an aspect-ratio’d box for the image to paints in. This prevents layout shift as the image loads.decoding="async"
(Optional) - This prevents the browser from blocking other content and move image decoding it decodes the image data to a bitmap. I feel like this should be the browser default?loading="lazy"
(Optional) - Recommended for any image below the fold.
Honorable mentions
srcset
+sizes
- If you want the fastest images, you can offer different sizes and cuts of your images. I don’t do this and Lighthouse is always mad about it.fetchpriority
- This is like driving a manual stick shift, but may be useful. I thinkloading="lazy|eager"
are easier to reason about thanfetchpriority
but I’m not your boss.
Some Markdown formatters have a custom syntax that supports adding more attributes, like Kramdown…
![descriptive text goes here](example.jpg){: height="36px" width="36px" decoding="async" loading="lazy" }
This makes your Markdown less readable and less portable to other engines. If you’re going to include all these attributes, you might as well use an HTML <img>
tag. This will make your images consistent with the other (unsupported without plugins) media like <video>
, <audio>
, <picture>
, and <svg>
in your Markdown posts.