Use of containerless


What is best/worse practice of using containerless in view model or in view?
When to use containerless and when not to use containerless?

All this question I have in my mind after conversation I have with @boban.r


I’ve used it in SVG where HTML components are not valid. It’s also useful if you want off the shelf CSS to work without modification.


Not an authoritative answer, but to share my experience.

As Aurelia document said, @containerless does fight shadowdom which will be part of html standard, plus other quirks, use it sparingly.

We use @containerless to avoid creating intermediate dom wrapper <my-comp> that destroys inner element styles or position, right? How could we avoid using it as much as possible.

Replace @containerless with as-element

  1. in almost every use cases, you can avoid using @containerless by using
    <ul as-element="my-comp">.
  2. you may ask what about dynamic composition <compose view-model="./my-comp">,
    can I avoid intermediate <compose> tag?
    • well, @containerless cannot fix this, but as-element can.
    • use <ul as-element="compose" view-model="./my-comp">. :scream: :scream: :scream:

You have to use @containerless for svg partial, as-element doesn’t work

Just read Aurelia document. This is limited by browser’s native html parser (which Aurelia uses to parse every html template file), you need a <svg> tag wrap in your svg partial template to teach browser parser you are writing svg, not html. (technically, svg is xml, not html)

But you might be perfectionist

You cannot stand the possibility that fellow developers might misuse your component directly as <my-comp>, then ends up blaming you the broken style/layout. How to ensure the usage of as-element?

Now you can shout back: “Read your console log, dumb ass!”.

import {inject} from 'aurelia-framework';

export class MyComp {
  constructor(element) {
    if (element.tagName === 'MY-COMP') {
      throw new Error("cannot use <my-comp>. use <other-tag as-element=\"my-comp\">.");
    if (element.tagName === 'COMPOSE') {
      throw new Error("cannot use <compose view-model=\"my-comp\">. use <other-tag as-element=\"compose\" view-model=\"my-comp\">.");
import {inject} from 'aurelia-framework';

export class MyTableRow {
  constructor(element) {
    if (element.tagName !== 'TR') {
      throw new Error("use <tr as-element=\"my-table-row\">.");


Just want to show one more off-topic tip, you can avoid intermediate <router-view> tag.

 <div class="row" as-element="router-view"></div>

Don’t be too surprised. compose and router-view are just custom elements, not much different from those you defined.


A good example of usage will be when you have list item as a component nested in list and you won’t break the style: ul > li { // CSS }



just out of curiosity :smile:, can we use as-element on <template> tag too?

<template as-element="my-custom-element">


I cannot test it right now :smile:


@huochunpeng <compose containerless></compose> works . I’m using it in a couple of places without issue.

This also works:
<router-view id="main-router" containerless></router-view>


Well this is black magic of semantic markup (-:


this qoute from docs makes total sense:

Note that when a containerless attribute is used, the container is stripped after the browser has loaded the DOM elements, and as such this method cannot be used to transform non-HTML compliant structures into compliant ones!

For example

<select name="" id="">
    <template repeat.for="">
        <option value=""></option>

does not work in ie


I really appreciate what all of you write. Until this moment everywhere I use as-element but I was curious what @containerless do.
While creating one CE and using in table I figure that you need to use as-element=“table-head” because only like this browser knows how to render your CE.

So to sum up if I can (please correct me if I’m wrong :smiley: )

  • use @containerless for SVG — removing custom element tag is happening after browser render all html
  • use as-element almost everywhere


I’d add : if you control markup - as-element is more compatible at the moment. with less styling needed.


Recently faced the need to use containerlesscustom elements. I just want to point out that if you want to use your custom element with all the glory of binding, but don’t want to have the wrapping DOM element, then containerless attribute is the best choice.

<my-element prop1.bind="value" containerless></my-element>

This makes specific instances of my-element container-less, without impacting all instances of my-element.