svelte: Dimension bindings intermittently add inline style="position:relative;" in Firefox

Using dimension bindings on an element will sometimes add an inline style position:relative; in Firefox. This overrides any other CSS positioning that may be defined on the element. The problem doesn’t happen in Chrome.

The code below (borrowed from w3schools.com) reproduces the problem on my system roughly 50% of the time (although you may have to reload 10-20 times to see it, maybe due to page caching). I’m using Svelte 3.22.1 with Rollup, Firefox 75, Windows 10.

The inner div should be positioned to the right side of the outer div. When Svelte sometimes gives it position:relative; it is positioned to the left.

<script>
    import { onMount } from 'svelte';

    let clientWidth, clientHeight;
</script>

<style>
    .relative {
        position: relative;
        width: 400px;
        height: 200px;
        border: 3px solid #73AD21;
    } 

    .absolute {
        position: absolute;
        top: 80px;
        right: 0;
        width: 225px;
        height: 100px;
        border: 3px solid #73AD21;
    }
</style>

<h2>position: absolute;</h2>

<p>An element with position: absolute; is positioned relative to the nearest positioned ancestor (instead of positioned relative to the viewport, like fixed):</p>

<div class="relative">This div has position: relative;
    <div class="absolute" bind:clientWidth bind:clientHeight>This div has position: absolute; and right: 0;</div>
</div>

EDIT: I can’t reproduce this problem in Svelte’s REPL. This is another sign (along with the intermittency) that makes me think the bug is lifecycle related. If so then maybe the page loading delays caused by the REPL infrastructure avoid the problem.

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 6
  • Comments: 18 (6 by maintainers)

Most upvoted comments

Agree that position: relative should definitely not be added, this is not what should be expected from the developer perspective. Are there plans to remove this weird and not desired behavior?

I have been chasing down an intermittent problem on Safari where a sticky header was rendering incorrectly.

I found that the problem was caused by “element.style {position: relative;}” on the element that was supposed to be sticky. I could not see anything in our code that could be causing this. Finally, I looked at bundle.js and found it coming from svelte’s generated code. A quick search then brought me to this issue thread. And, yes, the element in question is using the dimension binding feature (for offsetHeight).

To fix the problem I added an onMount handler for the parent component that just does element.style.position=“” to clear out whatever svelte might have put there. Now the element properly behaves using the position: sticky property set in css.

This seems to me to be a real bug. Imo, svelte should never be setting the position property of one of my elements under the covers. But if it’s going to do that then it should at least do it in a predictable, consistent and well documented way.

This is still an issue. Took me an entire day to figure out why a list of components I was creating was getting position: relative added magically and messing up the position:absolute element I was trying to get styled and positioned correctly on top of them. I don’t think a javascript framework should be adjusting styles on the fly like this. This was really difficult to debug because there is no indication whatsoever in any documentation that if I add bind:clientHeight to a div I’m also getting position:relative as well.

I ran into this issue today while building a <Header /> component that swaps out Tailwind position classes (absolute | fixed) depending on the windows scrollY position and header’s clientHeight.

<header bind:clientHeight={header}>...</header>

I was super confused why my classes weren’t applying and thought I had a bug somewhere…but I eventually opened up dev tools to find the inline ghost style position: relative. The simplest hack fix for my scenario was adding the position classes to the component styles.

<style>
  .absolute { position: absolute; }
  .fixed { position: fixed; }
</style>

Would be cool to see a fix for this in the future!

@isaacHagoel anything is possible with preprocessors 😉 (PS: I’ll opt-out of this conversation for a bit since it’s a bit off topic, feel free to open a discussion in the repo though)