Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use my own optionally namespaced HTML tags if I'm setting the CSS for each one?

I'd like to my own HTML tags but I don't want new tags that might use the same name to cause them to break in the future.

Is this a good idea? Could I use a namespace to avoid conflicts?


Example:

HTML :

<b:HGroup>
    <span>item 1</span><span>item 2</span><span>item 3</span>
</b:HGroup>

CSS:

@namespace b "library://ns.example.com/framework/1";

b|HGroup {
   display:inline-block;
   vertical-align: middle;
}

I read a related question and it suggests DTD. I'd rather not create a DTD but if it's necessary, then I'd like to define it inline. Also, I'd like it to be run as HTML5, not XHTML.


Note:

I do NOT want to use div plus a class.

As far as I understand it, it looks like custom elements I've written will not be overwritten by future elements of the same name if I explicitly register my custom element. Here is a quote from the W3:

Because element registration can occur at any time, a non-custom element could be created that might in the future become a custom element after an appropriate definition is registered. Such elements are called undefined potentially-custom elements. If such a definition is ever registered, the element will be upgraded, becoming a custom element.


I've included a full page prototype based on the answers and I can't get it to attach any CSS to any element with a namespace. I've included some JS I found on one of the links but commented out part of it that was giving me errors. My main concern is getting elements with namespaces to be styled by the CSS with namespaces. From how I understand it that should work without JS.

<!DOCTYPE html>
<html xmlns:xhtml="http://www.w3.org/1999/xhtml"
  xmlns:s="http://www.w3.org/2002/spark"
  xmlns:space="http://www.w3.org/2002/space"
  xmlns:spaced="http://www.w3.org/2002/spaced">
<head>

<script>
  "use strict";
 
  const inDocument = document.querySelector("example-element");
  const outOfDocument = document.createElement("example-element");
  // Before the element definition, both are HTMLElement:
  //console.assert(inDocument instanceof HTMLElement);
  //console.assert(outOfDocument instanceof HTMLElement);

  //class ExampleElement extends HTMLElement {};
  //customElements.define("example-element", HTMLElement);
  
  //class ExampleElement3 extends HTMLElement {}
  //customElements.define("element3", ExampleElement3);

  //document.body.appendChild(outOfDocument);
  
</script>
<style>

@namespace s url(http://www.w3.org/2000/spark);
@namespace space url(http://www.example.com/2000/spark-space);
@namespace spaced "http://www.example.com/2002/spark-spaced";

example-element {
    color: red;
    display:block;
}
element2 {
    color:green;
    font-weight:bold;
}
s|element3 {
    color:yellow;
}
space-element {
    color:yellow;
}
space|space-element {
    display:block;
    color:yellow;
}
spaced|spaced-element {
    display:block;
    color:yellow;
}
</style>
</head>

    <body>
        <example-element>example-element</example-element>
        <element2>element 2</element2>
        <space-element>space element</space-element>
        <s:element3>s namespace element 3</s:element3>
        <space:space-element>space namespace el</space:space-element>
        <spaced:spaced-element>spaced namespace el</spaced:spaced-element>
    </body>

</html>
like image 224
1.21 gigawatts Avatar asked Mar 11 '16 07:03

1.21 gigawatts


People also ask

Are custom tags allowed in HTML?

All standard rules of HTML elements apply to custom elements. Just like standard elements, you can create a custom element in the DOM using JavaScript, or declare it in HTML.

How to use namespace in CSS?

The @namespace rule can also be used to define a namespace prefix. When a universal, type, or attribute selector is prefixed with a namespace prefix, then that selector only matches if the namespace and name of the element or attribute matches. In HTML5, known foreign elements will automatically be assigned namespaces.

Does HTML support namespaces?

The HTML namespaces (plural) in general are the collection of various namespaces in HTML code. The HTML namespace (singular) itself is the one associated with the namespace URI http://www.w3.org/1999/xhtml .


2 Answers

Custom HTML elements are supported by HTML5, but according to the specs they should contain a - character :

The name must contain a dash (-). So for example, <x-tags>, <my-element>, and <my-awesome-app> are all valid names, while <tabs> and <foo_bar> are not. This restriction allows the parser to distinguish custom elements from regular elements but also ensures forward compatibility when new tags are added to HTML.

See this article for a good introduction.

Applying CSS to custom HTML elements works the same way as applying CSS to standard HTML elements :

custom-element {
    font-weight: bold;
    background-color: #ff0;
}
<custom-element>
    This is a custom HTML element
</custom-element>
like image 171
John Slegers Avatar answered Nov 05 '22 18:11

John Slegers


You have a well researched question here. In doing so, you've eliminated all of the "valid" solutions.

You can definitely do what you have proposed, which (harmlessly*) breaks the standards. To be future proof, all HTML standards allow for unknown elements, instructing browsers to ignore them (essentially, they all become <span> elements) since there's no indication of what to do with them, though CSS can indeed affect them. This will work in ALL browsers, even Mosaic and the original IE (though CSS won't work in such ancient browsers).

As you already noted, the "proper" way to do this would be to define your own Document Type Definition (DTD) that can then be included at the top of your ~HTML document with the <!DOCTYPE> tag. This is probably overkill, but it is technically the right approach.

Another solution (that you've also eliminated) would be to use <span class="HGroup"> for inline elements and <div class="HGroup"> for block elements since these elements don't actually do anything by default.

A variant of that solution is to override the action of some otherwise useless tag and disable its standard properties in CSS, <s> for example:

s {
  text-decoration: none; /* remove line-through */
  display: inline-block;
  vertical-align: middle;
}

(* The "harm" you can run into with custom element names is that if you don't specify a DTD (your own or else an existing one with an exact version), a future version of the HTML standard could theoretically define some undesired property for your custom element.)

like image 39
Adam Katz Avatar answered Nov 05 '22 19:11

Adam Katz