Short on custom elements
An exciting option with custom elements is to wrap the helper structure around valid markup.
<custom-element>
<h1>Happy birthday</h1>
</custom-element> And enhance the content with the possible APIs. With the blessing of JavaScript you can implement nice-to-have features which wouldn’t be possible with the markup language only.
I was reminded of this option quite recently in the context of a vector graphic. In the body of an svg element you can draw text with the element of the same name, text.
<svg>
<text x="5" y="20"><!-- ... --></text>
</svg> You can also color the letters with the fill attribute, but alas, you can’t paint the background. Not as freely as you can for HTML elements, with the background property.
We can work around the issue with JavaScript. You measure the text element, and programmatically draw a rectangle, before the text and with a rect element.
<rect fill="black" x="2.5" y="2.5" width="120" height="21.25" />
<text fill="white" x="5" y="20"><!-- ... --></text> For the position and the dimensions you rely on the getBBox method, but without stressing the implementation details, the important fact is that you indeed can.
With this in mind, why a custom element would be just perfect to pull off the task. Delegate the job to a class and you would only need to augment the markup.
<text-background>
<text x="5" y="20"><!-- ... --></text>
</text-background> Unfortunately, the party is spoiled by a quick fact: custom elements are HTML custom elements. Their reach does not spread to other specifications such as SVG or MathML.
In the specific instance the text completely disappears, and there is no way to bring it back fabricating your own custom structure. Here you would also stumble in the class signature, where you’d like to extend an element, but which element is up to debate.
customElements.define(
'text-background',
class TextBackground extends SVGGElement {
/* ... */
},
{ extends: 'g' }
); Extending an SVGGElement, the interface for a generic group, prompts an error, stressing the point mentioned earlier.
Once again, custom elements are defined and managed by the DOM standard, and live in the HTML spec.
It is therefore not possible to complete the operation for single text elements. But once you understand the reason, the good news is that you can lift your spirit by lifting the logic up a few levels. Instead of adding a custom element around a text node, include it as a true HTML element, around the entire svg.
<text-background>
<svg>
<!-- ...text -->
</svg>
</text-background> Do this and you gain the option to inspect the markup. You can even extend the feature to consider all text elements, however many there might be. The biggest challenge is to then insert the rectangles for the made-up background in the right place. But I’m more than positive you can figure out how by yourself.