superol3g / postcss-image-set-polyfill Goto Github PK
View Code? Open in Web Editor NEWPostCSS plugin for polyfilling image-set CSS function
License: MIT License
PostCSS plugin for polyfilling image-set CSS function
License: MIT License
With following input CSS
background-image:
image-set(
url(/app/themes/the-theme/dist/10a4c3eb1294af405c55c9f4a2fe2743-4256.jpg) 1dppx
);
I get the following output
background-image: -webkit-image-set(url(/app/themes/the-theme/dist/10a4c3eb1294af405c55c9f4a2fe2743-4256.jpg) 1dppx);
background-image: image-set(url(/app/themes/the-theme/dist/10a4c3eb1294af405c55c9f4a2fe2743-4256.jpg) 1dppx);
There are no media queries based polyfills generated by the plugin.
@SuperOl3g: Use case:
For a specific set of breakpoints I provide different background images (which can optimize loading time quite nicely). Now I also want to provide three images per pixel density (1x; 2.x and 3x) per breakpoint.
In SASS with webpack responsive-loader this would result in a construct like this:
$width-smallest: 420;
$widths: 1366, 1280, 1120, 1600, 1000, 850, 600, 500;
// (smallest)
background-image:
image-set(
url(../background.jpg?size=#{$width-smallest}&quality=10) 1dppx,
url(../background.jpg?size=#{$width-smallest * 2}&quality=10) 2dppx,
url(../background.jpg?size=#{$width-smallest * 3}&quality=10) 3dppx
);
@each $width in $widths {
@media (min-width: #{$width}px) {
background-image:
image-set(
url(../background.jpg?size=#{$width}&quality=10) 1dppx,
url(../background.jpg?size=#{$width * 2}&quality=10) 2dppx,
url(../background.jpg?size=#{$width * 3}&quality=10) 3dppx
);
}
}
Can this plugin handle these cases?
Can I make the whole thing simpler?
Demo: https://runkit.com/retyui/5941ce97106bda0012f4676b
Debug stdout:
.test{
bg: image-set(url('../img/[email protected]') 3x) /* error 👎 */;
bg: image-set(url('../img/[email protected]') 3x ) /* valid 👍 */;
}
Надеюсь предоставленной информации достаточно что бы решить проблему 😄
Some displays have densities between 1x and 2x (1.3dppx, 1.5dppx) -
which could show a better result when these use the 2x variant.
How can multiple factors specified? Is this already covered by the specs - and this polyfill?
Specifying the same image file with a different density could be wasteful?
Not everyone uses the mqpacker PostCSS plugin to consolidate the basically duplicate mediaqueries.
Currently this polyfill doesn't seem to support densities specified with decimal value (e.g. 1.3x
or 1.5x
).
Input:
.image {
background-image: image-set(
url(img/test.png) 1x,
url(img/test-2x.png) 2x,
url(my-img-print.png) 600dpi
);
}
Expected output:
.image {
background-image: url(img/test.png);
}
@media (min-resolution: 144dpi) {
.image {
background-image: url(img/test-2x.png);
}
}
@media (min-resolution: 600dpi) {
.image {
background-image: url(my-img-print.png);
}
}
Actual output:
.image {
background-image: url(img/test.png);
}@media (min-resolution: 144dpi) {.image {
background-image: url(img/test-2x.png);
}
}@media (min-resolution: 600dpi) {.image {
background-image: url(my-img-print.png);
}
}
PostCSS v6 is for Node 4+, but I see you rolled back to ES5. What was the issue?
I’m not sure your plugin will remain Node 0.12 compatible in the PostCSS ecosystem.
image-set can be also used in background (as shorthand) property,
it would be nice if this plugin could also support this or at least emit a warning
when it skips such a declaration.
As image URL could be assigned to content property the polyfill should be applied to CSS snippet like this:
.content-view.canvas-overview .content-view.canvas > footer > .view-related-items > .view-shader {
content: image-set(url(../Images/DocumentGL.png) 1x, url(../Images/[email protected]) 2x);
}
According to the specification draft the resolution unit identifiers are: dpi, dpcm, dppx.
https://drafts.csswg.org/css-values-3/#resolution-value
But this plugin only accepts dpi units, for other units "Incorrect size value" error is thrown.
It is possible to (also accidentally) modify the AST Explorer example linked from
README page (Try it online) (when saving it).
This requires a major version bump.
@SuperOl3g: The x
unit is deprecated, it should be replaced with
stylelint/stylelint#3026 (comment)
(hudochenkov)
I would recommend using dppx instead of x.
GitHub don’t show fork repositories in search.
Please write to GitHub and ask to remove fork
tag.
@SuperOl3g:
Using image-set in shorthand with other background values results in just image-set being used:
.test {
background: linear-gradient( // solid color workaround
// see https://css-tricks.com/tinted-images-multiple-backgrounds/
rgba(255, 0, 0, 0.5),
rgba(255, 0, 0, 0.5)
),
image-set( url('../images/bck.jpg') 1x,
url('../images/[email protected]') 2x,
url('../images/[email protected]') 3x );
}
.test {
background: url(../images/bck.jpg)
}
@media (-webkit-min-device-pixel-ratio:1.5),(min-resolution:144dpi){
.test{
background: url(../images/[email protected])
}
}
@media (-webkit-min-device-pixel-ratio:2.25),(min-resolution:216dpi){
.test {
background: url(../images/[email protected])
}
}
The non-image-set CSS should either be placed outside the mediaqueries as usual or
with each image-set polyfill for preventing cascading/override issues.
I really like your plugin!
Would you create a GitHub Pages demo? It helps people discover your plugin. I’ve created one for you, if you’d like it:
https://jonathantneal.github.io/postcss-image-set-polyfill/
You can easily copy this to your repo:
git remote add jonathantneal [email protected]:jonathantneal/postcss-image-set-polyfill.git
git fetch jonathantneal
git checkout -b fork_branch jonathantneal/gh-pages
When using the type()
descriptor, that Safari
currently doesn't support.
Cannot read property 'dpi' of undefined
background: image-set(
url('../images/sky.jpg') type("image/jpeg"),
url('../images/sky.webp') type("image/webp"),
url('../images/sky.avif') type("image/avif")
);
It should be polyfillable though - by using a CSS feature
query.
postcss-cssnext
is plugin pack for all polyfills.
Media queries are all very well for browsers that don’t support image-set()
, but it’d be nice to leave the image-set()
function in there so that browsers that do support it can use it—because they will handle transitions between queries better (such as keeping the old image around until the new one is loaded, which I’m guessing they won’t do for media-query-based image source changes).
I haven’t thought too deeply about this, but I don’t think @supports
will need to be used—just create a new rule after the media queries which will overrule them. But doing this properly will entail decomposing shorthand syntaxes, so background: image-set(…)
becomes background-image: image-set(…)
, lest other properties be accidentally reset.
I expect this:
.foo {
background: red image-set(url(a) 1x, url(b) 2x);
background-size: cover;
/* If there was a background-image or background declaration here, you’d
possibly need to abort the whole thing. Probably out of scope for this issue. */
}
To compile to roughly this:
.foo {
background: red url(a);
background-size: cover;
}
@media (min-resolution: 2dppx) {
.foo {
background-image: url(b);
}
}
.foo {
background-image: image-set(url(a) 1x, url(b) 2x);
}
I'm propably missing something, but isn't support for Safari completely missing here? Safari seems to only support device-pixel-ratio and the supported -webkit-image-set
is removed (#14).
As there is a universal stack available shouldn't -webkit-min-device-pixel-ratio
always be added?
<x-resolution>
is a <dimension-token>
with a unit of x, and is treated the same as if the unit were dppx
.This unit represents the number of dots per px unit. Due to the 1:96 fixed ratio of CSS in to CSS px, 1dppx is equivalent to 96dpi, that corresponds to the default resolution of images displayed in CSS as defined by image-resolution.
2x -> 2dppx -> 2 * 96dpi = 192dpi
but youre plugin genrated 2x = 144dpi ??? 👎
Plese fixed it! 😃
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.