Skip to content

Decide whether to allow custom self-closing elements. #5563

Closed

Description

@jelbourn

Need to discuss and decide whether Angular will allow custom void elements (which aren't permitted by the HTML specification).

cc @vicb @tbosch

Activity

  1. added this to the beta.0 milestone on Dec 3, 2015
  2. kasperpeulen commented on Dec 3, 2015

    @kasperpeulen

    +1000

  3. Aetet commented on Dec 3, 2015

    @Aetet

    +1. Because this modular approach is not about only UI, but for Modular components in common. Because component may not view anything but must be present in hierarchy as high order component.

  4. pkozlowski-opensource commented on Dec 3, 2015

    @pkozlowski-opensource
    Member

    TL;DR;:

    • throw when you detect a closed void element
    • allow self-closing non-void elements

    @jelbourn IMO we are talking about 2 things here and looking at the different discussions I feel like we are mixing up 2 concepts:

    • HTML5 void tags - things like <input>, <img> etc. Those are clearly defined in the HTML spec as:

    The following is a complete list of the void elements in HTML: area, base, br, col, command, embed, hr, img, input, keygen, link, meta, param, source, track, wbr

    and then:

    A void element is an element whose content model never allows it to have contents under any circumstances.

    So IMO void elements should never ever have a closing tag in any form. IMO we should throw for both <img></img> and <img />. Only <img> should be allowed.

    Then, there is a second case for so-called self-closing tags (ex. <p /> ). AFAIK this is not not valid HTML5 code. It is just that browsers will try to auto-correct this invalid markup, but they can go horribly wrong! Just try <p /><div /> and compare your expectations with what actually happens :-)

    Now, the question is: shell we allow self-closing tags? IMO yes, as this is what many people expect to work. Having said this we need to be aware that this is clear departure from how HTML5 works.

  5. changed the title [-]Decide whether to allow custom void elements.[/-] [+]Decide whether to allow custom self-closing elements.[/+] on Dec 3, 2015
  6. pkozlowski-opensource commented on Dec 3, 2015

    @pkozlowski-opensource
    Member

    Oh, actually it loos like void elements can have an optional self-closing tag. From http://www.w3.org/TR/html-markup/syntax.html#syntax-elements:

    Optionally, a "/" character, which may be present only if the element is a void element.

    Which means that we should allow <input /> but not <input></input> (same applies to other void elements)

  7. pkozlowski-opensource commented on Dec 3, 2015

    @pkozlowski-opensource
    Member

    BTW, I don't think it makes sense to say "custom void elements" since void elements are clearly listed in the spec and we can't add to this list. This is why I've changed the title of this issue to custom self-closing elements as custom elements can't be void.

  8. kasperpeulen commented on Dec 3, 2015

    @kasperpeulen

    BTW, I don't think it makes sense to say "custom void elements" since void elements are clearly listed in the spec and we can't add to this list. This is why I've changed the title of this issue to custom self-closing elements as custom elements can't be void.

    @pkozlowski-opensource I thought this was about custom elements that "act" like void elements. So for example, I would expect an error if I add a closing tag, and try to put elements inside the element.

  9. pkozlowski-opensource commented on Dec 3, 2015

    @pkozlowski-opensource
    Member

    I thought this was about custom elements that "act" like void elements.

    I don't think we should be arbitrarily choosing which custom elements are void and which are not. With HTML5 the situation is clear: there is a fixed set of void elements. If we start to add "custom" ones how on earth our users will know which ones are void and which ones are not?

    What I'm trying to say that IMO we should only have void elements as specified in the HTML5 spec. All the custom tags should be assumed non-void. What remains is to decide: do we want to support self-closing tags in our parser / compiler (which once again would be departure from HTML5 spec / current browser behavior).

  10. kasperpeulen commented on Dec 3, 2015

    @kasperpeulen

    If we start to add "custom" ones how on earth our users will know which ones are void and which ones are not?

    Well I think you would document that right? How on earth does a user know which input properties a
    custom element accepts? Well, read the documentation of the element :)

    Ideally, you can press F1 or something on the element in an editor/IDE, and the documentation will show up.

    I more see this as error prevention. If I specify that my element is "void-like" in my API. I expect that an editor, will show a warning, if someone tries to put content inside the element.

    I understand your point of view with regards to departure from HTML spec btw. This is just something I would really like to be able to do.

  11. mgol commented on Dec 3, 2015

    @mgol
    Member

    @pkozlowski-opensource

    Then, there is a second case for so-called self-closing tags (ex.

    ). AFAIK this is not not valid HTML5 code. It is just that browsers will try to auto-correct this invalid markup, but they can go horribly wrong!

    I don't think it's a real issue. All browsers supported by Angular 2 (including old Androids) except IE9 implement the HTML5 parser so the behavior is the same everywhere - <foo/> in HTML mode is always treated like <foo> (i.e. an unclosed tag which is fine for void tags).

    HTML5 doesn't allow to define custom void elements so I think we should stick to the standard ones. With those tags I think <foo/> should be allowed; for all other tags the form <foo></foo> should be required. In that case it will be possible to write templates that are both HTML- & XHTML-compliant and I think that's an important use case considering how easy it is to achieve.

  12. pkozlowski-opensource commented on Dec 3, 2015

    @pkozlowski-opensource
    Member

    I don't think it's a real issue.

    But this is confusing. Just try to do <p/></div/> and see what happens. I guess most people would expect this to be equivalent to <p></p><div></div> while browsers will "auto-correct" it to <p><div></div></p>

    All browsers supported by Angular 2 (including old Androids) except IE9 implement the HTML5 parser so the behavior is the same everywhere - in HTML mode is always treated like (i.e. an unclosed tag which is fine for void tags).

    Totally agree for void elements - this is part of the spec.

    IMO the only discussion here is about non-void elements (those not marked by void in the HTML5 spec).

  13. vicb commented on Dec 3, 2015

    @vicb
    Contributor

    Context:

    • <ng-content> has always been a void tag with the new parser,
    • <voidtag></voidtag> has always been allowed with the new parser - you can add an end tag for a void element if there is no content (which is not allowed by spec). Any subsequent content after the start tag closes the void element and then specifying an en tag would be an error, ie <void>some content</void> is an error,
    • because of a bug (html parser: text nodes do not close void tags #5528), void elements would only be closed if some content (from previous bullet point) is html. Text nodes would not close void elements but be added as children which is obviously wrong.

    After the fix <void></void> (no content) is still allowed but <void>whatever content</void> is always an error, whatever the content is (text/html).

    Things we have to decide:

    • do we want to allow void custom els (not allowed per spec),
    • do we want to allow self-closing custom els (not allowed per spec),
    • do we want to error on self-closing html element (p, ... ie all els not void or foreign)
  14. pkozlowski-opensource commented on Dec 3, 2015

    @pkozlowski-opensource
    Member

    @vicb

    <ng-content> has always been a void tag with the new parser,

    What was the reasoning behind it? As stated in my previous comments I don't think we should be adding void tags to the spec.

    has always been allowed with the new parser

    Are you saying that <input></input> would be valid? If so what would be reasoning behind it? This is clear departure from HTML5 spec and I don't see strong reasons for it.

    do we want to allow void custom els

    I'm not sure I understand this sentence. For me a set of void tags is fixed by the HTML5 spec and I don't see how we can extend it.

    How do you decide if a given custom element is void or not? What would be the rules here? If it can have content or not? Would directive / component authors be able to mark a component as "void"? IMO this is a very slippery slope.

    do we want to allow self-closing custom els (not allowed per spec),
    do we want to error on self-closing html element (p, ... ie all els not void or foreign)

    Isn't it the same case? Why would you like to distinguish between standard and custom elements?

  15. vicb commented on Dec 3, 2015

    @vicb
    Contributor

    Are you saying that <input></input> would be valid?

    It would. One of the reason is <ng-content></ng-content> as some tools would automatically add the end tag. Plus I think it is supported by browsers.

    Would directive / component authors be able to mark a component as "void"?

    No. That's a ng-content specific thing that might go away.

    Isn't it the same case?

    One of the goal of switching to the new parser was to allow self closing custom els. Again, this is being reconsidered

  16. pkozlowski-opensource commented on Dec 3, 2015

    @pkozlowski-opensource
    Member

    One of the reason is as some tools would automatically add the end tag.

    I'm not sure why we are treating <ng-content> and <input> the same way. IMO we are running into problems since we try to have <ng-content> being a void one, and I'm not sure why we want to have is as void.

    That's a ng-content specific thing that might go away.

    Yeh, I wouldn't try to do ng-content any special

    One of the goal of switching to the new parser was to allow self closing custom els. Again, this is being reconsidered

    Right. I'm still good with having self-closing tags. We just need to make sure that void elements are special case - that is, you can't have <input></input>

  17. IgorMinar commented on Dec 3, 2015

    @IgorMinar
    Contributor

    Hi folks,

    we considered many options are here is the conclusion:

    • the default html parser will throw if it comes across a custom element that is self-closing or missing closing-tag
    • in the future we will make it easy to use custom template parsers that can support self-closing custom elements

    reasoning:

    • current angular html templates are valid html5 fragments (even after the case-sensitivity change, they will be valid html5, but with higher fidelity)
    • custom element spec currently doesn't allow custom elements to be self-closing or void
    • we should not deviate from standards
    • we care about usability though and that's why we'll make it possible to author templates in other syntaxes (e.g. xhtml5, custom stuff, jade, whatever)
    • we don't want to rush the decision on the default behavior since we are under beta pressure. relaxing this rule in the (near) future even for the default parser is possible without a breaking change (the reverse is not)
  18. added a commit that references this issue on Dec 4, 2015
    e67e195
  19. kylecordes commented on Dec 4, 2015

    @kylecordes

    I was surprised by the alpha 47 behavior, concerned by this issue earlier today, and am thrilled to see it resolved fast in a sane, wise, standards-compliant way. Big +1 to the Angular team here, thank you.

  20. ksa-real commented on Aug 27, 2016

    @ksa-real

    BTW As of today Chrome/Opera/Safari/Firefox 'autocorrect' <p/><div/> as <p></p><div></div>. Hasn't tested on IE yet.

  21. romanzoller commented on Aug 16, 2017

    @romanzoller

    BTW As of today Chrome/Opera/Safari/Firefox 'autocorrect' <p/><div/> as <p></p><div></div>. Hasn't tested on IE yet.

    I tested with Chrome 59, and the behavior is as you say, but on the other hand, <p/><span/> is corrected to <p><span></span></p>, which I think is the confusion that @pkozlowski-opensource was referring to (see fiddle, see also corresponding issue for AngularJS: angular/angular.js#1953).

  22. angular-automatic-lock-bot commented on Sep 12, 2019

    @angular-automatic-lock-bot

    This issue has been automatically locked due to inactivity.
    Please file a new issue if you are encountering a similar or related problem.

    Read more about our automatic conversation locking policy.

    This action has been performed automatically by a bot.

  23. locked and limited conversation to collaborators on Sep 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions