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 · 157 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 · 157 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. 👍

@mangelozzi
Copy link

2cents...
As someone who has just made friends with the default value of bracketSameLine after at first thinking it's very strange...

I must say I thought this behavior was very strange when I first encountered it, and Jake Archibald makes a good case against it too: https://jakearchibald.com/2023/against-self-closing-tags-in-html/

...But I think its about readability with the rest of the defaults, e.g.

<md-input-container class="md-block">
    <label>Buying</label>
    <md-select
        required
        ng-model="create.data.Buying"
        md-on-open="create.loads(create)"
    >
        <md-option
            ng-value="terms"
            ng-repeat="terms in create.value"
        >
            <input
                ng-if="cowsGoMoo"
                ng-repeat="Only on tuesdays"
            />   
            <!-- This where you would expect the code to be indented again unless you see the "/>" -->
            <span>Hello<span>
            {{DeliveryTerms}}
        </md-option>
    </md-select>
</md-input-container>

Here we can follow the indentation because of the self closing, without it you would have to check every tag.

@danielniccoli
Copy link

danielniccoli commented Aug 25, 2023

Prettier takes an opinionated stance on reformatting void elements to self-closing elements and imposes its choice on the developer. I would be fine with that, if we're talking about coding style (I also use Python/Black that almost offer no configurations). But the HTML5 specs are very clear on void elements. I read some comments here talking about XHTML, but I don't see how it applies to HTML5 documents. That's two different specs altogether. I'm not in favour of this and I hope the behaviour will change for HTML5 documents. At least give us an option like preserveVoidElements.

@tommy-gilligan
Copy link

Vnu complains about Prettier output with

Trailing slash on void elements has no effect and interacts badly with unquoted attribute values.

I really did not expect Prettier to be doing this. If I was writing XHTML, I'd expect this but I'm not writing XHTML. I'm writing HTML.

@lrusso
Copy link

lrusso commented Sep 9, 2023

This issue was reported 5 years ago and the PR was submitted already (#15021). The code provides what is requested as something optional, not mandatory. Can someone take a look at this please?

cc: @fisker @sosukesuzuki @thorn0

@lrusso
Copy link

lrusso commented Sep 20, 2023

Is there some reason why the fix to this issue is deliberately ignored?

#15021

@fisker @sosukesuzuki @thorn0

@fabulousgk
Copy link

Is there some reason why the fix to this issue is deliberately ignored?

#15021

@fisker @sosukesuzuki @thorn0

Willfull stuborness

@sosukesuzuki
Copy link
Member

I am opposed to adding new options for this matter, in alignment with our option philosophy.

To be transparent, I don't have a personal interest in this issue. However, it appears to be important to some users. With that in mind, I'll revisit this thread and examine the relevant HTML specifications.

Please understand that both myself and the other maintainers have limited availability due to our current workload. We may not have sufficient time to address such complex issues at this time.

@danielniccoli
Copy link

danielniccoli commented Sep 20, 2023

I am opposed to adding new options for this matter, in alignment with our option philosophy.

To be transparent, I don't have a personal interest in this issue. However, it appears to be important to some users. With that in mind, I'll revisit this thread and examine the relevant HTML specifications.

Please understand that both myself and the other maintainers have limited availability due to our current workload. We may not have sufficient time to address such complex issues at this time.

Hi @sosukesuzuki, thanks for taking the time to look into this.

I've been one to voice the removal of the trailing slash on void elements. I wanted to help you find the correct sections in the specs that declare self-closing tags as technically incorrect on void elements. "Unfortunately" I ended up refuting my own argument while researching it. Oops. Anyway, here are the sections that talk about this:

https://html.spec.whatwg.org/#elements-2

Void elements
area, base, br, col, embed, hr, img, input, link, meta, source, track, wbr

https://html.spec.whatwg.org/#start-tags

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 (/), which on foreign elements marks the start tag as self-closing. On void elements, it does not mark the start tag as self-closing but instead is unnecessary and has no effect of any kind. […]

So void elements can be self-closing. However, that paragraph ends with:

[…] For such void elements, it should be used only with caution — especially since, if directly preceded by an unquoted attribute value, it becomes part of the attribute value rather than being discarded by the parser.

So I would still argue that it's better to not force this on the developer. But I don't have any other hard facts that would prove Prettiers current stance technically incorrect.

Hope that helps.

@sideshowbarker
Copy link

To clarify one point:

html.spec.whatwg.org/#start-tags

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 (/), which on foreign elements marks the start tag as self-closing. On void elements, it does not mark the start tag as self-closing but instead is unnecessary and has no effect of any kind. […]

So void elements can be self-closing.

That’s not correct. The spec explicitly says, “On void elements, it does not mark the start tag as self-closing”. The only elements that can be “self-closing” are foreign elements.

I worked on that language in the spec, so I can speak with some authority about at least what the intent of that language is. And so also if anybody finds that the current language in the spec isn’t clear enough, I’m happy to work on refining it to add greater clarity. There’s a related open issue at whatwg/html#9642, the gist of which is if/how we should state even more strongly in the spec that authors/developers should not be using the trailing slash.

@fisker
Copy link
Sponsor Member

fisker commented Sep 20, 2023

Personally, I strongly prefer void tags, but other team members seems prefer the current implementation.

I wounder how other members think, if we respect the original input? So we can enforce void tags with other tools without conflicts.

@lrusso
Copy link

lrusso commented Sep 20, 2023

Personally, I strongly prefer void tags

To be transparent, I don't have a personal interest in this issue.

The pr at #15021 provides a logic that:

  • Is disabled by default.
  • Is not mandatory.
  • Is optional.
  • It won't affect developers that doesn't like or want void tags.
  • So developers that are not interested in this, won't be aware that this logic/feature/rule even exists because it won't be enabled by default.

cc: @fisker @sosukesuzuki @thorn0

@lrusso
Copy link

lrusso commented Sep 21, 2023

Beside my previous comment, here is an example (https://validator.w3.org/nu/?doc=https%3A%2F%2Ftn.com.ar%2F) where the optional fix at #15021 will be useful where there are lot of messages saying:

Trailing slash on void elements has no effect and interacts badly with unquoted attribute values.

cc: @fisker @sosukesuzuki @thorn0

@austinw-fineart
Copy link

Personally I blame React/Vue for twisting the HTML spec and dragging the tooling with them. You'd never see this sort of tug-o-war between TypeScript and JavaScript.

@fisker
Copy link
Sponsor 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.

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.