Allow `URL` instances in `css` template tag
hsablonniere opened this issue · 3 comments
Hello team!
The context
Like many other users of LitElement, I'm trying to avoid bundler specific config and ES import syntax to refer to the URL of assets like SVG images.
This means, I don't do this:
import checkSvgUrl from '../assets/check.svg';
but I do this:
const checkSvgUrl = new URL('../assets/check.svg', import.meta.url).href;
With this technique, my code works "as is" in any modern browsers without any bundler.
I can easily use this in a lit-html template:
render() {
return html`<img src=${checkSvgUrl}>`
}
The "limitation"
If I want to use this URL in CSS, I need to use unsafeCss
like this:
static get styles () {
return css`
.foo {
background-image: ${unsafeCss(checkSvgUrl)}
}
`
}
The proposition
As we can see here, LitElement css
template tag allows instances of CSSResult
and type Number
: https://github.com/Polymer/lit-element/blob/master/src/lib/css-tag.ts#L68-L79
I was wondering if we could also allow instances of URL
?
This way, we could do this:
const checkSvgUrl = new URL('../assets/check.svg', import.meta.url);
// ...
static get styles () {
return css`
.foo {
background-image: ${checkSvgUrl}
}
`
}
NOTE: This time, the checkSvgUrl
is not the href
string but a real instance of URL
.
I think it could improve DX with just a few more characters in the source code and it would maybe push users towards this new URL
pattern instead of relying on bundler configs and non standard import syntax for assets.
WDYT?
In CSS URLs are the most unsafe thing you can feed untrusted strings to. It's why we disallow arbitrary strings in the first place.
unsafeCSS
is the signal that the source of the URL is trusted, so that's really the right way handle this. We could also integrate Trusted Types here so that we allow TrustedHTML
values. That would still require wrapping a URL, but it would be a standard wrapper at that point.
Fair enough
Closing based on #1117 (comment).