srcset and printing

"Today I learned something new and stupid."

I should know that everything involving printing is just... perma-stupid. But still.

I've been tweaking both web sites to use <IMG SRCSET> in a few places in an attempt to speed things up a bit by downloading less data. The spec for SRCSET is actually pretty sensible, allowing the browser to download an appropriately-sized image based on the size of its window, the relationship between screen pixels and display pixels, and your hint as to how much of the screen the image will take up..

So let's say you've got a stack of SRCSET images, and the image on your screen is, let's say "five inches" wide, whatever that means, and the vagaries of the world result in the 768px image being used for that. So then you hit print. And now you're going to be printing a "five inch" image on a 300dpi device. Does it use the 1600px image for that?

The hell it does. It scales up the blurry-assed 768px image.

Safari, Mozilla, Chrome and Opera all do this.

This is annoying, because in the DNA store, when you buy a ticket, you are presented with a page with a image of your ticket on it, like so:

One of the common use cases here is "print it out and take it with you". So I've been serving 1600px PNGs, so that they will print well. But it sure would be nice if the people who aren't printing were being served a smaller file.

So I guess my choices are to keep serving large images always, or have prints be blurry. "Hooray."

Maybe there's some nuttery I could do with @print stylesheets in the CSS to override the SRC but that sure sounds fragile.

I mean, hopefully most people are using the Apple Wallet pkpass attachment we send them instead of printing, but still, this is dumb and ought to work.

Incidentally, is there some Android equivalent of pkpass? I'm including the Google-recommended EventReservation microformat in the confirmation email, but I tend to assume that microformats are still just wishful thinking. I haven't seen any documents suggesting that this format actually does anything anywhere. Does it? If it does, what does it look like? (Go buy a DNA ticket and send me a screen shot.)

Previously, previously, previously, previously.
Tags: , , , ,

