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

Add an option to prefer void tags over self closing tags. #5246

Open
michaeljota opened this issue Oct 11, 2018 · 169 comments · May be fixed by #15021
Open

Add an option to prefer void tags over self closing tags. #5246

michaeljota opened this issue Oct 11, 2018 · 169 comments · May be fixed by #15021
Labels
lang:html Issues affecting HTML (and SVG but not JSX) status:needs discussion Issues needing discussion and a decision to be made before action can be taken type:option request Issues requesting a new option. We generally don’t accept these unless there is technical necessity.

Comments

@michaeljota
Copy link

michaeljota commented Oct 11, 2018

Update:

I have change my opinion on this, and I don't think I require this any more. If this is ever implemented I would probably use it, but I really don't mind this behavior at all. If you want to read more, I wrote a post in dev.to


Original post:

Prettier 1.14.3
Playground link

# Options (if any):

Input:

<input type="button">

Output:

<input type="button" />

Expected behavior:
I would like an option to prefer void element tags over the current implementation of self-closing element tags. I understand why is this the default behavior, as this is xml compatible, but several style guides suggest the usage of void tags as they are valid HTML5 tags. As I understand in the option philosophy, if there is enough usage from developers there is a justification to add the option.

Style Guides:

# Options:
--prefer-void-tags=true
<input type="button">
@ikatyang ikatyang added status:needs discussion Issues needing discussion and a decision to be made before action can be taken type:option request Issues requesting a new option. We generally don’t accept these unless there is technical necessity. lang:html Issues affecting HTML (and SVG but not JSX) labels Oct 11, 2018
@alexander-akait
Copy link
Member

I don't think we need option. I think we should print this as in source code, i.e. if you have <input type="button" /> print this as is.

Why:

  1. Compatibility with XHTML.
  2. It is out of scope prettier, here should be used linter to avoid HTML errors.

@lydell
Copy link
Member

lydell commented Oct 11, 2018

I think it's good that Prettier takes a stance here since this is something that programmers easily could have unnecessary debates over.

@thorn0
Copy link
Member

thorn0 commented Oct 11, 2018

It's about readability, not XML/XHTML. The moment you see a self-closing tag, you understand it's void. Otherwise you have to remember which tags are void. I'd prefer Prettier to remember this for me.

@michaeljota
Copy link
Author

@evilebottnawi As you can see in the link, that's not what is currently happening.

@thorn0 The current reason is not about readability, but compatibility with XML. Still, as I pointed in the issue, there are many style guide that suggest the usage of void element tags, even Google Style Guide suggest it.

Otherwise you have to remember which tags are void.

You would need to remember it any way. I don't see why you would stop doing it.

@thorn0
Copy link
Member

thorn0 commented Oct 11, 2018

The current reason is not about readability, but compatibility with XML.

You're mistaken, see #5098 (comment)

@michaeljota
Copy link
Author

@thorn0

A slash at the end of the tag can prevent us from such ambiguity and also support XHTML.

@ikatyang
Copy link
Member

Both readability (no ambiguity) and XHTML compatibility are the reason why I think self-closing is better than void.

And it'd be worse if it comes to sensitive whitespace, considering there's a void element with a super long opening tag:

  • prefer void over self-closing
    <input
      longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong
      longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong
      longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong
      longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong
      longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong
    ><span>something</span>
  • prefer self-closing over void
    <input
      longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong
      longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong
      longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong
      longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong
      longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong
    /><span>something</span>

@michaeljota
Copy link
Author

michaeljota commented Oct 12, 2018

Using the option --html-whitespace-sensitivity=ignore, the output is legible regardless if is void or self-closed.

  • Input
<input
  longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong="1"
  longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong="2"
  longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong="3"
  longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong="4"
  longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong="5"
><span>something</span>
  • Output: (Assuming void)
<input
  longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong="1"
>
<span>something</span>

BTW: As you can see, attributes with the same name are being ignored after the first one. I don't remember what's the behavior for all the browsers, but I think that at least Chrome actually just take the last one.

Playground link

@ikatyang
Copy link
Member

@michaeljota FYI, I tried it on parse5 and it takes the first one as well.

@michaeljota
Copy link
Author

michaeljota commented Oct 12, 2018

But, should it? Anyway, I don't think this is a big issue you can't actually have multiple attributes with the same name. I don't think it matters if it ignores the others or take the last.

@ikatyang
Copy link
Member

Missing duplicate attribute issue is fixed in a3ec5a6.

@michaeljota michaeljota mentioned this issue Oct 12, 2018
26 tasks
@pauldraper
Copy link

pauldraper commented Oct 12, 2018

Comment from #5098 (comment)


On void tags:

