1
0

Image переписан так, чтобы обойти баг Chrome, но не возиться с переопределением стилей noscript

This commit is contained in:
2025-09-11 21:13:24 +04:00
parent 8042321142
commit c917c83d5d

View File

@@ -1,19 +1,18 @@
<noscript>
<img
{loading}
{...others}
/>
</noscript>
<img
bind:this={node}
class:loaded
class="noscript-visible"
{loading}
{...others}
/>
{#if dynamic}
<img
{loading}
{...others}
bind:this={node}
class="dynamic"
class:visible
/>
{/if}
<noscript>
<style>
.noscript-visible {
opacity: 1 !important;
}
</style>
</noscript>
<script>
let {
@@ -22,12 +21,7 @@
} = $props()
let node = $state()
let visible = $state(false)
let dynamic = $state(false)
$effect(() => {
dynamic = true
})
let loaded = $state(false)
$effect(() => {
if (!node) {
@@ -35,39 +29,26 @@
}
if (node.complete) {
visible = true
loaded = true
} else {
node.addEventListener('load', () => visible = true, { once: true })
node.addEventListener('load', () => loaded = true, { once: true })
}
})
</script>
<style lang="scss">
/*
Ideally, <noscript> could use display: contents so it wouldn't create a block container.
However, due to a Chrome bug, we must set it to display: block to ensure proper layout.
This ensures that fallback images inside <noscript> scale correctly to the container width.
https://issues.chromium.org/issues/41179501
*/
noscript,
img {
display: block;
max-width: 100%;
width: 100%;
height: auto;
}
img {
object-fit: cover;
object-position: top center;
transition: opacity 0.4s ease;
opacity: 0;
&.dynamic {
transition: opacity 0.4s ease;
opacity: 0;
&.visible {
opacity: 1;
}
&.loaded {
opacity: 1;
}
}
</style>