├── README.md
└── imgsupport.js
/README.md:
--------------------------------------------------------------------------------
1 | # imgsupport
2 |
3 | Detecting support for AVIF, WebP, JPEG 2000, JPEG XR and SVG to supply the best image for the UA
4 |
5 | ## Install
6 |
7 | Download/fork the script to your server.
8 |
9 | Insert script before any `` tag to css file, so browser will start to download right images.
10 |
11 | ```
12 |
13 |
14 | My Page
15 |
16 | ...
17 |
18 | ...
19 | ```
20 |
21 | ## What this script do?
22 |
23 | Like modernizr, it injects one or a few CSS class names to the document element, e. g. ``, according to which image formats are supported by the browser:
24 |
25 | - `jxl` – if browser supports JPEG XL, then this class will be added. Currently it's Chrome and Firefox behind a flag.
26 | - `avif` – if browser supports AVIF, then this class will be added. Currently it's available on Chrome and Opera (not Edge) and in Firefox it's still behind a flag.
27 | - `webp` – it's already in all modern browsers. But be careful Safari started to support it not that long ago and it's available only in v14+ (BigSur, iOS14+).
28 | - `jp2` – browser supports JPEG 2000. It's Safari for Mac OS X and all browsers for iOS (based on iOS WebKit).
29 | - `jpx` – browser supports JPEG XR... Internet Explorer 9+ and old MS Edge till v18.
30 | - `svg` – all modern browsers, but this class is set only if none of the above formats are supported. Currently it's Firefox only.
31 | - `png` – if even SVG is not supported... fallback variant.
32 | - Additionally are added classes if the format is not supported: `notjxl`, `notavif`, `notwebp`, `notjp2`, `notjpx` and `notsvg`.
33 |
34 | ### Example results
35 |
36 | Chrome
37 |
38 | ```
39 |
40 | ```
41 |
42 | Safari
43 |
44 | ```
45 |
46 | ```
47 |
48 | Firefox
49 |
50 | ```
51 |
52 | ```
53 |
54 | ## Usage
55 |
56 | You can use css-cascade to specify what kind of image your browser must download:
57 |
58 | ```
59 | .jxl .myelem {
60 | background-image: url('myimage.jxl');
61 | }
62 | .avif.notjxl.notwebp .myelem {
63 | background-image: url('myimage.avif');
64 | }
65 | .webp.notjxl.notavif .myelem {
66 | background-image: url('myimage.webp');
67 | }
68 | .jpx.notavif.notwebp .myelem {
69 | background-image: url('myimage.wdp');
70 | }
71 | .jp2.notavif.notwebp .myelem {
72 | background-image: url('myimage.jp2');
73 | }
74 | .svg .myelem {
75 | background-image: url('myimage.svg');
76 | }
77 | .png .myelem {
78 | background-image: url('myimage.png');
79 | }
80 | ```
81 |
--------------------------------------------------------------------------------
/imgsupport.js:
--------------------------------------------------------------------------------
1 | (function (document) {
2 | var checkCount = 0,
3 | formatFound = false;
4 |
5 | function setHTMLClass(height, className) {
6 | checkCount++;
7 | if (height == 2) {
8 | formatFound = true;
9 | document.documentElement.className += " " + className;
10 | } else {
11 | document.documentElement.className += " not" + className;
12 | if (checkCount == 4 && !formatFound) {
13 | if (
14 | document.implementation.hasFeature(
15 | "http://www.w3.org/TR/SVG11/feature#Image",
16 | "1.1"
17 | )
18 | ) {
19 | document.documentElement.className += " svg";
20 | } else {
21 | document.documentElement.className += " notsvg png";
22 | }
23 | }
24 | }
25 | }
26 |
27 | var JXL = new Image();
28 | JXL.onload = JXL.onerror = function () {
29 | setHTMLClass(JXL.height, "jxl");
30 | };
31 | JXL.src =
32 | "data:image/jxl;base64,/woIELASCAgQAFwASxLFgkWAHL0xqnCBCV0qDp901Te/5QM=";
33 |
34 | var AVIF = new Image();
35 | AVIF.onload = AVIF.onerror = function () {
36 | setHTMLClass(AVIF.height, "avif");
37 | };
38 | AVIF.src =
39 | "data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A=";
40 |
41 | var WebP = new Image();
42 | WebP.onload = WebP.onerror = function () {
43 | setHTMLClass(WebP.height, "webp");
44 | };
45 | WebP.src =
46 | "data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA";
47 |
48 | var JPX = new Image();
49 | JPX.onload = JPX.onerror = function () {
50 | setHTMLClass(JPX.height, "jpx");
51 | };
52 | JPX.src =
53 | "data:image/vnd.ms-photo;base64,SUm8AQgAAAAFAAG8AQAQAAAASgAAAIC8BAABAAAAAQAAAIG8BAABAAAAAgAAAMC8BAABAAAAWgAAAMG8BAABAAAARgAAAAAAAAAkw91vA07+S7GFPXd2jckQV01QSE9UTwAZAMFxAAAAATAAoAAKAACgAAAQgCAIAAAEb/8AAQAAAQDCPwCAAAAAAAAAAAAAAAAAjkI/AIAAAAAAAAABIAA=";
54 |
55 | var JP2 = new Image();
56 | JP2.onload = JP2.onerror = function () {
57 | setHTMLClass(JP2.height, "jp2");
58 | };
59 | JP2.src =
60 | "data:image/jp2;base64,/0//UQAyAAAAAAABAAAAAgAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAEBwEBBwEBBwEBBwEB/1IADAAAAAEAAAQEAAH/XAAEQED/ZAAlAAFDcmVhdGVkIGJ5IE9wZW5KUEVHIHZlcnNpb24gMi4wLjD/kAAKAAAAAABYAAH/UwAJAQAABAQAAf9dAAUBQED/UwAJAgAABAQAAf9dAAUCQED/UwAJAwAABAQAAf9dAAUDQED/k8+kEAGvz6QQAa/PpBABr994EAk//9k=";
61 | })(
62 | (window.sandboxApi &&
63 | window.sandboxApi.parentWindow &&
64 | window.sandboxApi.parentWindow.document) ||
65 | document
66 | );
67 |
--------------------------------------------------------------------------------