I understand the desire for a more consistent syntax. Unfortunately HTML opted for its own bespoke SGML-ish syntax instead of XML. (I am currently looking for anyone that is willing to loan me their time machine.)

Many style guides discourage self-closing void tags: Google, jQuery, Drupal, codeguide.co. (Counterexample: W3Schools, WordPress)

<input>
<input />

This may have to with reduced visual noise.

Or it may be related to the fact that until HTML5, self-closing tags were not even permitted. Back then it was SGML, where the syntax for a start tag can be <div/ and the ending tag is /, meaning self-closing tag is <div// (SHORTTAG NETENABL IMMEDNET). Thus <input /> was actually <input>&gt;.

I don't anyone's goal here is supportting HTML4, but anyway, most style guides don't use self-closing tags.


The current reason is not about readability, but compatibility with XML.

I think that as it stands the HTML parser will make a subpar XML formatter. If I am writing XML (including XHTML), I would expect that

<br />
<div></div>
<path></path>

becomes

<br />
<div />
<path />

@michaeljota
Copy link
Author

michaeljota commented Oct 12, 2018

From the w3 html5 syntax document here

Then, if the element is one of the void elements, or if the element is a foreign element, then there may be a single U+002F SOLIDUS character (/). This character has no effect on void elements, but on foreign elements it marks the start tag as self-closing.

So, there self-closing elements, and void elements are two separate things. I really would like for prettier to have this option, but I don't have any idea how to do it properly, but to have a know list of the void elements, but also for valid foreign elements that can be self-closing.

Update: I ended in the the w3 document from the reasoning from Drupal to drop the self-closing elements.

@pauldraper
Copy link

pauldraper commented Oct 13, 2018

Yes, "self-closing" elements technically are only foreign elements (i.e. elements in certain XML namespaces).

Void elements (area, base, br, col, embed, hr, img, input, link, meta, param, source, track, wbr) are HTML elements without closing tags. Since these affect parsing, they are defined as a part of the syntax section. HTML5.2, 8.1.2

"Self-closing void elements" colloquially refers to the practice, first permitted in HTML5, of writing void elements as if they were self-closing foreign elements.

I really would like for prettier to have this option, but I don't have any idea how to do it properly, but to have a know list of the void elements, but also for valid foreign elements that can be self-closing.

Any HTML5 parser (e.g. parse5) already has to know the list of self-closing elements, and properly detect foreign elements. Nothing new here.

There's no question of feasibility, only a question of desire of whether prettier should support the Google, jQuery, Drupal, etc. style guides.

@thorn0
Copy link
Member

thorn0 commented Oct 15, 2018

Prettier makes the very notion of style guide obsolete. Why care about this relic of the passing era of manual formatting?

@michaeljota
Copy link
Author

As I said, there is enough people using void elements, enough companies using void elements, to at least make an option for it.

I'm sorry, I get why you are against options, but this is a new parser, and a lot of people, and big companies, are using void elements, because they are void elements.

I don't see how this is different from the basic options to format Javascript. Those opinions where already there. As I see it, is the same thing here.

@thorn0
Copy link
Member

thorn0 commented Oct 15, 2018

I don't see how this is different from the basic options to format Javascript.

Read this issue tracker to learn the difference. There happened a long battle over each of those options. They have been added as a result of strong pressure from the community, not because of speculative attempts to foresee what people will want. So let's cross this bridge if we come to it.

@michaeljota
Copy link
Author

I see. Well, I guess I just wait until you get real feedback after this gets implemented. Thank you.

@felixfbecker
Copy link

Imo this is exactly the kind of discussion I do not want to have with coworkers and Prettier should just do what it does right now without an option. We should optimize for modern code, not old syntax, and there are arguments in favor of self-closing regarding readability and compatibility with XML. Now just let people write however they want and Prettier format it to self-closing on save, with no time wasted discussing it.

@snebjorn
Copy link

snebjorn commented Nov 8, 2018

I just ran the updated prettier on my html files and it converted my HTML5 <input>s to XHTML <input />. It made me a sad panda 😭

@lydell
Copy link
Member

lydell commented Nov 8, 2018

@snebjorn <input /> is valid HTML5 too! 🎉

@pauldraper
Copy link

pauldraper commented Nov 8, 2018

there are arguments in favor of self-closing regarding readability and compatibility with XML

Compatibilty with an entirely different language is an argument!?

In that case, consider that self-closing tags are incompatible with the last major version of HTML, HTML4.

@michaeljota
Copy link
Author

@snebjorn If you want to at least be able to chose, up vote the main issue. With enough votes I'm sure this will eventually land. 👍

@fisker
Copy link
Member

fisker commented Sep 21, 2023

@lrusso Prettier won't add more options, see https://prettier.io/docs/en/option-philosophy.

@tommy-gilligan
Copy link

