Open hober opened 3 years ago
Would a pseudo protocol have wider application--and still be viable in CSS?
Maybe...
body { background-image: "qrcode:https://w3.org/" }
# though the actual text may have to be URI encoded...
body { background-image: "qrcode:https%3A%2F%2Fw3.org%2F" }
<img src="qrcode:https://w3.org/" />
<!-- or -->
<img src="qrcode:https%3A%2F%2Fw3.org%2F" />
If we went that way, we already have data:
urls for that purpose; you'd just need to mint a qr code MIME type, where the resource data is intended to be interpreted as a qr code. Like data:image/qrcode,https://example.com
However, that doesn't remove the use-case for a dedicated function that just takes a string, since that allows one to send the data directly, as @hober demonstrated, and without having to worry about URL encoding.
So a MIME type can be pursued in tandem, and then perhaps this feature rebased over that later, without stopping us from defining qrcode()
in CSS.
If we went that way, we already have
data:
urls for that purpose; you'd just need to mint a qr code MIME type, where the resource data is intended to be interpreted as a qr code. Likedata:image/qrcode,https://example.com
Not sure a media type is necessary (or wise) in this case. Media types shouldn't generally describe what's inside the package--just the packaging. 😃 And qrcode's themselves are "shipped" in all kinds of image/*
packages currently (and it should stay that way).
The point of this proposal (as I understand it) is to have the browser turn strings into QR codes with minimal effort. Using the data:
URL wouldn't provide for that; just an alternate means of shipping an existing image, and extending it to be more than a means of conveyance would be concerning.
I think you misunderstood - that url wasn't a compressed example omitting a ton of binary data, it was literally what you would write. image/qrcode
would be an image format, same as, say, SVG; like SVG, it would be a declarative image format, containing drawing instructions (namely, "draw the smallest QR code that embeds the following data") rather than pixel data.
But like I said, that's a separate discussion that doesn't have to impinge on any efforts to add qrcode()
to CSS.
@tabatkins great explanation. 😃 I do think that browser support for either URL approach we've each proposed would obviate the need for qrcode()
in CSS.
It'd be nice to have this feature regardless.
Like I said - it wouldn't obviate the need. @hober's example from the first post showed off something that absolutely could not be done if this was just a URL - you can't (currently...) construct a url()
from multiple strings, and you definitely can't url-encode a string in CSS.
@hober do you know of a reference for the definition of qr codes? I'm wondering if we need more (optional) specifiers, like size; I know you can output the same data in multiple sizes of qr code, and I imagine a consistent size would be desirable in practice. (You can of course change the size of the generated image, but I mean the rows/cols of the grid itself.)
https://wicg.github.io/shape-detection-api/#dom-barcodeformat-qr_code mentions ISO 18004. @yellowdoge might know more details.
ISO 18004 isn't free to access in full, grumble, but it does look like someone put the PDF on GitHub.
I think it's important that QR codes are exposed to accessibility APIs differently from (background-)images such that non-visual users can know there's something to scan (without relying on every author to provide proper alternative text). See the related imagecode
element (QR/barcodes) proposal: https://github.com/whatwg/html/issues/5801.
We've implemented ISO18004 (along with a dozen other symbologies). The main controllable parameter for QR-code are:
So yes, you'd need to allow for parameters other than the actual content of the barcode. The idea of using <img>
is problematic for the reasons tab said (crazy long URLs). We use object
and/or embed
:
<object type="bfo/barcode">
<param name="value" value="whatever">
<param name="ecc" value="high">
</object>
But until now we hadn't thought of doing this with CSS.
I agree with @Malvoz that this needs to be useful for accessibility, but if you made QR as a general image type, like linear-gradient
, then they wouldn't be limited to backgrounds; you could do something like
div.qrcode {
content: qrcode(contents);
}
<div class="qr">content here</div>
which would let accessibility APIs do the right thing without extra effort on the part of the author (note that content is allowed on non-pseudo elements but is limited to a few types, one of which includes <image>
- so no issues with doing this. And we already use the contents
keywords there to mean the DOM content of the node)
Two other things CSS would give us over a markup-based solution (object or a <barcode>
element as proposed in https://github.com/whatwg/html/issues/5801):
We can layer background-images, so we could put an image over the middle of the barcode - an inexplicably popular practice despite it completely trashing all the error correction, which is in the center of the barcode. Although you can do this with markup of course, using a separate absolutely positioned image.
Generate these automatically for URLs would be neat:
a[href^=http]::after {
content: qrcode(attr(href));
}
One suggestion however is to use barcode()
rather than qrcode()
. The reasoning is that while QR is the flavour du jour, in twenty years we might all be using aztec code or whatever.
So I'd think something more like this would be better:
div.qrcode { content: barcode(contents, ecc=high, unit=1mm); }
div.azteccode { content: barcode(contents, ecc=high, unit=1mm, symbology=aztec); }
With an open list of parameters to the barcode()
function and a symbology that defaults to qrcode, you're completely future proofed and can define symbologies as necessary.
For reference, PDFReactor have support for this, as does Antenna House formatter. PDFReactor uses a <barcode>
element and Antenna House use a magic URL (ref)
There's no need to make a generic function that smuggles the details in arguments, when the syntax of what's allowed might vary based on that argument. We're not exactly pressed for function names, so we can just give functions the maximally useful name to start with, and then give them the correct specialized syntax based on that. In 20 years we can add an azteccode()
function alongside qrcode()
, that's fine.
Thanks for the description of what needs to be controllable for QR codes, btw - that's what I was missing to make this a proper proposal. So we're looking at a grammar like:
<qrcode()> = qrcode( <string> | <url>]
[ [ low-ecc | medium-ecc | high-ecc ]
|| [ unit [ auto | <length> ] ]
|| [ version [ auto | <integer [1, 40]> ] ]
]
)
<url>
is specified, it's absolutized and serialized, then treated identically to a <string>
argument.unit auto
is specified (the default when omitted), the image has no natural width or height, only a 1/1 natural aspect ratio; if it's provided with a length, the image has an appropriate natural size determined by that unit size.version auto
is specified (the default when omitted), the image uses the minimum version to allow it to display the data; otherwise it uses the specified version, truncating the data if necessary.Your example would be:
div.qrcode { content: qrcode("contents" high-ecc unit 1mm); }
Some further questions:
content
, but not when using it as a background-image, and I presume there's a reasonably standard padding region suggested by the specs to ensure proper reading.Just linking up related issues for notifications of interest/posterity/etc: https://github.com/whatwg/html/issues/5801 which in turn links to other related things, as well as https://discourse.wicg.io/t/proposal-element-for-qr-code-barcodes/4673
Sorry, just checking ISO18004 for confirmation and there are actually four ECC levels, which have the highly descriptive names L
M
Q
and H
in ISO18004:2006 (what I have here). I've no idea what Q means. quite-high-ecc
?
"Q" is "quartile", meaning that up to 25% of the data can be recovered by the error correction - it lies between M and H in terms of recovery %.
Yes, a minimum amount of whitespace is required around the code to make it scan (the "quiet zone"). I'd suggest this should be part of the intrinsic dimensions, as otherwise a user who wants to generate qrcodes to spec is going to have to calculate it themselves, which seems bad.
Yeah looks like it should be 4 units in width. Having it default to that but be controllable (so one can have codes stack up next to each other with just the minimum quiet zone between them, rather than double the zone) seems reasonable.
Agree it may make sense to make it easier to generate QR codes, but is it CSS' place to define this?
<img src>
If it's used in content
, you can specify an alt text, and we could (should!) auto-fill that from the content.
That said, for url use-cases there should be a link anyway, probably wrapping the qr code. a[href].qr { content: qrcode(attr(href) ...); }
would work wonderfully, for example.
That said, for url use-cases there should be a link anyway, probably wrapping the qr code.
a[href].qr { content: qrcode(attr(href) ...); }
would work wonderfully, for example.
Yup, exactly.
1D barcodes and 2D matrix codes are alternative, machine readable, monochromatic graphic representations of textual content. Using image files for them is roughly like Word Art. So, ideally, it would be used something like this:
<code>text to be encoded</code>
<a href="url:to.be/encoded">label</a>
code {
display: code; /* add magic */
}
a::after {
display: code;
content: attr(href);
}
:root {
code-redundancy: high; /* ECC */
code-unit: 1mm;
code-type: quick-response;
}
(display
and code
are probably not the best choices, but hopefully get the idea across.)
PS: It would be too much of a stretch to use text-transform
for this, but perhaps text-transcode
.
Generating QR code images from URLs is more and more common these days. It'd be nice if you could generate QR code images from CSS.
For example, you could generate QR codes for links in a print stylesheet:
Or you could generate a QR code for the document itself in a print stylesheet, so someone could find the online version of an article in print (see also #6546):
Thought of this while reading a twitter thread between @jyasskin @dauwhe @tabatkins: https://twitter.com/jyasskin/status/1430586358658043909