34 Responses:

  1. Taylor Hunt says:

    You could try SVG, maybe? All browsers print it as crisp as it gets. For something with clean lines and solid colors like that ticket, it may even be smaller than a compressed PNG.

    • jwz says:

      I dunno, every SVG I've ever seen has been comically gigantic in the way that only overly-verbose XML idiocy can be. Also there's a flyer image in there, and a very crinkly (albeit useless) QR code.

      • Taylor Hunt says:

        Yeah, I should demonstrate how I would go about doing it. But here's a quicker fix:

        <picture>
        <source media="print" srcset="highres.png">
        <img srcset="...">
        </picture>

        This tells browsers that the highrest image is required for printing, so you may have better luck.

        • jwz says:

          Hope springs eternal, but no. With this:

          <picture>
            <source media="print" srcset="1600.png" />
            <img src="640.jpg"
              srcset="1600.png 1600w,
                1280.jpg 1280w,
                768.jpg 768w,
                640.jpg 640w,
                360.jpg 360w"
              sizes="(max-width: 530px) 100vw, 530px" />
          </picture>

          printing still uses blurry 640.jpg.

        • Anonymous says:

          This doesn't work because (unless things have changed in the last few years since I stopped caring about and slogging through browser engines' implementations), no major browser actually supports the CSS spec wrt @media print. It's just Web shit lip service, but otherwise totally ignored. It would be surprising, then, if media="print" did work.

          I'm curious if there are situations where this has worked for you, or if you're just relying on your understanding of what's supposed to work based on the specs.

          • jwz says:

            For many years, I've successfully used "@media print" to set colors and "display: none". I've never tried anything more sophisticated than that. But I sure wouldn't be surprised if that basic stuff is the only part that works.

            • Taylor Hunt says:

              Yeah, I use @media print { ... } all the time without a hitch. I imagine the <picture> implementation just isn't up to snuff yet, since IIRC a web dev had to raise money for him to implement it his dang self in WebKit/Blink in the first place.

              Idea, though. If it always prints the src, should that be the highres version, and then srcset would override the display in mobile browsers that support it?

              • jwz says:

                It does not always print the src -- it always prints whatever image it happened to pick when the @media screen page was loaded.

              • jwz says:

                Here, I made a test page. Resize, reload, print.

                • Bob says:

                  I tried adding id="ticket" to the picture and some CSS to show the high res image when printing. It kind of sort of works and is a little loathsome, but it could work with some massaging.

                  @media print {
                  #ticket img {visibility: hidden}
                  #ticket:before {
                  content: "" url(https://www.jwz.org/srcset-tester/2560.jpg);
                  max-width: 100vw;
                  }
                  }

      • Taylor Hunt says:

        I wrote up an example of how the SVG might go: https://codepen.io/tigt/pen/GMjqpx

        It's not complete, but I figured you'd get the gist of this much before I sunk any time into vectorizing the DNA logo. :)

        I think it's not too bad. Running the code through SVGO would get it even smaller, since this is just what I wrote by hand.

  2. For Android I simply use Pass2U; I've never seen any format that is Google-specific for this.

  3. jwb says:

    The microformats don't do anything except for users of Inbox by Gmail by Alphabet by Google or whatever they call it now. And this is not a lot of users.

  4. Ben Curthoys says:

    I always send e-tickets as PDF documents. I hate the format, but it has the highest chance of preserving barcodes at a scannable quality through the forwarding, printing and mangling that people subject them to.

    • thielges says:

      Almost every European rail line operator that sells tickets over the web delivers the ticket as a PDF.

  5. ff says:

    In related news, the images in the sidebar here under "Previously" all appear as 0px height, at least in chrome61 on mac. See https://imgur.com/a/qBkDM

    • jwz says:

      Well, if you have any idea how to fix that, do let me know.

      • raglan says:

        Give the enclosing a tag position: relative and the img position: absolute; top: 0; left: 0; seems to work in Safari and Chrome¿

      • erlogan says:

        It seems that some of the styles for the widget_jwz_previously stuff are a little weird. The images are 0px tall because that's what the CSS says to do to the enclosing a:

        .widget_jwz_previously a {
        display: inline-block;
        width: 100%;
        height: 0;
        padding-bottom: 100%;
        margin: 0 0.5em 0.5em 0;
        }

        ...and then the images are set to height of 100% of 0.

        That padding-bottom directive is also strange, because it gives a monstrous area of clickable whitespace (blackspace?) underneath, which I don't think is what you meant. If I tell my browser to ignore both of them (as well as a padding-bottom: 50% on @media screen and (min-width: 84em) #sidebar .widget_jwz_previously a) a sane thing seems to happen.

        Of course, now I've checked in a different browser, and while it looks great the first time in Safari, those changes cause lunacy. It's not like there's supposed to be a standard for this sort of thing or anything. You have my sympathy.

        • jwz says:

          "width: X%; height: 0; padding-bottom: Y%" is how you make a div that has a fixed aspect ratio regardless of size in pixels, because padding is always a horizontal measure even when in a vertical context.

          • erlogan says:

            But of course.

            I can also confirm that raglan's suggestion fixes it in both Firefox and Chrome on Mac.

    • tfb says:

      This is the case for Firefox (55.0.3) on mac as well. The hack suggested by raglan makes working noises for Firefox as well.

  6. Muon Cellefane says:

    Could you redesign the page so it has a "Click to Print" button. Then it just has an a href that goes to a page with only the high res version and a javascript window.print() call.

    • jwz says:

      I could, but I think "click to print" pages are terrible, as terrible as having different markup for your desktop and mobile site. That's why CSS media queries exist at all!

  7. Teddy says:

    Couldn’t you use a @media print CSS rule¹ to load alternate images for print and screen? In theory, it’s supposed to do the same as the media="print" attribute, but maybe it works better to use a CSS rule for this?

    1. https://www.w3.org/TR/css3-mediaqueries/

    • jwz says:

      You can't use CSS to override SRC -- to replace images from CSS you have to use background-image instead. But if you're doing that, now you're out of the SRCSET world, too. Ugh. I guess there could be two different images atop each other with CSS selecting one or the other?

      It's infuriating because these kinds of incredibly complicated CSS games are exactly what SRCSET and PICTURE were specifically designed to replace!

    • Anonymous says:

      My knowledge here may have recently passed its expiration date, but on the off chance that it's still fresh: at no point in the last 20 years of @media print has any major browser actually implemented it. See my comment above.

  8. jwz says:

    More great news! Since I started using SRCSET, my logs have been filling up with 404s from some shitty-assed Windows phone trying to load the entire srcset as an image -- spaces and widths and all, e.g., "GET IMG1.jpg%201280w,%20IMG2.jpg%20768w,%20IMG3.jpg%20640w HTTP/1.1" from some turd identifying itself as "Mozilla/5.0 (Windows Phone 8.1; ARM; Trident/8.0; Touch; rv:11.0; WebBrowser/8.1; IEMobile/11.0; Microsoft; Lumia 640 Dual SIM) like Gecko".

    I mean you've got to go out of your way to break things that badly.

Leave a Reply

Your email address will not be published. But if you provide a fake email address, I will likely assume that you are a troll, and not publish your comment.

You may use these HTML tags and attributes: <a href="" title=""> <b> <blockquote cite=""> <code> <em> <i> <s> <strike> <strong> <img src="" width="" height="" style=""> <iframe src="" class=""> <video src="" class="" controls="" loop=""> <div class=""> <blink> <tt> <u>, or *italics*.

  • Previously