Skip to content

Container attributes

Container attributes are rendered on the <li> that wraps the menu link, not on the <a>.

An attribute is a container attribute when either:

  • its name starts with container_, or
  • it has container: true.

The container_ prefix is removed when rendering. container_class becomes class on the <li>.

attributes:
  container_class:
    label: 'Container class(es)'
  data-section:
    label: 'Section'
    container: true

With has-dropdown entered for Container class(es) and products for Section, the menu item is rendered like this (plus any classes the theme adds):

<li class="has-dropdown" data-section="products">
  <a href="/products">Products</a>
</li>

An attribute named container_* always needs to go on the <li>. With container: false it would be an <a> attribute with an underscore in its name, which is not allowed, so the field does not show up on the menu link form. The configuration form does not catch this yet, see #3590639.

Theme requirements

The module adds container attributes in hook_preprocess_menu() to each item's attributes object. The theme's menu.html.twig must print item.attributes on the <li>. Core and most contrib themes do:

<li{{ item.attributes.addClass(classes) }}>

If your template builds its own attribute object, merge item.attributes into it:

{% set li_attributes = create_attribute({'class': classes}).merge(item.attributes) %}
<li{{ li_attributes }}>

Menus rendered without the menu theme hook, such as custom blocks that loop over links in code, do not get container attributes.