Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Layout shifts when loading images dynamically... #108

Closed
411A opened this issue Aug 29, 2024 · 2 comments
Closed

Layout shifts when loading images dynamically... #108

411A opened this issue Aug 29, 2024 · 2 comments

Comments

@411A
Copy link

411A commented Aug 29, 2024

Describe the bug

If we use JS/Svelte code inside a post to dynamically load around 10 images in an iteration, a huge gap or extra margins will appear before the content when navigating to another page (Fixes by reloading the page). I'm new to Svelte, so it could be something I'm doing wrong. I would really appreciate any help, especially if the issue is in my code.

Reproduction

  1. Create a new post (repro_issue).
  2. Inside the index.md use following code with any images:
👀 View Reproducible Code

Paste the following code inside the /user/blogs/repro_issue/index.md, remember to add some images to the folder (src_to_imgs):

---
title: "My Image Gallery"
description: "Image Gallery..."
#cover: /qwer.webp
# Don't list in blog posts, only accessible with direct URL
options:
  - unlisted
published: "2024-08-29T16:11:00.000+08:00"
---

<script>
  const images = [
    { src: '/src_to_imgs/img1-name.png', caption: 'img1-caption', link: 'https://linktoimg.com' },
//TODO Add more images here...
  ];

  function handleImageClick(event) {
    event.stopPropagation();
  }
  
</script>

<style>
  .gallery {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
  }

  .gallery-item {
    position: relative;
    width: calc(25% - 10px); /* Four columns with 10px gap */
    box-sizing: border-box;
  }

  .image-container {
    position: relative;
    width: 100%;
  }

  .gallery-item img {
    width: 100%;
    height: auto;
    display: block;
    transition: filter 0.3s ease;
  }

  .gallery-item:hover img {
    filter: blur(5%);
  }

  .icon-overlay {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    display: flex;
    justify-content: center;
    align-items: center;
    /* Default opacity of icon */
    opacity: 0;
    transition: opacity 0.3s ease;
    pointer-events: none;
  }

  .gallery-item:hover .icon-overlay {
    opacity: 1;
    pointer-events: all;
  }

  .gallery-item:hover .icon-overlay a {
    opacity: 0.70; /* Increase opacity of icon on hover */
  }

  .icon-overlay a {
    font-size: 24px;
    color: white;
    text-decoration: none;
    background-color: rgba(0, 0, 0, 0.5);
    padding: 10px;
    border-radius: 50%;
    /* Default opacity of icon link */
    opacity: 0.5;
  }

  .caption {
    text-align: center;
    margin-top: 5px;
  }

  @media (max-width: 768px) {
    .gallery-item {
      width: calc(50% - 10px);
    }
  }

  @media (max-width: 480px) {
    .gallery-item {
      width: calc(100% - 10px);
    }
  }
</style>

<div class="gallery">
  {#each images as { src, caption, link }}
    <div class="gallery-item">
      <div class="image-container">
        {#if link !== ''}
          <button class="icon-overlay" 
                  aria-label="Opens the link to certificate"
                  on:click|stopPropagation={() => handleImageClick(event)}
                  on:keypress={(event) => { if(event.key === 'Enter') handleImageClick(event); }}
                  tabindex="0"
                  style="all: unset; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);">
            <a href={link} target="_blank" rel="noopener noreferrer">🔗</a>
          </button>
        {/if}
        <ImgZoom src={src} alt={caption} class="h-full object-cover" />
      </div>
      <div class="caption">{@html caption}</div>
    </div>
  {/each}
</div>

Logs

System Info

Deployed on Vercel.

Additional Information

You can view this issue on my blog:

  1. Navigate to https://abditory.dev/my-certificates
  2. Then from hamburger menu choose another section.

Normal About section (Before navigating from Certificates section):
image
Problematic About section (After navigating from Certificates section):
image

@toddLiao469469
Copy link
Contributor

I think this issue is caused by the lack of a key in the {#each} block. Without a key, it can lead to conflicts during out transitions.

You could try doing it like this:

 {#each images as { src, caption, link } (src)}
 {/each}

@411A
Copy link
Author

411A commented Oct 17, 2024

I think this issue is caused by the lack of a key in the {#each} block. Without a key, it can lead to conflicts during out transitions.

You could try doing it like this:

 {#each images as { src, caption, link } (src)}
 {/each}

Thank you so much! ❤️

@411A 411A closed this as completed Oct 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants