Skip to content

Supporting non-standard sizes query strings #10

@dawaltconley

Description

@dawaltconley

Initially I was thinking of just using the device list to generate media queries for any image using a non-standard sizes query, and calculating the right image for each device query.

Now I'm rethinking this approach. Not all non-standard sizes queries need to be converted to a device list. For example:

sizes="(min-width: 1280px) cover 400px 300px, 100vw"

You only need to know aspect ratio of the source image to pick the right image size, and then this can be converted back to a standard media query. So you would get:

// for an image of w=300 h=400 (aspect=0.75)
sizes="(min-width: 1280px) 400px, 100vw"

// for an image of w=500 h=300 (aspect=1.6667)
sizes="(min-width: 1280px) 500px, 100vw"

This only becomes difficult when you introduce at least one viewport-relative unit on a cover or contain calculation:

sizes="(min-width: 1280px) cover 400px 50vh, 100vw"

Because the aspect ratios of device viewports vary, any given image might be constrained by either the height or width variable. Nonetheless, it's possible to identify a breakpoint where this changes. This can be done by converting the

$bp = 400px * ($sourceHeight / $sourceWidth) * (100vh / 50vh)
// for an image of w=300 h=400 (aspect=0.75). 
sizes="(min-width: 1280px) and (min-height: 1067px) 37.5vh, (min-width: 1280px) 400px, 100vw"

// for an image of w=500 h=300 (aspect=1.6667)
sizes="(min-width: 1280px) and (min-height: 480px) 83.333vh, (min-width: 1280px) 400px, 100vw"

With vh units, this will be a height breakpoint. With vw units, this will be a width breakpoint. With both, this will be an aspect-ratio breakpoint.

// given
$sizes: "(min-width: 1280px) cover 60vw 100vh, 100vw"

$aspectBp: ($imageWidth / $imageHeight) * (100 / 60)

// for an image of w=300 h=400 (aspect=0.75). 
$sizes: "(min-width: 1280px) and (min-aspect-ratio: 1.25) 75vh, (min-width: 1280px) 60vw, 100vw"

// for an image of w=500 h=300 (aspect=1.6667)
$sizes: "(min-width: 1280px) and (min-aspect-ratio: 2.778) 166.667vh, (min-width: 1280px) 60vw, 100vw"

This may be more difficult or impossible for a crop keyword, but I think it's worth implementing for the others regardless.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions