Gracefully degrading a Custom Element (or Polymer element) - polymer

A number of developers have been wondering how graceful degradation should be approached in custom elements (or Polymer elements). This is for the use-case where either polyfills are not being used, Web Components are not supported or JavaScript is simply switched off.
Does anyone have thoughts on how this should be done?

There are two types of custom elements we're usually interested in adding support for graceful degradation to: Custom Elements that extend native HTML tags and Custom Elements which do not.
Custom Elements support natively extending elements already baked into the platform (e.g <button>, <input>). One way of doing this is using the is syntax. So, if you're extending a built-in, I believe the most direct way to ensure graceful degradation is to use the is syntax as follows: <button is="my-button"> rather than <my-button></my-button>.
Some examples of where I could see this working well are:
Fancy input fields:
<input is="fancy-input" type="text" value="So fancy">
Custom video players:
<video is="custom-player" src="amazeballs.mp4">
Music visualizers:
<audio is="music-visualizer" src="track.ogg">
This way if a browser without Custom Element cannot understand the is syntax, the element being extending should still work with a degraded experience.
What about Custom Elements where you are not extending a specific built-in? For example: <my-preload-animation>.
One approach I've been taking to this is specifying fallback content in the Light DOM:
<my-preload-animation>
Loading...
</my-preload-animation>
If a browser without Custom Element support interprets the tag as HTMLUnknownElement, the fallback (a loading message) will still be rendered. This (appears) to work for simple elements.
For more complex ones (e.g if you're making use of <content>/<shadow> in your element), I remove the fallback via script when my custom element is upgraded.

I think that's reasonable. This is how most (not all) HTML elements work. Check out this blast from the past: http://code.tutsplus.com/tutorials/quick-tip-html5-video-with-a-fallback-to-flash--net-9982

Related

FontAwesome SVG + JS with pseudo-elements performance issue on Select2

I'm actually using the FontAwesome 5 package, using the SVG+JS implementation with the "data-search-pseudo-elements" option.
I'm in a context where I use a "Select2" plug-in to display a <select> element, which is containing nearly 600 options (for a timezone selection). But when I try to open the select to choose an option, it takes a very very long time to open (which doesn't occur when using the CSS framework, or when pseudo-elements are disabled)!
A little look in browser performances panel seems to show that it's the FontAwesome script which is responsible of this, while there is no pseudo-element in the elements generated by Select2.
Is there any way to improve FontAwesome performance, or to avoid its activation for some HTML elements?
As long as you have data-search-pseudo-elements enabled, Font Awesome will scan the DOM when changes are made, looking for any pseudo-elements that represent icons that should be converted into <svg> elements.
Unfortunately, a scenario like you've described is the Achilles heel of this feature. Scanning the DOM for all possible pseudo-elements can be slow when there are many DOM elements. And the Mutation Observer causes re-scans to occur whenever the DOM changes--which is what sounds like is happening when you open that select control.
So it's probably best to avoid SVG/JS with pseudo-elements in a situation like this.
While I would not recommend putting more effort into trying a work around, if you're up against a wall and for some reason have a requirement to continue using SVG/JS and pseudo-elements together like this, then here are two possibilities:
If you don't need the MutationObserver to watch for changes, then you could disable it altogether using the Configuration API. For example, add data-observe-mutations="false" to your <script> tag.
If you do need the MutationObserver to watch for changes elsewhere in the DOM, but not on this select control, then after disabling the MutationObserver on load (using the above), you could kick it off programmatically on a smaller region of the DOM using the dom.watch() API with a observeMutationsRoot parameter that is more narrowly scoped. By default, the MutationObserver, when enabled, scans everything under a root of document.body, but this is a way that you can make it work on a smaller region of the DOM.
If you have a requirement to support pseudo-elements, and especially if you need to support that in a DOM with many elements, and especially especially if the DOM is changing a lot, it's almost certainly going to be best for you to use the CSS/Webfont technology.

What is the harm of using html custom elements which was created in the page itself?

