Skip to content

Instantly share code, notes, and snippets.

@rwaldron
Created September 6, 2012 16:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rwaldron/9f3ced6a91d7390b080d to your computer and use it in GitHub Desktop.
Save rwaldron/9f3ced6a91d7390b080d to your computer and use it in GitHub Desktop.

Can you share with us your credentials and experience in the field of modern UI design and development for web applications? (mail list arguments don't count)

How come no one is discussing what goes on in real life?

Given the following:

<picture id="ui-picture" alt="">
  <source src="large.jpg" srcset="large.jpg 1x, large-high.jpg 2x" media="min-width: 600px">
</picture>

<img id="ui-img" src="large.jpg" alt="" srcset="large-high.jpg 2x">

Q: How do I add a "mobile" image?

A: (with <picture>)

var source = document.createElement("source");

source.src = "mobile.jpg";
source.srcset = "low.jpg 0.5x, mobile.jpg 1x, mobile-hd.jpg 2x";

document.getElementById("ui-picture").appendChild(source);

A: (with <img>)

var img = document.getElementById("ui-img");

img.srcset += ", low.jpg 600w 0.5x, mobile.jpg 600w 1x, mobile-hd.jpg 600w 2x";

This is assuming that there wasn't a trailing comma in the original srcset attribute.

Q. How do I remove an image?

A: (with <picture>)

var source = document.querySelector("#ui-picture [src='mobile.jpg']");

source.parentNode.removeChild(source);

A: (with <img>)

var img = document.getElementById("ui-img");

// since there is no consensus on an API for this, I'm forced to roll my own...
var sources = img.srcset.split(",");

var removes = [ 
  "low.jpg 600w 0.5x", 
  "mobile.jpg 600w 1x", 
  "mobile-hd.jpg 600w 2x"
];

img.srcset = sources.filter(function( val ) {
  if ( removes.indexOf(val.trim()) === -1 ) {
    return true;
  }
}).join(", ");

For those of you following at home, these are just new examples of old DOM pain points with different words. Neither is very good, but at least picture+source is familiar DOM node creation, removal territory. img+srcset is a trip down memory lane with class attributes. Neither example is capable of sparing the developer from pain if they want to remove a single entry from a source.srcset or img.srcset; picture+source makes it less awful by making the values potentially addressable via query apis.

Of course, most web developers will prefer to use a library like jQuery (http://trends.builtwith.com/javascript/jQuery), because standards have betrayed everyone by making the simplest tasks verbose, awkward and painful to use (I'm talking about the physical pain one endures from typing obscenely long API names).

Let's look at the examples above through the eyes of the average web developer using jQuery:

Q: How do I add a "mobile" image?

A: (with <picture>)

$("#ui-picture").append(
  "<source src='mobile.jpg' srcset='low.jpg 0.5x, mobile.jpg 1x, mobile-hd.jpg 2x'>"
);

A: (with <img>)

// we can only hope that the dev is smart enough to cache the selection...
var img = $("#ui-img");

img.attr({
   srcset: img.attr("srcset") + ", low.jpg 600w 0.5x, mobile.jpg 600w 1x, mobile-hd.jpg 600w 2x"
});

Again, this is assuming that there wasn't a trailing comma in the original srcset attribute.

Q. How do I remove that same "mobile" image?

A: (with <picture>)

$("#ui-picture [src='mobile.jpg']").remove();

A: (with <img>)

var removes = [ 
  "low.jpg 600w 0.5x", 
  "mobile.jpg 600w 1x", 
  "mobile-hd.jpg 600w 2x"
];

$("#ui-img").attr("srcset", function( i, sources ) {
  return sources.split(",").filter(function( val ) {
    if ( removes.indexOf(val.trim()) === -1 ) {
      return true;
    }
  }).join(", ");
});

Less horrible, but still completely convoluted.

None of the above addresses the issue that srcset is still a string with multiple comma separated values—that's an issue for another day.

@marcoscaceres
Copy link

Seems problematic to use comma as a delimiter with URIs. Commas seem to be valid characters in a number of places of URIs (path, query string and fragment).

Real world example:
https://maps.google.com/?ll=37.0625,-95.677068&spn=35.494074,79.013672&t=h&z=4

Meaning srcset would be annoying to work with without needing to escape the URL first:
http://example.com/generated.image.php?rect=23,23,32&and=so,on

@marcoscaceres
Copy link

I asked on #WHATWG, and got told "at least one descriptor always exists; the space between the url and the descriptor ends the url".

@attiks
Copy link

attiks commented Oct 11, 2012

so in code this means the following should be safe:
sources.split(", ")

@marcoscaceres
Copy link

@attiks, I guess so. I'm thinking of doing a reference implementation of the algorithm in JS to see how it really works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment