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

Flickering effect when applying parent stylings to a filled slot #8337

Closed
Destaq opened this issue Feb 28, 2023 · 3 comments
Closed

Flickering effect when applying parent stylings to a filled slot #8337

Destaq opened this issue Feb 28, 2023 · 3 comments

Comments

@Destaq
Copy link

Destaq commented Feb 28, 2023

Describe the bug

When applying styles to both the parent of a slot and items within the slot, the screen quickly flickers / blinks on initial page load.

It seems that parent styles are only applied after the slot has been rendered, which leads to an undesirable UI side effect.

Screen.Recording.2023-02-28.at.8.05.29.AM.mov

Reproduction

Very simple repo.

Logs

N/A — no error logs.

System Info

System:
    OS: macOS 13.0.1
    CPU: (8) arm64 Apple M1
    Memory: 80.69 MB / 16.00 GB
    Shell: 5.8.1 - /bin/zsh

Binaries:
    Node: 19.6.0 - /opt/homebrew/bin/node
    Yarn: 1.22.11 - /opt/homebrew/bin/yarn
    npm: 9.4.0 - /opt/homebrew/bin/npm

Browsers:
    Brave Browser: 110.1.48.164
    Safari: 16.1

npmPackages:
    svelte: ^3.54.0 => 3.55.1

Severity

annoyance

@Destaq Destaq changed the title Flickering effect when when applying multiple stylings to a filled slot Flickering effect when applying multiple stylings to a filled slot Feb 28, 2023
@Destaq Destaq changed the title Flickering effect when applying multiple stylings to a filled slot Flickering effect when applying parent stylings to a filled slot Feb 28, 2023
@Destaq
Copy link
Author

Destaq commented May 18, 2023

Any chance of this being looked at? Seems to be a widespread issue in Svelte-dependent projects (e.g. here), even in production.

@geoffrich
Copy link
Member

geoffrich commented May 18, 2023

This appears to be caused by how HTML works, and is not a Svelte bug. The repro provided attempts to render the following HTML (spread between +page.svelte and Register.svelte):

<p class="flex text-green-500">
  <div slot="top">
    <p class="text-center">
        This is a test sentence. It should not flicker.
        <br />
        However, it blinks from gray to green, and from center to left.
    </p>
  </div>
</p>

However, the HTML spec does not allow placing a <div> or <p> element inside a <p> (see SO), so the browser corrects the server-rendered HTML to the following (note that the <p> tag is immediately closed since it can't contain the div):

<p class="flex text-green-500 s-q3Jb3FW-YQDU"></p>
<div slot="top" class="s-y_bCXRrkrYfP">
        <p class="text-center s-y_bCXRrkrYfP">This is a test sentence. It should not flicker.
            <br class="s-y_bCXRrkrYfP">
            However, it blinks from gray to green, and from center to left.
        </p>
</div>
<p></p>

(You can observe the above markup by disabling csr and inspecting the output in the browser)

But then, Svelte's hydration takes over and constructs the originally requested (invalid) markup with JavaScript:

<p class="flex text-green-500 s-q3Jb3FW-YQDU">
  <div slot="top" class="s-y_bCXRrkrYfP">
    <p class="text-center s-y_bCXRrkrYfP">This is a test sentence. It should not flicker.
            <br class="s-y_bCXRrkrYfP">
            However, it blinks from gray to green, and from center to left.
    </p>
  </div>
</p>

This causes the flicker, since the structure of the server-render and the hydrated DOM are different.

To fix this, you should update the Register component to use a <div> instead, so the browser can correctly interpret the HTML.

See also #5049 - Svelte will show an error message for this case if you incorrectly nest paragraphs in a single component.

@Destaq
Copy link
Author

Destaq commented May 19, 2023

@geoffrich Thank you for taking a look — my bad for using such a poor example. However, it wasn't due to the <p> that I raised the issue in the first place; it occurs elsewhere as well.

Take, for example, the below:

<script lang="ts">
    let item = [1, 2, 3, 4, 5, 6];
</script>

<div>
   {#each item as item}
       <!-- represent the item details in a tailwind card -->
       <div class="w-64 inline-block bg-pink">
           <div>
               <a href="/media/{item}">Page</a>
           </div>
       </div>
   {/each}
</div>

<style>
   .w-64 {
      width: 16rem;
   }

   .inline-block {
      display: inline-block;
   }

   .bg-pink {
      background-color: rgb(241 126 184)
   }
</style>

I've made a ~20-line minimum live repro of the above here: https://www.sveltelab.dev/vg1t4x2cb8n84f4. Notice that when you click the refresh button, links are initially a bit apart from each other, and then flicker to come closer together. The same happens on a more massive scale throughout the rest of my application's components.

That said, this occurs only on SSR, so perhaps I should open an issue on the SvelteKit page.

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