Personally I blame React/Vue for twisting the HTML spec and dragging the tooling with them

💯

Another potential solution I've been thinking about:
Instead of a new parameter for the existing HTML formatter, create a new formatter (still part of Prettier) that focusses on formatting HTML (as opposed to JSX). Keep the old formatter for formatting JSX etc only.

@weakish
Copy link

weakish commented Sep 25, 2023

Personally I blame React/Vue for twisting the HTML spec and dragging the tooling with them.

The reason behind the twisting1 is implementation simplicity:

We could omit the trailing slash but we have to special case known void element tags which adds bytes and runtime cost so it's unlikely to give any gains. (facebook/react#25944)

Footnotes

  1. Trailing slash is not encouraged but still permitted by HTML5 spec.

@lrusso
Copy link

lrusso commented Nov 19, 2023

Hello everyone, a developer just wrote a plugin that takes cares of this requirement that the Prettier team doesn't want to implement:

#15336 (comment)

Before I was using patch-package for adding this required code, but the plugin is much better and cleaner 👍 I hope it can be useful for someone else 👍

@junaga
Copy link

junaga commented Nov 25, 2023

This Meta vs Google culture war is making me go mad. Can the prettier team please stop goofing around?

JSX != HTML && XHTML != HTML

Jake said it best. JSX is not HTML. XHTML is not HTML. HTML is HTML. github:whatwg/html is HTML. In HTML the / is ignored. We, devs on prettier, use indentation to write nested content in HTML. not /, no one needs /, it's boilerplate.

@fabulousgk
Copy link

It feels like this issue has become a sort of hill the devs are going to die on. Regardless of all the comments, the evidence the Prettier is creating code the violates standards (from standards authors themselves), and possible resolutions, they simply will not respond, engage or otherwise even countenance a discussion.

@43081j
Copy link

43081j commented Jan 22, 2024

It feels like this issue has become a sort of hill the devs are going to die on. Regardless of all the comments, the evidence the Prettier is creating code the violates standards (from standards authors themselves), and possible resolutions, they simply will not respond, engage or otherwise even countenance a discussion.

one of the maintainers did actually try picking this up last time the issue made its rounds, but seems they never got around to it (sosukesuzuki).

fisker also tried to do this in a PR long ago, but was rejected at the time by the rest of the maintainers iirc. opinions have likely changed since then, though (since the ecosystem has too).

a while back, i created another issue for tracking the specific proposed fix (as opposed to this issue which is more of a discussion now, and no longer titled correctly since we don't want an option).

we can't really expect a maintainer to understand this thread anymore, it is too long (or to keep track of it). so you are still right in a way, it is unlikely to go anywhere without one of the maintainers dedicating a large chunk of time to it.

@samal-rasmussen
Copy link

samal-rasmussen commented May 21, 2024

Are there other examples where Prettier explicitly goes against the spec of the language that it is formatting? I would have thought that following the language spec would be a primary requirement for Prettier, so I am kinda dumbfounded by this issue not being welcomed.

@KevinGIRAULT
Copy link

Instead of proposing an option, why not simply change the function to comply with the standard?
That would respect Prettier's philosophy. Who will it really impact?

@43081j
Copy link

43081j commented May 21, 2024

Instead of proposing an option, why not simply change the function to comply with the standard? That would respect Prettier's philosophy. Who will it really impact?

Already tracked elsewhere in a separate issue fyi.

This issue is specifically for adding an option and seems unlikely to result in anything given how old it is now.

I forget the issue number but changing the behaviour has been raised there instead

@junaga
Copy link

junaga commented May 26, 2024

The Hate will flow in, but it will take many more months, before Prettier is "defeated". this is an forever-issue already, the maintainers dont care, and they think they are above the law - above the ecosystem. Just switch to Biome today, it's not worth to keep track of their "progress".

@awmottaz
Copy link

Seeing as this is the issue specifically requesting a new configuration option, I'm going to restate my comment from the other issue:

Fixing this from plugin-land is really difficult (I've attempted it and struggled with nasty edge cases because the plugin APIs don't really support doing anything like this).

So I am asking once again: Is the Prettier team open to a PR that would enable this alternative formatting behind a config option?

Changing the behavior outright is a hugely disruptive breaking change, so it seems like an opt-in approach is warranted. I'm happy to try implementing it.


@KevinGIRAULT @43081j

Instead of proposing an option, why not simply change the function to comply with the standard? That would respect Prettier's philosophy. Who will it really impact?

Already tracked elsewhere in a separate issue fyi.

This issue is specifically for adding an option and seems unlikely to result in anything given how old it is now.

I forget the issue number but changing the behaviour has been raised there instead

It's tracked in #15336

@junaga
Copy link

junaga commented Jun 28, 2024

@lrusso Prettier won't add more options, see https://prettier.io/docs/en/option-philosophy.

sorry, but what do you think prettier is? POSIX? HTTP? I honestly don't see how a couple more options could hurt, just compare the amount to eslint options. ryan once said that things that are so perfect they "feel cute" are always regretted down the road.

@awmottaz
Copy link

In the "Option Philosophy" page, Prettier lists a few examples of options that are "easier to motivate":

  • --trailing-comma es5 lets you use trailing commas in most environments without having to transpile (trailing function commas were added in ES2017).
  • --prose-wrap is important to support all quirky Markdown renderers in the wild.
  • --html-whitespace-sensitivity is needed due to the unfortunate whitespace rules of HTML.
  • --end-of-line makes it easier for teams to keep CRLFs out of their git repositories.
  • --quote-props is important for advanced usage of the Google Closure Compiler.

They also mention this caveat at the very end:

There may be situations where adding an option can’t be avoided because of technical necessity (e.g. compatibility), but for formatting-related options, this is final.

It seems to me that this issue is precisely a compatibility issue and not a request for a formatting-related preference:

  • The W3C validator wiki section on trailing slashes and void elements explains how self-closing syntax on void elements is unnecessary and potentially problematic with unquoted attribute values. Prettier actually guards against that pitfall, since <br data-foo=bar> and <br data-foo=bar/> both get formatted into <br data-foo="bar" />, so I'm less worried about problems that arise from this usage of self-closing tags.
  • According to the HTML spec, self-closing syntax is only allowed on void elements and foreign elements anyway. For non-void elements, the syntax is invalid (the W3C HTML validator will produce an error) and it is ignored. So arguably Prettier shouldn't be printing <div /> anyway (even though it totally will). This is definitely a compatibility issue. For example, see Svelte parses HTML all wrong.
  • This blog post also articulates some specific issues from how Prettier handles self-closing syntax: The case against self-closing tags in HTML — Jake Archibald.

Note

An argument can be made that there should be two separate issues on the topic of self-closing syntax: one issue for how to format void HTML tags, and a separate issue for how to format non-void HTML tags. If that's desirable, I'll happily open new issues to keep those conversations isolated.

I would love to hear from a Prettier maintainer whether they agree that this rises to the level of a compatibility issue that warrants an option. Or — if this is something that Prettier should change without adding an option, I'm happy to continue the discussion in #15336.


And please, let's keep this conversation well-reasoned and civil. No matter how old this issue is, or how frustrated you are about whatever, no amount of fist-shaking is going to help make progress. This issue is still Open, after all 😄

@egrieco
Copy link

egrieco commented Jul 2, 2024

Well said @awmottaz. The reason why I'd like this option is that every time prettier runs, it introduces validation errors into my pages that are flagged by other tools.

It's really annoying to have to choose between well formatted code and code that actually validates.

The only "viable" workaround is to write a mini script that runs after prettier and fixes the syntactic damage it introduces so that pages validate properly.

...or to switch to Biome once that actually supports CSS.

@elandorr
Copy link

elandorr commented Jul 2, 2024

For new posters: This is from 2018 with no response from the maintainers.

Forget it.

I posted https://beautifier.io/ here before with some flags to get it quite close to prettier. It's not some 'opinionated' bullshit, and does JS/CSS/HTML.

Not a kewl new kid on the block, but it works well.

There are many others, too.

It's funny to see this thread being active still, but maybe it's time to unsubscribe.

@TPReal
Copy link

TPReal commented Jul 2, 2024

I've been subscribed to this thread for over 4 years, just for entertainment, and it's still worth it.
As for formatting code, I ditched prettier years ago, and this was one of the reasons.

@egrieco
Copy link

egrieco commented Jul 2, 2024

I've been subscribed to this thread for over 4 years, just for entertainment, and it's still worth it. As for formatting code, I ditched prettier years ago, and this was one of the reasons.

There are bugs like this on every project out there. "Small" stuff that is a complete deal breaker for a number of users.

It makes sense on corporate projects as everyone is trying to push some new blockbuster feature to get a promotion. But it's harder to understand on open source projects.

Sometimes "papercuts" bleed a lot more than expected.

@egrieco
Copy link

egrieco commented Jul 2, 2024

I posted https://beautifier.io/ here before with some flags to get it quite close to prettier. It's not some 'opinionated' bullshit, and does JS/CSS/HTML.

What were the flag combinations that you suggested? I don't see them above.

There are many others, too.

What other options do you recommend? @junaga has suggested Biome but as far as I can tell, it doesn't support CSS yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lang:html Issues affecting HTML (and SVG but not JSX) status:needs discussion Issues needing discussion and a decision to be made before action can be taken type:option request Issues requesting a new option. We generally don’t accept these unless there is technical necessity.
Projects
None yet
Development

Successfully merging a pull request may close this issue.