<source> media attribute - width of container rather than screen? - image

I'm using the <picture></picture> tag to responsively display an image after assessing the size of the container it's in.
Some example code:
<picture>
<source media="(max-width: 70px)" srcset="IMAGE_URL">
<source media="(min-width: 71px) and (max-width: 170px)" srcset="IMAGE_URL">
<source media="(min-width: 171px) and (max-width: 270px)" srcset="IMAGE_URL">
. . .
<img src="IMAGE_URL" alt="An image">
</picture>
However, the <source media="(MEDIA_QUERY)" ... > part in an implementation of the format above considers the width of the entire screen, rather than the container that the <picture></picture> is currently inside.
Help on this is appriciated.

There is unfortunately no standard way (yet) to base responsive behavior upon a container instead of the browser viewport.
There are community efforts around Container Queries, but nothing has yet been defined, that could eventually become a standard.
There are several JavaScript libraries, like EQCSS, trying to provide solutions, but requiring JavaScript for a presentation —hence CSS— job is often not a good idea.
You can also look at CSS Conditions, but it also requires JavaScript.

You can use srcset and specify image size:
<div class="container">
<img src="image-200.jpg"
srcset="image-100.jpg 100w, image-200.jpg 200w,
image-400.jpg 400w, image-800.jpg 800w,
image-1000.jpg 1000w, image-1400.jpg 1400w,
image-1800.jpg 1800w" />
</div>
Browser will download optimal image file.

Related

Flexbox works only when I use a <img> instead of a <picture>

This is a super cleaned version of some photos I need in a wall of text (padding and red for visualization aid).
<div style="background:red;width:300px;display:flex;flex-wrap:wrap;padding:1em;justify-content:space-between;">
<picture>
<source type="image/avif" srcset="xxx.avif">
<img alt="xxx" src="xxx.jpg" style="width:100%;height:auto;padding-bottom:2%;">
</picture>
<picture>
<source type="image/avif" srcset="xxx.avif">
<img alt="xxx" src="xxx.jpg" style="width:49%;height:auto;">
</picture>
<picture>
<source type="image/avif" srcset="xxx.avif">
<img alt="xxx" src="xxx.jpg" style="width:49%;height:auto;">
</picture>
</div>
Until I use three img (deleting all "picture" and "source" code) it works flawless, I can't solve, it's four hours I try, I'm going crazy. Thanks, I attach a screenshot next.

Failed to load resource: the server responded with a status of 404 () but visiting url directly shows image

I have a weird problem where the browser says the server returns a 404 on an image.
However visiting the URL directly shows the image. The image is within the <picture> element, which loads in a slightly different order. Could that be the cause, and if so why? Could it be cached?
Here's the site:
https://www.vamoney.squareballoon.co.uk/
And here's my code from that site:
<picture>
<source media="(min-width:1201px)" srcset="/images/aspirational-photos/borrow--va-money-main-image--1920.webp" type="image/webp">
<source media="(min-width:1201px)" srcset="/images/aspirational-photos/borrow--va-money-main-image--1920.jpg" type="image/jpg">
<source media="(min-width:960px)" srcset="/images/aspirational-photos/borrow--va-money-main-image--1200.webp" type="image/webp">
<source media="(min-width:960px)" srcset="/images/aspirational-photos/borrow--va-money-main-image--1200.jpg" type="image/jpg"><source media="(min-width:768px)" srcset="/images/aspirational-photos/borrow--va-money-main-image--959.webp" type="image/webp">
<source media="(min-width:768px)" srcset="/images/aspirational-photos/borrow--va-money-main-image--959.jpg" type="image/jpg">
<source media="(min-width:480px)" srcset="/images/aspirational-photos/borrow--va-money-main-image--767.webp" type="image/webp">
<source media="(min-width:480px)" srcset="/images/aspirational-photos/borrow--va-money-main-image--767.jpg" type="image/jpg">
<source media="(min-width:0px)" srcset="/images/aspirational-photos/borrow--va-money-main-image--479.webp" type="image/webp">
<source media="(min-width:0px)" srcset="/images/aspirational-photos/borrow--va-money-main-image--479.jpg" type="image/jpg">
<img src="/images/aspirational-photos/borrow--va-money-main-image--479.jpg" alt="VA Money - A picture of a calculator and some documents representing the idea that you can Borrow Money for your business requirements">
</picture>
The browser says the images are a 404. But visiting one directly (it's easiest to click the one on the img=src shows the image.
https://www.vamoney.squareballoon.co.uk/images/aspirational-photos/borrow--va-money-main-image--479.jpg
How can it be both a 404 and also viewable? This must be something idiotic I am doing right?
I had used the <picture> element to show WebP with a JPG fallback.
I had misunderstood that the JPG would fall back, because it only falls back when the browser does not support WebP. When it does support WebP it shows a 404 error if the WebP doesn't look.
So in this case, the issue was that the WebP was a 404 error but I was checking the JPG as I expected it to fall back.

For responsive images with different aspect ratios, what's a good way to minimize Cumulative Layout Shift?

If you have a <picture> element with image sources at different aspect ratios at different breakpoints, what is the best way to minimize CLS by using aspect-ratio and media queries in CSS?
For <picture>, you should be fine as long as each <source> image has the same aspect-ratio in your responsive image snippet:
<img width="1000" height="1000"
src="puppy-1000.jpg"
srcset="puppy-1000.jpg 1000w,
puppy-2000.jpg 2000w,
puppy-3000.jpg 3000w"
alt="Puppy with balloons"/>
For <picture> where each <source> has a different aspect-ratio, browsers are awaiting standardization of width/height being recommended for each <source> for the art-direction use-case:
<picture>
<source srcset="https://via.placeholder.com/600x279" media="(max-width: 599px)" width="600" height="279">
<source srcset="https://via.placeholder.com/1500x300" media="(max-width: 991px)" width="1500" height="300">
<img src="https://via.placeholder.com/1500x300" width="1500" height="300">
</picture>
In the meantime, you can provide height through padding-top CSS hacks, with different media-queries per <picture> breakpoint.
The source element supporting dimension attributes is now part of the HTML standard — https://html.spec.whatwg.org/multipage/embedded-content.html#the-source-element
The standardisation matches the example implementation #addyo already provided.
For the art-direction use-case of a <picture>, where each <source> has a different aspect-ratio, each <source> can provide its own width and height value.
<picture>
<source srcset="https://via.placeholder.com/600x279" media="(max-width: 599px)" width="600" height="279">
<source srcset="https://via.placeholder.com/1500x300" media="(max-width: 991px)" width="1500" height="300">
<img src="https://via.placeholder.com/1500x300" width="1500" height="300">
</picture>
Implementation for browser support is underway and should be trackable in caniuse soon.

How to make picture srcset with media queries in liquid (shopify)

I'm looking to render device specific images for both my products, but also all the content that is uploaded through the customize section in Shopify.
I'm looking to generate something like the following:
<picture>
<source media="(min-width: 1028px)" srcset="path/image-desktop.jpg 1x, path/image-desktop#2x.jpg 2x">
<source media="(min-width: 768px)" srcset="path/image-tablet.jpg 1x, path/image-tablet#2x.jpg 2x">
<source media="(max-width: 768px)" srcset="path/image-mobile.jpg 1x, path/image-mobile#2x.jpg 2x">
<img src="path/image.jpg" alt="">
</picture>
How can this be done in liquid as a reusable snippet for both product images, collection images and for uploaded images in the customise section? I'm not looking to use a js library to handle it.
Thanks in advance!

How to use .svg files in a webpage?

I want to know how can one actually use a .svg file In a web page?
See svgweb quickstart and the svgweb project homepage for something that works in all browsers including IE (requires flash plugin).
There are many ways to include an existing svg file:
<img src="your.svg"/>
<object data="your.svg"/>
<iframe src="your.svg"/>
<embed src="your.svg"/>
<div style="background:url(your.svg)">...</div>
If all you want to do is to place an SVG image such as a logo or static diagram, you just need to be careful to provide a fallback for older versions of Internet Explorer (i.e. versions 8 and earlier).
The best and simplest method I've found is to use a .png or .jpg for your fallback, placed using a normal img tag. You then wrap the img tag in an object tag, using the data attribute to place the SVG.
<object data="/path-to/your-svg-image.svg" type="image/svg+xml">
<img src="/path-to/your-fallback-image.png" />
</object>
The img fallback is only loaded and used if the browser doesn't understand SVG.
I recommend putting the svg inline into your document (html5 technique). Just open your SVG file, copy the SVG tag and everything insideof it and then paste it into your html document.
<html>
<body>
<svg></svg>
</body>
</html>
It has the advantage that this allows you to use css to style it, like changing the fill color or applying filters to it like blur. Another advantage is that you save one http request for fetching the svg file if it is inside of your document.
If you want for example to change its position using css, then you have to put the css inside of a style attribute. Styles that are in an external css file will not get applied in most browser as this is a security restriction. For example:
<svg id="mySVG" style="position: absolute; top: 200px; left: 200px;"></svg>
This technique is supported by all browsers except IE8 and below as well as the android 2.3 browser and below.
Read the chapter inline SVG for further details:
css-tricks.com Using SVG
developer.mozilla.org SVG In HTML Introduction
If you dont want to put it inline in your page then the best alternative seems to be the object tag and avoid using the embed tag.
Read this for further details about object vs embed vs img tag:
How to Add Scalable Vector Graphics to Your Web Page
http://www.w3schools.com/svg/svg_inhtml.asp
The best example:
<embed src="rect.svg" width="300" height="100"
type="image/svg+xml"
pluginspage="http://www.adobe.com/svg/viewer/install/" />
Caspar's approach is the proper one. However, I would move the fallback to the CSS, since you probably want to apply some styles to the svg file itself...
<object data="/path-to/your-svg-image.svg" type="image/svg+xml" class="logo"> </object>
CSS
.no-svg .logo {
width: 99px;
height: 99px;
background-image: url(/path-to/your-png-image.png);
}`
Raphaël—JavaScript Library. Nice javascript library that is using svg, and gives you a large range of effects!
Also supports most browsers, including IE
I'd like to agree with the answer from "code-zoop". Although this technically doesn't answer your question, it might also be a solution: enter the relevant data straight into the HTML. Either directly as an svg element, or by using Raphaël-JS.
From w3c-schools:
SVG is all suported in In Firefox, Internet Explorer 9, Google Chrome,
Opera, and Safari you can
<html>
<body>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<circle cx="100" cy="50" r="40" stroke="black"
stroke-width="2" fill="red"/>
</svg>
</body>
</html>
(end of quote)
And to think even more outside the box, depending on how you want to use it, you can also put your 1-color graphics in a webfont. (see for example iconmoon.io )

Resources