4 ms·
The element/attribute distinction is because HTML is a markup language, where the primary content is text and markup is used to add structure and metadata. You
by goto11 4y ago
The element/attribute distinction is because HTML is a markup language, where the primary content is text and markup is used to add structure and metadata.
You can eliminate attributes to get a simpler format, but it isn't really a markup language anymore, since the distinction between text and markup is removed. It is just a generic data structure, like JSON or s-expressions.
- chrismorgan 4y agoThe text/markup distinction is one I’ve been thinking a lot about recently as I’ve been both working on my own lightweight markup language, and implementing a component-based website using Django/Jinja/Nunjucks/whatever-style templates. There are too many places where you end up with attribute-like syntax, but want to pass markup, and it sometimes becomes unclear whether you’re working with a string or markup, yet the two are definitely different—in HTML serialisation, one needs escaping, the other doesn’t; or in something like DOM, one’s a string and the other’s a fragment. I’ve become progressively more and more convinced that these kinds of template languages are quite bad at writing this sort of thing. Take this example of unfortunate mixing: {% somecomponent attr="value", title="<strong>A:</strong> B" %} <strong>C:</strong> D {% endsomeecomponent %} Trouble is that you basically have at most one markup slot, but many things semantically want more than one. The closest you can generally get in such languages as these is the likes of this: {% somecomponent attr="value" %} <strong>A:</strong> B {% body %} <strong>C:</strong> D {% endsomecomponent %} This can be done in some such languages, but not others—and can’t be done in anything like XML. In XML, the solution would be extra nesting, which gets messy quickly: <somecomponent attr="value"> <title> <strong>A:</strong> B </title> <body> <strong>C:</strong> D </body> </somecomponent> In JSX I suppose you could do something like this, for better or for worse: <SomeComponent attr="value" title={<><strong>A:</strong> B</>}> <strong>C:</strong> D </SomeComponent> If you use a fragment/child nodes for what is logically a string value, you run the risk of people putting non-text in there; things like an href should clearly be strings, not text nodes—or else you have to decide what to do with <a><href>/<b>exam</b>ple</href>…</a>, and poorly-written DOM manipulators will surely occasionally assume the href element contains only one text node at times. But there’s then also the question of whether you want strings to be usable in text node context (probably the more pragmatic approach), or if you want to maintain a strong distinction between the two (probably the more correct approach). For my own language, in the more macroy part (when you’re extending it beyond the basic elements), I’m maintaining a distinction between strings and markup fragments, using different delimiters for the two, with "…" for strings and {…} for fragments. I’m also treating attributes and children equivalently, having all as possibly-named children. The basic example could be something like this in my current syntax: @somecomponent(attr: "value", title: {**A:** B}, { **C:** D })
- djedr 4y ago> The element/attribute distinction is because HTML is a markup language, where the primary content is text and markup is used to add structure and metadata. That may have been the idea, but it falls apart in implementation. Lines between content and metadata get blurred. Consider attributes like: input/value, input/placeholder, optgroup/label, img/alt, title. And then elements like: script, colgroup, col, title, noscript, noframes, applet, object, the void elements[0]. Then consider the ability of CSS to add content to elements, including lifting it from attributes[1], and, on the other side, completely hiding element contents. The line between metadata and data is conventional. It's all data in the end. But let's suppose it isn't and there is a hard line. Why should the metadata in attributes not be allowed to have structure and be extensible in the same way data is? > You can eliminate attributes to get a simpler format, but it isn't really a markup language anymore, since the distinction between text and markup is removed. It is just a generic data structure, like JSON or s-expressions. What I'm saying is that HTML-like attributes are not necessary to keep the distinction. You can keep the functionality, simplify things and at the same time make them more flexible. HTML-like attributes also don't stop people from using the language to describe generic data structures (XML). On the other side, if JSON or S-expressions had syntax and semantics that made them suitable as markup languages, I don't see a problem with that. [0] https://developer.mozilla.org/en-US/docs/Glossary/Void_element https://developer.mozilla.org/en-US/docs/Glossary/Void_eleme... [1] https://developer.mozilla.org/en-US/docs/Web/CSS/attr https://developer.mozilla.org/en-US/docs/Web/CSS/attr
- goto11 4y agoThe difference is not between tags and attributes, the difference is between text and markup. A markup language is human-readable text with added markup. A plain text file is basically a valid HTML file (I believe <title> is the only required element). You can then add markup to provide structure and metadata. This sets it apart from generic data structure formats. You can express the same information in JSON, but in JSON there is no distinction between text content and other information, it is all just structured data. Something like s-expression is clearly simpler than HTML syntax, and it is endlessly flexible, but it is just not optimized towards writing structured text content the way markup languages are.