My thoughts about images in HTML

My thoughts about images in HTML

An alternative way of dealing with images without compromise semantics

I prefer SVG when possible and I try to do all my images in CSS. I use media queries and image-set() and CSS variables to control URLs. But who knows me can agree that I'm passionate about semantic content. So here I want to share what is my preferred way of dealing with images.

Images as HTML img tags in our markup just feel wrong. I don't like to define width and height inline values. Nor I found natural the way of dealing with the responsiveness nature of images using just the img tag.

I get the courage to make and publish this post thanks to a short post that one of my favorite technology public figures made some days ago about this topic. Where I felt highly identified with his words but the subject was kept as an abstraction. So I wanted to make this short example in case someone out there can use another point of view on treating images not only as part of the look and feel but as content.

The markup

I start by using the figure and figcaption with the text that describes the image. This can be used by the browser for accessibility purposes and is up to the requirements if need to be hidden or not. Then as the first child and sibling of the figcaption an SVG element or a div with a class or id value for referring later in CSS with the respective selector.

  <figure id="horse-pic">
    <div class="image">
    </div>
    <figcaption>White Horse</figcaption>
  </figure>

This is the minimal required set of elements to archive a semantic markup. The way you choose to pick where to put the identifying part is up to you. I had chosen the most common way I use as an illustration.

The styles

I will keep this as simple as possible by not including proper sizing handling by media queries or aspect ratio. Meaning the sizing strategy is for you to implement. Although, a basic sizing was set so the example can be reproduced and seen.

:root{
    --white-horse-pic-url: url("white-horse.jpg");
    --white-horse-pic-large-url: url("white-horse.large.jpg");
}

figure#horse-pic{
    width: 260px;
    height: 200px;
}

figure#horse-pic > .image{
    background-size: cover;
    width: 100%;
    height: 100%;
    /* fallback for those browsers that do not support the function */
    background-image: var(--white-horse-pic-url);
    background-image: -webkit-image-set(
        var(--white-horse-pic-url), 1x,
        var(--white-horse-pic-large-url), 2x);
    );
    background-image: image-set(
        var(--white-horse-pic-url), 1x,
        var(--white-horse-pic-large-url), 2x);
    );
}

figure#horse-pic > figcaption{
    display: none;
}

The URL for all the images and their different density/resolutions files are declared as CSS variables on top of the file for easy maintenance.

Then the selectors for these three components are declared and used for defining the respective styles. Here you can opt to use image-set().

image-set() from the CSS functional notation is a method of letting the browser pick the most appropriate CSS image from a given set, primarily for high pixel-density screens.

This feature is currently supported by modern browsers only, so a fallback in the way of a normal background-image property value is advised to be defined.

If you think some proper sizing strategies need to be included in this post, let me know in the comments. I will be glad to add it then.