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

preserveWhitespace does not behave according to the docs or the docs are vague rather #4337

Closed
Prinzhorn opened this issue Jan 29, 2020 · 4 comments · Fixed by #4341
Closed

Comments

@Prinzhorn
Copy link
Contributor

Prinzhorn commented Jan 29, 2020

Describe the bug

I'm aware of #189 (didn't read the whole thing) and #2258

Docs say

If true, whitespace inside and between elements is kept as you typed it, rather than optimised by Svelte.

"optimised by Svelte" is vague and not well-defined. Naive as I am I was expecting all whitespace between elements to be removed by svelte. But they are not.

To Reproduce
Paste into REPL:

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

	onMount(() => {
		console.log(el.childNodes);
	});
</script>

<span bind:this={el}>
	<span>a</span>
	<span>b</span>
</span>

Output

NodeList(3) [ span, #text, span ]

Expected behavior

Output

NodeList(2) [ span, span ]

The same example in React (JSX) behaves that way https://jsfiddle.net/pc5ozm1r/

Information about your Svelte project:

  • Your browser and the version: Chrome 79.0.3945.130, Firefox 72.0.1

  • Your operating system: Ubuntu 19.10

  • Svelte version: REPL

  • Whether your project uses Webpack or Rollup; Irrelevant, reproduces in REPL

Severity

It's more annoying than super sever. I'd have to resort to old hacks such as using font-size:0 on the wrapper to get rid of the whitespace, which would introduce all kinds of dependencies (suddenly my component would care about the context it is used in). I'd be more than happy with a non-awkward workaround.

Additional context

There is a long history of issues with whitespace between elements and there is currently still no clean solution https://stackoverflow.com/questions/2628050/ignore-whitespace-in-html
I was using React a while ago and forgot that problem even existed.

@antony antony added the docs label Jan 29, 2020
@ghost
Copy link

ghost commented Jan 29, 2020

One of the points of confusion I see is here are competing optimizations.

In the case above, the innerHTML optimization is kicks in and substitutes the child markup as-is, letting the browser apply whitespace eliding rules.

I will mention that putting the example html:

<span>
   <span>a</span>
   <span>b</span>
</span>

in a plain html page and rendering it actually results in 5 nodes [text,span,text,span,text] so Svelte is actually ahead of the game in this respect.

@Conduitry
Copy link
Member

Conduitry commented Jan 30, 2020

Would it help if the docs instead said "rather than collapsed to a single space where possible"?

@Prinzhorn
Copy link
Contributor Author

In the case above, the innerHTML optimization is kicks in and substitutes the child markup as-is, letting the browser apply whitespace eliding rules.

If I understand correctly that happens at runtime? While I believe the whitespace should and can be handled at compile time, regardless of how (innerHTML or whatever) it will actually be rendered at runtime.

so Svelte is actually ahead of the game in this respect.

you could also say Svelte behaves unexpected or is less predictable or more non-standard. The Browser does it one way, other Frameworks (e.g. React using JSX) do it a second, predictable way (no whitespace at all) and Svelte has its own (third) way.

Would it help if the docs instead said "rather than collapsed to a single space where possible"?

I don't think this can be solved with words. Maybe the compiler options should be accompanied by examples?

I'm also not sure if this is purely a "docs" things. What is the benefit of how Svelte does it? I'm still looking for a workaround that let's me keep using prettier (I don't want to cramp multiple <span> into a single line, they could also be mixed with plain text).

@Prinzhorn
Copy link
Contributor Author

Prinzhorn commented Feb 1, 2020

Is anyone aware of a workaround? I'd really appreciate it. It doesn't look like we're getting white-space-collapse: discard; in CSS anytime soon.

Example rendering a colored URL query string. This makes it obvious that I cannot control the whitespace as a user. It is impossible for me to cramp everything in a single line. I cannot set font-size: 0 because I cannot know the context that this component is put into, so there is no way to reset the font-size inside. inline-flex breaks other things.

<span class="query-string">
  {#each pairs as [key, value], index}
    {#if index === 0}
      <span>?</span>
    {/if}

    <span class="key">{key}</span>

    {#if value}
      <span>=</span>
      <span class="value">{value}</span>
    {/if}

    {#if index < pairs.length - 1}
      <span>&</span>
    {/if}
  {:else}
    <span>{search}</span>
  {/each}
</span>

Selection_573
Selection_574

[span, text, span.key.svelte-e0wic4, text, span, text, span.value.svelte-e0wic4, text, span, text, text, span.key.svelte-e0wic4, text, span, text, span.value.svelte-e0wic4, text, text]

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

Successfully merging a pull request may close this issue.

3 participants