12 ms·
HTML Web Components: An Example
- axilmar 3y agoWhy bother? the percentage of users that have JS disabled is what nowadays? 0.000000000001% maybe? even smaller?
- jsdeveloper 3y ago[flagged]
- chrismorgan 3y agoI don’t think this item is the place to share it: your thing embodies the approach the article is arguing against! Try posting it as a Show HN instead.
- Woshiwuja 3y agoi agree with the article, we dont need react to do things like this
- BurningPenguin 3y agoI'll never understand why JS decided to use backticks. It's so weird to type on German keyboard.
- pavlov 3y agoIt’s fundamentally a Unixism, like the tilde and some other characters used in C family languages that don’t exist on many European keyboards. If you look back 30-50 years, most of the popular programming languages like Pascal and BASIC used a very limited character set. Instead of symbols like various brackets and tilde and backtick, they used keywords. This was intentional because they were designed to be possible to type on various Latin keyboards. But Unix and C were developed by American hackers who had no reason not to use all the ASCII characters available on the Teletype-whatever connected to the PDP-whatever. And that’s the path we ended up on. In the 1980s the C standard committee tried to address this problem by adding support for trigraphs. There’s a whole set of three-character symbols (identified by a prefix of two question marks) that can be used in C code in place of curly brackets and all the rest of the exotic ASCII set. But I’ve never seen anyone use this, and I think trigraphs are scheduled for removal in C.
- Kiro 3y agoWith your reasoning we wouldn't be able to use any special characters considering every character has layouts where it's awkward to type.
- BurningPenguin 3y agoBackticks are used for certain letters in several European languages. à, ì, ù, ò. Depending on the editor, it's kinda annoying. Normal quotes or double quotes usually don't do that. Also, the key is right beside the backspace key, which feels kinda far away for my hands (which of course also depends on the keyboard).
- cantSpellSober 3y ago> Normal quotes or double quotes usually don't do that With backticks we don't need to worry about quotes in the content inside being interpreted as the end of a string in JS
- Dma54rhs 3y agoSwitch to the US layout for programming then. It's impossible to cater to all the languages in the world.
- yett 3y agoIsn't it on the right side of question mark? On my nordic keyboard it is and you just need to press shift and backtick key. I don't see how it's too difficult.
- BurningPenguin 3y agoYes. But to me it feels far away compared to the quotes. And depending on the editor, it may end up above a letter if you forget to press space. For example "à". It can be a bit annoying.
- scns 3y agoTry the Neo layout, optimized for writing german, english and programing. It places the most used letters and symbols under your strongest fingers. Absolutely worth the effort, QWERTX is a pain in comparison. https://neo-layout.org/ https://neo-layout.org/
- VPenkov 3y agoIt's the closest thing to a quote without being a quote. Enabling interpolation for old syntax would break old websites that display strings that aren't intended to be interpolated. If you're curious enough, I'm sure you can find the TC39 proposal.
- Zanfa 3y agoI'm from the EU, but once I switched to US-keyboard layouts everywhere, so many programming languages' syntactical choices suddenly made sense.
- Kiro 3y agoIf we're not doing any state manipulation and are just using static props I don't see why we even need any abstraction at all. I would really like to see an example where "setShowTooltip" is used and the equivalent is implemented in Web Components. That's the part React is solving for me.
- quickthrower2 3y agoBut that is just going to be the vanilla JS and React versions of the same thing. React doesn’t solve UI. It solves state management of UIs (IMO).
- untitaker_ 3y ago> If we're not doing any state manipulation and are just using static props I don't see why we even need any abstraction at all. People are using React outside of SPAs just because they're already used to it, and because it's got a rich ecosystem of reusable components. I don't know how to implement setShowTooltip in vanilla js and webcomponents. It is probably really ugly. But also, making your web components work with progressive enhancement does not necessarily mean you have to get rid of React. You can still use React to define a custom HTML element, and combine the state management of React with the progressive enhancement of web components.
- codethief 3y ago> This is nice enough. But the point is: it requires JavaScript (React, 3rd-party-tooltip-on-npm, your JS code) before anything will render in the browser. It’s an all-or-nothing approach. As was already pointed out in the previous discussion (of the previous blog post) here on HN, this is a complete non-issue. In most frameworks these days you would prerender your application or maybe even server-side render it. The issue I see with the suggested "solution" (of the non-issue) is that the "placeholder" <img> tag is not "type-safe". I can put anything in there without paying attention to what exactly my web component does or expects. If the behavior of my web component changes, I won't get a warning at code writing or compile time. Instead the layout will silently break. All in all, I don't think this approach scales well with the size of the code base and the number of people working on it. (Let's say, e.g., <user-avatar> is provided by some other team.) And again, it's trying to solve a non-issue.
- throwaway318 3y agoIf <user-avatar> starts to provide something else, and depends on compiling a code base to alert that it's breaking something, an automated test(?), then that suggests everyone's working blind and hoping for the best while the application development methodology's broken.
- codethief 3y agoHave you ever worked on (or with) a component library for a large code base? When updating the library you can't possibly manually check every single usage of every component. I mean, depending on the CSS, things might already break if the <img> suddenly needs to be wrapped inside a div etc.
- quickthrower2 3y agoI agree although prerender land has it’s issues. Mainly it is hard to make forms that work both with/without JS, especially with validation. You need separate code paths for both. At least in NextJS. The latest version is very close though. Sans validation and with experimental features I think you can have a server action that handles both form and JS submissions the same way.
- achairapart 3y agoThis is essentially what was called ~20 years ago "Progressive enhancement", and was lost togheter with "Graceful Degradation" when a new generation of "Front-End Engineers" started over-engineering the www around the 2010s. My impression is that some common sense was lost too along the way. Remember the Rule of the Least Power, anyone? Good Practice: Use the least powerful language suitable for expressing information, constraints or programs on the World Wide Web.[0] [0]: https://www.w3.org/2001/tag/doc/leastPower.html https://www.w3.org/2001/tag/doc/leastPower.html
- geek_at 3y agoThis is exactly why I love HTMX [1] in combination with PicoCSS[2]. HTMX is just the regular html elements with ajax extensions built into the tags (it is a js library currently but they plan on lobbying to have these as default functionalities with HTML in the future) and picoCSS also works without classes so you are "trained" to use the semantic tags for the page to be rendered beautifully [1] https://htmx.org/ https://htmx.org/ [2] https://picocss.com/ https://picocss.com/
- phero_cnstrcts 3y agoWhat I don’t like about htmx is that you have html spread over two very different places - front end and backend. On the backend side you might not even have syntax highlighting.
- politelemon 3y agoIt's not that common sense gets lost, I think what happens is the lessons keep getting forgotten as the new generation enter the fold, and reinvent old concepts ("everything old is new again"). As an industry we don't do a great job of persisting lessons learned. Not sure how we could, I've got no answers, just an observation of what happens.
- marcosdumay 3y agoIf you use the principle of least power to make fundamental architectural decisions, you'll get stuck, very soon and very often when the requirements change. People used to understand that too. But limited functionality frameworks became too enticing to ignore as a user (of the framework), and to sell as a developer. That lead the way into the stuff we have today, that are extendable limited functionality frameworks where the amount of functionality is so large that one hopes never to exceed it.
- sirwhinesalot 3y agoI quite like this approach but I wish the web component spec had been better to begin with, I shouldn't have to "feed in" the internal divs to the web component (which wrecks encapsulation), HTML templates should be possible to name and instantiate from within HTML, allowing for proper encapsulation, while having the javascript be entirely optional and allow for progressive enhancement. I ramble about this on my blog if anyone cares: https://btmc.substack.com/p/making-sense-of-web-components https://btmc.substack.com/p/making-sense-of-web-components I've wanted to make a simple compiler (I'm talking a single python script level of complexity here) which takes a set of .html files with named templates inside (HTML+CSS+JS sane web components), encapsulates the CSS and the JS, then goes through the various actual .html page files and replaces each instance of the template <my-component></my-component> with a "HTML Web Component" as described in Jim Nielsen's article. Alas, I lack the time, feel free to steal my idea.
- jadbox 3y agoFwiw I love this idea for a simple js-free component compiler/bundler.
- pphysch 3y agoDjango has something similar, on top of its template support https://docs.djangoproject.com/en/4.2/topics/forms/media/ https://docs.djangoproject.com/en/4.2/topics/forms/media/
- seabass-labrax 3y agoWhat you describe is provided by XSL and XHTML! These are both standard web technologies, albeit not particularly popular ones. This is how you define a template: <xsl:template match="put the xpath query for your components name here"> Anything inside that template will be expanded when you use your component's name in your XHTML file, either by the web browser or (more practically in an HTML5 world) by a server-side XSL processor. It's pretty fun :)
- deleted 3y ago[deleted]
- joshstrange 3y ago> If the user’s browser fails to download, parse, and run any JavaScript, nothing will display on screen. > So before any JavaScript has been downloaded, parsed, and run, a desktop browser could display something like If? Before? I’m sorry but that’s just not based in reality at all. These examples are so hopelessly contrived. Their fallbacks are rough and often ugly, require a ton more testing and development, and are not what users want. If your JS is slow to load or often fails loading then that’s what you should focus on. Not some half-working BS. Web _apps_ require JS. Pure and simple. Pretending that it’s worth the time to implement a fraction of your web app’s functionality for the case where JS doesn’t load is ludicrous. “Oh look you can use a title instead of a tooltip”, cool, now make some actually complicated work. If I had unlimited budget and unlimited QA time I still would think this was a stupid idea. Dealing with all these “graceful” (press X to doubt) fallbacks means double the QA time: once to test the happy path that users demand and once to test the absurd path that <1% of your uses will see or want. Anti-JS/noscript people don’t make any sense to me. Might as well reject CSS or h1 tags while you are arbitrarily drawing the line somewhere. Yes I know HN has a higher proportion of these people than the internet at large but it’s simply not worth the extra effort and testing. It’s like installing peddles in a car in case the engine goes out.
- sirwhinesalot 3y agoI still regularly see spinning dots of death or broken pseudo-progress-bars on top of pages that are little more than blogs and could very well be statically generated. Don't get me started on broken browser history, even youtube fails at that. Web _apps_ require JS, no doubt about it, the problem is that every website these days thinks it's a web app.
- joshstrange 3y agoFair, and in other comments on this subject I’ve complained that we don’t have good “language” for discussing things like blogs vs marketing sites vs JS-heavy sites vs actual web apps. More often than not people are taking past each other in the pro/anti-JS context with each person thinking of a different example. I completely agree that your blog probably doesn’t need to require JS and might even be worth some of these fallbacks if you do want to enhance it but a blog is tiny testing space compared to any “web app”. Also even if your user-facing aspect of the blog can handle noscript your backend admin/editor is going to require JS in most cases. Yes, yes, static site generators are great but let’s not kid ourselves and pretend they are suitable for most people. Hell, I used SSG for years before deciding I just wanted a web admin UI to edit/write in for my blog. And you can even pair the two together (JS-based admin that generates static frontend files for readers). Bottom line if any part of your website/app requires JS then it’s a waste of time to try implement fallbacks. At a previous company I dealt with this, the core of our business was a website that needed JS to function but I had one dev who constantly wanted to have fallbacks on our less JS-heavy pages. A user using noscript would not be able to do the most important things since there was literally no conceivable way to have a noscript fallback (show me the fallback for drawing polygons on a map without JS, I’ll eat my hat). Being able to create calendar items in our system might be possible without JS (with a terrible UX) but good luck with the UI to assign people to the calendar entry. It just wasn’t worth the effort and QA time to support both.
- _heimdall 3y agoIn my experience web components got a bad wrap because it was never really clear what exactly they are. Are they the shadow DOM? Custom elements? Yes! And no I very rarely use the shadow DOM APIs but really lean heavily into custom elements for simple lifecycle hooks. Similar to the example in this article, its really easy to server render the HTML and have a bit of JS hook on in the client. The main downside is that there's no support for delaying the component, the custom element will be created and connected immediately.
- blittle 3y agoAgreed, in my opinion the unnecessary emphasis on shadow dom is what prevented web components from gaining more adoption.
- rambambram 3y agoMaybe it's just the used example that irks me the wrong way a bit, but I do these things with pure CSS or even HTML. <img title='Jim Nielsen'/> anyone? For making apps on the web, I abide to the request/response cycle that's inherent to HTTP. JS is only for cropping images, picking colors and other necessary functionality that adds to the otherwise serverside monolith. Of course there are use cases where one needs a JS framework, but I think it would surprise a lot of devs to see what's possible with just HTML, CSS and a little bit of JS on the client side. Although that seems to require a big mindshift nowadays...
- trondeh80 3y agoI have angered so many frontend devs by touting this for years. It amazes me how common sense like this is instantly attacked and belitteled. Unless you create a user-interface UI in a webpage (a complicated frontend state), I think its way more reasonable to just use html/css with small sprinkles of js to open/close menues and modals. It loads fast, its less code so its easier to maintain. It does not require a complicated build step that instantly becomes deprecated once its deployed. Heck, its even greener, it requires less CPU power to build and render.
- rahkiin 3y agoI’ve found it is quite doable to have open/close menus purely with html and css these days using selectors! The text you click on is a label for a hidden checkbox. The checkbox you put adjacent to the item you’re hiding/showing. Then put css on it that uses input[type=checkbox]:checked and the tilde operator
- tonyedgecombe 3y agoI wonder why the HTML menu element was so half hearted. This is such a common requirement that it shouldn’t require hacks like that.
- qingcharles 3y agoAs CSS has developed over the last few years it is amazing how much you can now do on the front-end without JavaScript. I wish the browsers would enable their "behind-a-flag" support for masonry so many sites could then remove another chunk of JavaScript being used for layout.
- singularity2001 3y agoas mentioned earlier, It will be nice if/when these components can also be defined within HTML <template tag="user-avatar" parameters="[src,alt]"> <img src="{src}" alt="{alt}"/> </template
- coldacid 3y agoThere _is_ a <template> element[0] for this purpose, but so far it falls short on being able to inject parameters like that, and is essentially useless if you don't have Javascript.[1] [0]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template https://developer.mozilla.org/en-US/docs/Web/HTML/Element/te... [1]: https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_templates_and_slots https://developer.mozilla.org/en-US/docs/Web/API/Web_compone...
- marcosdumay 3y agoI got the impression that the people defining the web standards just gave-up on letting things work without javascript. If you don't want to import things like a frontend framework and HTMX parser, the templates are incredibly useful. They are also very useful for the backend to pass structure over to the frontend, as they are plain HTML. What they do not do is helping with the things that a static site generator will do.
- jeswin 3y agoI haven't used Web Components yet, but plan to. If you have worked with or evaluated vanilla Web Components and Lit[1], is there any reason to prefer one of the other? [1]: https://lit.dev/ https://lit.dev/
- hellcow 3y agoLit is a small lib that extends components to handle common needs, like state management, adding/removing event listeners, etc. As someone who wrote and maintained a lot of vanilla web components, I much prefer using lit nowadays. It’s still just native components… but many of the parts you needed to write yourself are already there and very well implemented.
- freddex 3y agoLit is very close to vanilla Web Components, but makes the standard more convenient to work with. Especially when used with TypeScript and a nice plugin such as lit-plugin [1], you get syntax highlighted and checked CSS + HTML, auto-completion in templates, and so on. Also, the reactivity offered by Lit is something you could implement yourself using the standard lifecycle methods of custom elements, but is quite boilerplate-y. Overall, Lit gives you a better developer experience with fewer foot guns and boilerplate without much overhead. [1]: https://marketplace.visualstudio.com/items?itemName=runem.lit-plugin https://marketplace.visualstudio.com/items?itemName=runem.li...
- alex_suzuki 3y agoI read the article and don’t understand the example. So every time I want to use the avatar component (let‘s say inside a navbar, in a profile page, in an article header etc.) , I‘d have to include the <img> tag. Because it’s basically a required „input template“ of the web component. And when the web component changes, I‘d have to go through all the places I use it and adapt the <img> tag to the new requirements of the web component…? that‘s… ridiculous?
- aatd86 3y agoAgreed. It's weird. If the goal is to extend HTML elements, should just send the compound elements definition with the html. The image should just be refered by a src attribute of user-avatar. But in any case, you still want javascript if you have to change something dynamically. People are hell-bent on using a static markup language designed for static documents even if it doesn't fit. Ok it's slow but that's another problem.
- simonw 3y agoRight. It's the difference between this: <user-avatar src="https://www.jim-nielsen.com/.well-known/avatar" alt="Profile photo of Jim Nielsen" width="32" height="32" title="Jim Nielsen" /> And this: <user-avatar> <img src="https://www.jim-nielsen.com/.well-known/avatar" alt="Profile photo of Jim Nielsen" width="32" height="32" title="Jim Nielsen" /> </user-avatar> I will argue that the extra <img> there is worth it for the benefits you get in terms not just of no/slow-loading JavaScript but also better semantics - code that process images in an HTML document will know what to do with the latter, it will be unable to handle the former.
- regularjack 3y agoWhat if next year you decide to change the img tag to an svg?
- riquito 3y agoYou have to go back to your codebase and edit every implementation of the component under the sun. <user-avatar> content is both a view and an interface, which is not obvious
- cantSpellSober 3y agoI think adding a bit (or a new article) about why someone should choose this approach for state mangaement over existing alternatives would make a stronger argument. Perhaps clarify the connectedCallback() and customElements.define() methods are not arbitrary, but specific to the API (I know the API is linked to in the article, but readers are lazy). (Better examples here than in the previous article, thank you!)
- bastawhiz 3y agoIt seems wild to me to write raw HTML and then write a layer of code that works with that specific, bespoke markup to enhance it. You lose the benefits of the code being modular! That's the whole point of it being a component! What you could do is have some code on the server that generates the markup. That way it's not so bespoke. And the client side code could somehow be aware of what the server is doing, so you're not writing a layer to enhance the code, you're just adding interactivity... ... Congrats! You've just invented server side rendering.
- rlnorthcutt 3y agoThis is a decent fallback, but it really doesn't solve the underlying problem. The whole point of web components is the ability to encapsulate and reuse your work... and _specifically_ to extend the HTML tag library. The fact that you need JS to load/run to parse your custom web component is an issue. But, the solution is to allow users to cache these components or add them to the browser itself. Ideally, <user-avatar> should be available without JS just like <img> is. Imagine a world where we have this capability - a large library of reusable components that can be used as easily as native HTML. This is the vision, is it not?
- wruza 3y agoIt only works for sites that don't really require a framework. What bugs me in most examples and "getting started" articles is that they take a trivial, best-implemented thing and present it as if it will be an average experience and/or a common modality. Yes, a card can be implemented with a trivial fallback. Now show a repo of an average site or an app with a decent requirements+development history without waving hands about "classes of web content" and "limited application". We are not time-traveling oracles. If the base platform doesn't work for an average in-the-wild use case, fix it until it works. Make rules for styling tooltips, add strict data model for controls, tables and requests, etc. Meanwhile, turn your js on.
- wirtsi 3y agoThe article really misses out the full power of Web Components <slots> ... that's how you would inject plain html tags into them
- karol 3y agoSolutions in search of a problem.
- wackget 3y agoThis entire article could have been replaced with two words: "graceful degradation." Sadly that concept is utterly foreign to today's "web developers" who have absolutely no idea of web development without JavaScript.
- micromacrofoot 3y agowait why not progressive enhancement?
- pphysch 3y agoBecause the vast majority of users have JS enabled, I suppose
- T3RMINATED 3y ago[dead]
- hollowturtle 3y agoMaybe it’s the contrived example but I’m not convinced. First I understand that if a user disable JavaScript then it has a functioning fallback, but can’t accept browser double rendering(first pass HTML, second JavaScript and with potential layout shift) and with the risk of breaking accessibility, one should take for granted that the tooltip library has proper accessibility integrated. Then one thing that I will never understand: why calling them web components and not just custom elements? And shouldn’t the purpose of custom elements be to avoid JavaScript as much as possible? I can’t see why they were spec’d in this way, what’s the purpose of custom HTML elements if I need to wait javascript to kick in? Give me the possibility to define custom elements in a declarative fashion directly inside HTML with the <template> tag and with styles scoped to that node. Eventually, if one wants, could add some JavaScript to further enhance the custom element. That way we could have expanded the web more and more. Edit: spelling corrections
- simonw 3y ago"one should take for granted that the tooltip library has proper accessibility integrated" Really? My experience to date has been that the majority of libraries for things like tooltips fail to take accessibility into account at all.
- hollowturtle 3y agoI agree, and imo users of those libraries fails as well
- naasking 3y ago> First I understand that if a user disable JavaScript then it has a functioning fallback That isn't the only case. They could be on an unreliable internet connection and the JS fails to load. They could be referencing unpkg and it's down or otherwise unreachable. There could have been a syntax or other error that escaped testing that causes the JS to fail to execute. The point is that there are many failure modes that may cause the JS-only approach to fail to display anything at all, where the progressively enhanced version is still usable.
- teg4n_ 3y agoI like to think of these kind of web components as analogous to jquery plugins from back in the day. IF I think of them like that instead of a react component things make more sense as to why this is useful.
- peebeebee 3y agoI used this technique in a project I'm working on extensively. This works great for server-side rendered projects, because you can just combine the HTML inside and the custom-tag in a partial, and re-use this partial like a default component. A nice advantage is also that it will auto-execute code when you include components in the DOM through the connectedCallback() function. No need to do manual stuff, or wait for onDOMContentLoaded. BUT when you go more advanced, like intra-component communication, or nested component structures, it starts to become a bit troublesome. Or you'll dream of some reactive templating or other advanced features, and you'll check out what LIT-components are doing... I feel that in most simple cases doing vanilla enhancements on some .js-something classes are is even easier that using this technique. No need for a custom-element. Just go back to the jQuery days. :)