question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Hydrated Nested Svelte Components Losing Styles

See original GitHub issue

I ran across a problem where a hydrated components nested component lost some or all of it’s styles. The following component has hydrate-client on it:

<!-- Navigation.svelte --!>
<script>
  import MobileMenu from './MobileMenu.svelte';
  let y;
  $: scrolled = y > 100;
  export let menu;
  let menuOpen = false;
</script>

<style>
  .navcontainer {
    position: fixed;
    top: 0;
    left: 0;
    padding: 25px 0 20px 0;
    width: 100%;
    align-items: center;
    justify-content: center;
    background-color: rgba(0, 0, 0, 0.1);
    transition: background-color 0.3s ease;
    --small: var(--media-lte-sm) none;
    display: var(--small, flex);
  }
  .navcontainer.scrolled {
    background-color: #162b2e;
  }

  a {
    color: #2a8290;
    font-size: 19px;
    margin: 0 24px;
    padding: 4px 20px;
    text-decoration: none;
    display: inline-flex;

    transition: background-color 0.3s ease;
  }

  a:visited {
    color: #2a8290;
  }

  a:hover,
  a:focus {
    background: rgba(255, 255, 255, 0.2);
  }

  a.scrolled {
    color: white;
  }

  a.scrolled:visited {
    color: white;
  }

  .hamburger {
    position: absolute;
    padding: 30px;
    top: 6px;
    right: 6px;

    --small: var(--media-lte-sm) initial;
    display: var(--small, none);
  }
  img {
    height: 16px;
    place-self: center;
  }
  span {
    display: grid;
    grid-gap: 8px;
    grid-template-columns: auto auto;
    justify-items: center;
  }
</style>

<svelte:window bind:scrollY={y} />
<div class="navcontainer" class:scrolled>
  <nav>
    {#each menu as { url, name }}<a href={url} class:scrolled> {name} </a>{/each}

    <a rel="noreferrer" href="https://forms.gle/6PBKXng9jfrvxjhX8" target="_blank" class:scrolled> Sign Up </a>

    <a rel="noreferrer" target="_blank" href="https://twitter.com/sveltesociety" class:scrolled>
      <span> <img src="/dist/static/images/twitter.svg" alt="" /> Twitter </span>
    </a>
  </nav>
</div>
<div class="hamburger" on:click={() => (menuOpen = true)}><img src="/dist/static/images/burger.svg" alt="" /></div>

{#if menuOpen}
  <MobileMenu {menu} on:click={() => (menuOpen = false)} />
{/if}

and

<!-- MobileMenu.svelte --!>
<script>
  export let menu;
</script>

<style>
  .container {
    background: #17353a;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    overflow: scroll;
  }
  ul {
    padding-top: 100px;
    padding-bottom: 100px;
    display: grid;
    grid-gap: 40px;
    list-style: none;
  }
  li {
    text-transform: uppercase;
    font-family: Anton;
    font-size: 48px;
    line-height: 120%;
  }
  a:hover {
    color: white;
    opacity: 1;
  }
  a {
    color: var(--sky-blue);
    opacity: 0.6;
    text-decoration: none;
    letter-spacing: 0.6px;
  }
  img {
    padding: 30px;
    position: absolute;
    top: 6px;
    right: 6px;
  }
</style>

<div class="container">
  <ul>
    {#each menu as { name, url }}
      <li><a on:click href="/{url}">{name}</a></li>
    {/each}
    <li><a href="https://forms.gle/6PBKXng9jfrvxjhX8" rel="noreferrer" target="_blank"> Sign up </a></li>
    <li><a target="_blank" href="https://twitter.com/sveltesociety">Twitter</a></li>
  </ul>
</div>
<button on:click> <img src="dist/static/images/close.svg" alt="" /> </button>

The workaround I found is to move the content of MobileMenu.svelte into Navigation.svelte.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:15 (6 by maintainers)

github_iconTop GitHub Comments

2reactions
nickreesecommented, Oct 31, 2020

@x4080 yup. Should be good to go. @arggh should also be fixed. Let me know if you guys hit snags.

1reaction
nickreesecommented, Sep 21, 2020

@kevmodrome @x4080 @arggh

It appears that the css isn’t emitted when there is a boolean that is false-y during SSR. Another work around for V1 is to use process.env.componentType === 'server' to generate a SSR only true boolean. This would mean let menuOpen = false; would become let menuOpen = process.env.componentType === 'server';.

I think it may be worth opening an issue with Svelte on because it appears that NOT emitting CSS on the client is the desired behavior… except when the compiler is given ‘ssr’.

Having discussed the options with @halafi, Elder.js has few ways to solve this problem directly due to our complex rollup process.

  1. Use something like ./src/**/*.svelte to glob for all svelte files and have the svelte compiler emit css so it can be managed by rollup plugins and merged into an all.css. The big downside here is that on projects with more than a handful of components re-bundling will take a lot longer during development.
  2. Have all components emit their css into a folder within the ___ELDER___ folder. After the rollup process is done, we then glob that folder, merge the css together into an all.css then copy it where it needs to go.

I like the 2nd option the best, but not sure how to get a script to fire EVERY time rollup runs if it isn’t a rollup config.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Introduction / Nested components • Svelte Tutorial
Notice that even though Nested. svelte has a <p> element, the styles from App. svelte don't leak in. Also notice that the component...
Read more >
Full Stack SvelteKit For Beginners - Joy of Code
File based routing; Figure out how to server-render a component; Hydrate the ... In this section you're going to learn how to use...
Read more >
Documentation - SolidJS · Reactive Javascript Library
assume this code is in a component function, so is part of a rendering phase ... This is useful for nested reactive scopes...
Read more >
Goober: A lightweight CSS-in-JS solution - LogRocket Blog
We now use component-based libraries like React and Vue.js to ... It even has nested styled-components; It enables us to extend styles.
Read more >
Stop Overcomplicating Web Development - Try Svelte
svelte, a Svelte component can be pretty simple, containing three parts; html, a script tag to put your javascript, and a style tag...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found