Skip to content

caboodle-tech/element-behaviors

Repository files navigation

Element Behaviors

Element Behaviors let you easily add reusable features (behaviors) to any HTML element with a simple has="" attribute. This provides a flexible and efficient alternative to custom elements.

The following information is a quick start guide to Element Behaviors. For more in-depth information and live examples please visit the interactive manual.

Usage

Element Behaviors allow you to enhance standard HTML elements with multiple functionalities without the need to define traditional custom elements. This makes it easier to add complex interactions and features to any element.

Example: Game Character

In this example, a div represents a human-controllable player in a game. The player is controlled by player two and is currently holding a sword:

<div has="player two" position="30 30 30" left-hand="" right-hand="sword"></div>

Example: Loader

Element Behaviors can also respond to the lifecycle events of HTML elements, allowing for dynamic and flexible enhancements. In this example, a div functions as a loader. The loader attribute customizes its appearance, and the visible attribute toggles its visibility:

<div has="loader" loader="wave" visible="true">
    Text shown when loader is set to `text`.
</div>

With Element Behaviors, you can seamlessly integrate advanced functionalities into your web components, providing a powerful alternative to custom elements. View live examples in the interactive manual, including a live demo of the loader example above.

Installation

The Element Behaviors library should be added to your web pages in the <head> tag, preferably before all other scripts:

If you would like to use a CDN we are on jsDelivr at the following URLs:

<!-- For the latest release. -->
<script src="https://cdn.jsdelivr.net/gh/caboodle-tech/element-behaviors@main/dist/eb.min.js"></script>

<!-- For older releases that have been tagged. Replace [TAG] with the proper semver number. -->
<script src="https://cdn.jsdelivr.net/gh/caboodle-tech/element-behaviors@[TAG]/dist/eb.min.js"></script>

Contributing

Contributions are welcome! If you encounter any issues or have suggestions for improvements, please open an issue on GitHub.

Important

Please note that we use pnpm instead of npm as our package manager. Additionally, we follow the conventional commits format for all commit messages and pull requests.

If you would like to contribute code changes, you can do so by submitting a pull request. Pull request will not be accepted if they do not reference an open issue. Before submitting a pull request, make sure to follow all these steps:

  1. Fork the repository and create a new branch for your changes.
  2. Make your code changes and ensure that they adhere to the project's coding conventions enforced by the project's eslint config and conventional commit messages.
  3. Test your changes thoroughly to ensure they do not introduce any regressions. Refer to the testing instructions for more information on how to run the manual tests.
  4. Commit your changes and push them to your forked repository.
  5. Open a pull request on the main repository, including the issue number in the title, and provide a clear description of your changes.

Differences in Element Behaviors

Attaching behaviors to elements is not a new concept and libraries attempting to do this have been around for some time. This library is my opinionated take on what element behaviors should look like, for a longer explanation please see the Brief History section below.

This library was heavily inspired by Lume's Element Behaviors entity-component system, but includes functionality I felt was missing. In summary you can expect:

  • Responding to attribute changes with observedAttributes just like custom elements.
  • Responding to lifecycle callbacks just like custom elements.
  • Easily and efficiently retrieve elements that have attached behaviors.
  • Saving state between disconnection and reconnection to any^ document.
  • The option to save state between removal and restoring of a behavior to the same element.
  • Working^ inside shadow dom and iframes.

For more information visit the interactive manual for Element Behaviors.

^ Since this library is not native code there are some restrictions and trade offs to these points. Please see the manuals Limitations and Modified Behaviors section for more information.

Brief History

The idea of attaching behaviors to elements has been around for at least a decade and a half, but I personally give credit to Joe Pea for pioneering a working concept with Lume's Element Behaviors entity-component system.

This desire for elements with behaviors is entwined with the history of custom elements. To be brief, Caboodle Tech's element behavior library ultimately steamed from Safari/WebKit refusing to adopt customized built-ins and the is attribute. This meant there would be no true 100% cross browser implementation of custom elements. The slightly longer history, one including the desire for custom attributes as well, is covered in Lume's element-behaviors note section:

See this long issue on w3c's webcomponents repo, which led to the issue where the idea for element-behaviors was born, with some ideas from this other issue... [Element Behaviors also uses] custom-attributes (originally by @matthewp, forked in LUME) to implement the has="" attribute.

Brief aside here: Well I was initially annoyed by the Safari/WebKit decision, I came to realize that they made the right call. Custom elements were a step in the right direction, but the implementation was less than desireable. This decision is what paved the way for developers to get innovative and think outside the box, hence the creation of element behaviors, the best successor to and evolution of custom elements in my opinion.

As of September 2023 the Web Incubator Community Group (WICG) has started discussing a proposal for "custom attributes for all elements, [and] enhancements for more complex use cases". I am excited to see what comes from this proposal, but as the web standards history has taught me, I won't hold my breath for the 100% adoption of any of these features.

For the time being this implementation (Caboodle Tech's implementation) of element behaviors is exactly what custom elements should be in my mind: elements that not only support the dynamic adding or removing of behaviors and attributes across documents, but also maintain their state. This is why Caboodle Tech's element behaviors operates differently than Lume's.

~ Chris (May 2024)