← Back to context

Comment by spartanatreyu

11 hours ago

> My point is that defining a complex behavior for a custom tag is not possible without js.

Not necessarily. CSS alone can allow for a lot of useful complex behaviour. You can customise how something renders (or not) or is interactable based on parent elements, sibling elements, css variables, or other state.

> For example, you can't define a reusable 'host-element' tag and expect some additional elements (or some behavior) to automatically appear inside it each time your html includes or you create <host-element> ... </host-element>.

Actually you can, using <template> and <slot> elements. No JS required.

> What's the point of using selector 'link-button[size="large"] a {...}' when you could do the same with '.link-button.large a {...}'?

This is really two questions:

1. What's the point of using <link-button> instead of a link-button class?

2. What's the point of using a size="large" attribute instead of a "large" class?

To answer 1:

Classes end up being misused compared to custom elements. When you make a custom element (in this example "<link-button>"), you're explicitly saying this is a <link-button>. It is not a <blockquote class="link-button">, it is not a <form class="link-button> and it is most certainly not a <picture class="link-button>. It is a <link-button>.

Also with what was stated above, you can use <link-button> to declare default internal elements (using <template> and <slot>) without using js to say what should be inside a link-button.

To answer 2:

Because you should make impossible states impossible (or at the very least present impossible states as impossible). Size is a state, it could be small, large or any other list of predefined values. If you use classes then you can end up with something like <link-element class="small large">. If you use attributes, you end up with something like <link-button size="small"> or <link-button size="large"> but not <link-button size="small" size="large"> (since that's illegal in html and duplicated attributes are ignored).

Plus you're already using attributes for interactive aria roles (or you should be).

So with a basic collapsible menu:

<nav role="navigation">

<a href="#">home</a>

<button id="navbar-toggle" aria-expanded="false" aria-controls="navbar-menu">Menu</button>

<ul id="navbar-menu">

  <li><a href="#">Login/Logout</a></li>

  <li><a href="#">Feedback</a></li>

  <li><a href="#">Other links...</a></li>

 </ul>

</nav>

You use css to style the menu being open or not with: `#navbar-toggle[aria-expanded=true] ~ #navbar-menu` and not something inaccessible like: `.navbar-menu.navbar-menu-open`.