Is there any harm if custom tags are used and created based on one's choice?
like the one below
<hello>hi there!</hello>
I tried using CSS
hello{
color:red;font-family:arial;
}
The above code works
I have used the above and also can add CSS. is there any harm of doing this, or the CSS features these won't support?
This is purely out of curiosity so don't suggest CSS edits or solutions please.
Why you can't make up elements
It is not valid HTML. Therefore how it behaves will be unpredictable.
It may work in some browsers, currently, but if any of your users visit your site on a different browser, they may get a totally different experience. Further to that, support could be dropped, or change at any time without warning.
Other options for custom elements
It is actually possible to define your own Document Type Definition (DTD), however that too is not a good idea.
Your best bet is to either stick with normal, well-supported HTML elements (see here for list of valid elements), or to use a web component framework, such as Vue, Angular or React, for custom elements/ components.
Don't forget, that you can add the class attribute (as well as others) to any element for styling, so for your use-case, there isn't any need to have additional elements.

Should I manually register custom knockout elements to the DOM?

In knockout we can create custom elements that can look something like this:
<flight-deals params='from: "lhr", to: "sfo"'></flight-deals>
The definition of custom elements in HTML is still work in progress and a part of the process of using this today is to register the custom element to the DOM using document.registerElement.
However, I can not find anything in the knockout documentation regarding these aspects, and when I investigate if my custom elements are registered to the DOM by knockout after calling ko.components.register, they turn out not to be.
So if I'm using custom elements in knockout, should I also make sure to also register these manually using document.registerElement? The fact that knockout does not already do this makes me a little confused.
You don't need to do anything special for modern browsers and IE9+.
For IE6 - IE8 support you do need to be aware of this and use a wee bit of magic. As the relevant documentation mentions:
HTML5-era browsers, which includes Internet Explorer 9 and later, automatically allow for custom elements with no difficulties.
Internet Explorer 6 to 8 also supports custom elements, but only if they are registered before the HTML parser encounters any of those elements.
IE 6-8’s HTML parser will discard any unrecognized elements. To ensure it doesn’t throw out your custom elements, you must do one of the following:
Ensure you call ko.components.register('your-component') before the HTML parser sees any <your-component> elements
Or, at least call document.createElement('your-component') before the HTML parser sees any <your-component> elements. You can ignore the result of the createElement call — all that matters is that you have called it.

What are the reasons NOT to use custom HTML tags?

Given current HTML5 specs that allows creating custom HTML elements (as long as their name contains a dash), and the fact that Web Components seem to be a feature that's here to stay, I'd like to know why is creating your own custom HTML elements frowned upon?
Note, that I'm not asking whether to use Web Components - which are still a moving target, and even with great polyfills like Polymer might not be ready for production yet. I'm asking about creating your own custom HTML tags and styling them, without attaching any JS APIs to them.
Short answer: I haven't heard any very compelling reasons to avoid them.
However, here are some recurring arguments I've heard made:
Doesn't work in old IE (just document.createElement("my-tag"); should fix that).
Global namespace clashes (same applies to class names, and custom elements in general).
CSS selector performance (doh, this is just about the last thing you should worry about).
Separation of functionality, meaning and presentation. This is actually the only argument I've heard that IMHO has any valid basis to it. You're of course better off with semantic HTML (search engines and all that), but if you were going to use a div for it otherwise, I don't see why you couldn't use a custom tag instead.
One of the arguments against custom tags is their implied incompatibility with screen readers. This issue can be resolved with WAI-ARIA attributes.
There exists an issue in IE11, which breaks table layout if a custom element without display property is inserted inside a table cell. Check the plunker code. Therefore, it's the safest to declare all new elements explicitly, for example like so:
new-element {
display: block;
}

What issues need to be considered when using HTML5shiv?

I am thinking about starting to use some HTML5 elements in my sites. With the varying lack of support for HTML5 in Internet Explorer I was considering using HTML5shiv. I have read that I would need to set the CSS for various unrecognised elements to be block level and also the possibility of issues with loading HTML5 elements via ajax.
I would like to know what issues others have encountered when using this script. Thanks.
If you're going to dynamically load HTML5 elements you'll need the innershiv. You'll also need to bear in mind that if the IE user has JavaScript disabled, it won't work at all.
I've found the existing solution to be highly unreliable when used in real world scenarios - it's fine for noddy little "hello world" examples but as soon as the pages start getting more complex then you will find that styles will stop applying on some requests etc.
It's not a very nice answer, but the truth is that if you need to support older IE versions then you basically can't rely on being able to style HTML5 elements reliably. If you can get away with using the elements but use superflous markup (divs etc.) to do things like layout then you might get away with it, but then it depends what you consider to be the lesser of the two evils : Loads of noddy markup or no IE support.