Honeycomb

Honeycomb 17.0 migration guide

Package upgrade

Upgrading with npm

Run the following script to install the latest honeycomb version:

npm update @flixbus/honeycomb@latest --save

While this is not a requirement, we recommend you to install the latest icons and illustrations packages as well, if you use them.

Upgrading from CDN

If Honeycomb is served to your application via our CDN, you'll need to update the url providing the proper version part, like so:

<link rel="stylesheet" href="https://honeycomb.flixbus.com/dist/17.1.0/css/honeycomb.min.css">

Same applies to any partials you fetch from our CDN, e.g. if you need the honeycomb fonts this will be:

<link rel="stylesheet" href="https://honeycomb.flixbus.com/dist/17.1.0/css/honeycomb-fonts.min.css">

Quick migration checklist

For a fast and safe migration, do these in order:

  1. Replace old grid classes (flix-grid*, flix-col*, flix-push*) with the new CSS Grid API or temporarily switch to flix-legacy-grid* classes.
  2. Update language switcher markup from flix-language-switcher-popup to popup-only flix-language-switcher.
  3. Replace removed button-group modifiers (--half-gap, --1-gap) with --gap-half and --gap-1.
  4. Remove usage of flix-header-user-widget and flix-language-switcher__toggle.
  5. Remove pager modifiers --content-fit, --prev, --next, and render icon content explicitly in pager items.
  6. Ensure all fieldsets include flix-fieldset__items around the items.
  7. Replace flix-data-table__header-btn with flix-btn flix-btn--link flix-btn--square flix-btn--sm flix-data-table__sorter-btn.
  8. If you import SCSS internals, migrate from grid-* to legacy-grid-* mixins/variables and update import paths.
  9. Replace spacing-13 to spacing-16 token names.

Search and replace cheatsheet

Use these CSS class names replacements as a starting point (always review manually):

FindReplace
flix-language-switcher-popupflix-language-switcher
flix-btn-group--half-gapflix-btn-group--gap-half
flix-btn-group--1-gapflix-btn-group--gap-1
flix-grid-containerflix-legacy-grid-container (temporary)
flix-col-flix-legacy-col- (temporary)
flix-push-flix-legacy-push- (temporary)
flix-gridflix-legacy-grid (temporary)
flix-data-table__header-btnflix-btn flix-btn--link flix-btn--square flix-btn--sm flix-data-table__sorter-btn
spacing-13spacing-16

Recommended replacement order:

  1. Replace more specific selectors first (flix-grid-container, flix-col-, flix-push-).
  2. Replace flix-grid last to avoid accidental double replacements.

After replacing, run UI regression tests focused on:

  1. Header area, including navigation, user and language switcher widgets.
  2. Grid layouts at all breakpoints.
  3. Pager controls and keyboard accessibility.
  4. Data tables sorter buttons.

Breaking changes

flix-grid now uses CSS Grid (with a flix-legacy-grid fallback)

The flix-grid component was refactored from flexbox to CSS Grid.

If your layout heavily depends on old flex behavior (especially push classes and wrapping behavior) and you need a temporary bridge, you can use the legacy grid classes while you migrate.

This fallback is intended as a short-term migration aid, not a long-term target.

Before (old grid classes):

<div class="flix-grid flix-grid--gutter-4">
  <div class="flix-col-6 flix-push-3">A</div>
  <div class="flix-col-3">B</div>
</div>

Now (temporary legacy fallback):

<div class="flix-legacy-grid flix-legacy-grid--gutter-4">
  <div class="flix-legacy-col-6 flix-legacy-push-3">A</div>
  <div class="flix-legacy-col-3">B</div>
</div>

Otherwise we strongly recommend you to check the new documentation and dedicate time to migrate to the new Grid.

Moreover, if you are using the old grid component to intentionally create a flexbox container, considering using the Group component instead.

SCSS grid-* mixins and variables renamed to legacy-grid-*

If you consume Honeycomb SCSS utilities directly, rename grid mixins and variables to legacy-grid-*. If you only consume compiled CSS, you can skip this section.

Also note that legacy grid utilities now live in:

  • scss/common/utils/_legacy-grid.scss

The old file scss/common/utils/_grid.scss was removed.

Before:

@use '@flixbus/honeycomb/dist/scss/common/utils/grid' as *;

.my-custom-grid {
  @include grid-container();
}

Now:

@use '@flixbus/honeycomb/dist/scss/common/utils/legacy-grid' as *;

.my-custom-grid {
  @include legacy-grid-container();
}

flix-language-switcher-popup renamed to flix-language-switcher and flix-language-switcher__toggle removed

The component markup has been updated to simplify implementation. The component is a popup-only and the internal language switcher toggle is no longer provided.

You must create your own button to trigger the language switcher popup (or control the popup externally however you please).

When using popup.js, the plugin handles dialog behavior plus toggling hidden and the popup --active modifier for animation states.

Before:

<div class="flix-language-switcher">
  <button type="button" class="flix-language-switcher__toggle" data-popup="migration-17-old-language-switcher">
    <img class="flix-language-switcher__flag" src="https://honeycomb-assets.hive.flixbus.com/honeycomb-flags-static/2.0.3/svg/gb.svg" alt="United Kingdom" />
    English
    <span class="flix-sr-only">Open language selection</span>
  </button>
</div>
<div id="migration-17-old-language-switcher" class="flix-language-switcher-popup" aria-label="Language selection" hidden>
  <div class="flix-language-switcher-popup__body">
    <button type="button" aria-label="Close language selection" class="flix-language-switcher-popup__close flix-btn flix-btn--square flix-btn--md flix-btn--link"></button>
    <section class="flix-language-switcher-popup__region">
      <ul class="flix-language-switcher-popup__list">
        <li class="flix-language-switcher-popup__item">
          <a href="#" class="flix-language-switcher-popup__link" lang="bs">
            <img class="flix-language-switcher__flag" width="24" height="24" src="https://honeycomb-assets.hive.flixbus.com/honeycomb-flags-static/2.0.3/svg/ba.svg" alt="Bosna i Hercegovina">
            Bosanski
          </a>
        </li>
      </ul>
    </section>
  </div>
</div>

Now:

<!-- The toggle button belongs to you now and you can put it wherever you want in the page. Yes, even as a dropdown item. -->
<button
  type="button"
  class="flix-btn flix-btn--link"
  data-popup="migration-17-new-language-switcher-popup"
>
  <img class="flix-language-switcher__flag" src="https://honeycomb-assets.hive.flixbus.com/honeycomb-flags-static/2.0.3/svg/gb.svg" alt="United Kingdom" />
  English
  <span class="flix-sr-only">Open language selection</span>
</button>

<!-- The `flix-language-switcher` is now THE popup. The __popup class is removed and the child element classes were adjusted accordingly. -->
<div
  class="flix-language-switcher"
  id="migration-17-new-language-switcher-popup"
  aria-label="Language selection"
  role="dialog"
  aria-modal="true"
  hidden
>
  <div class="flix-language-switcher__body">
    <button type="button" class="flix-language-switcher__close flix-btn flix-btn--square flix-btn--md flix-btn--link" aria-label="Close language selection"></button>
    <section class="flix-language-switcher__region flix-language-switcher__region--columns">
      <ul class="flix-language-switcher__list">
        <li class="flix-language-switcher__item">
          <a href="#" class="flix-language-switcher__link" lang="bs">
            <img class="flix-language-switcher__flag" width="24" height="24" src="https://honeycomb-assets.hive.flixbus.com/honeycomb-flags-static/2.0.3/svg/ba.svg" alt="Bosna i Hercegovina">
            Bosanski
          </a>
        </li>
      </ul>
    </section>
  </div>
  <div class="flix-overlay"></div>
</div>

flix-btn-group--align-center and --align-end no longer apply justify-content

These modifiers now control alignment only. If you relied on previous behavior, add explicit justify modifiers.

Before:

<div class="flix-btn-group flix-btn-group--align-center">
  <button class="flix-btn">A</button>
  <button class="flix-btn">B</button>
</div>

Now:

<div class="flix-btn-group flix-btn-group--align-center flix-btn-group--justify-center">
  <button class="flix-btn">A</button>
  <button class="flix-btn">B</button>
</div>

Header navigation redesign can affect custom header integrations

Header navigation was redesigned to better accommodate controls in the widgets area.

If you have custom CSS overrides targeting header internals, review and adjust them after upgrading.

There is no single class rename to apply here; this is a visual/layout validation step.

Recommended checks:

  1. Header widgets alignment across breakpoints.
  2. Navigation spacing and wrapping in your app.
  3. Any custom selectors targeting old header internals.

Color token values adjusted

The following token values changed in v17:

  • warning-dark-color (light + dark modes)
  • danger-dark-color (dark mode)
  • ui-primary-dark-color (Neptune theme)

No token names were changed, but visual output can differ. Please review critical UI states (warning, danger, and Neptune primary-dark usage) and update reference screenshots if needed.

Default icon size in square buttons and inputs changed to spacing-3

Default icon size for square buttons and icons within inputs was increased to spacing-3.

If you hard-coded icon sizes within square buttons and inputs, please remove the hard-coded value to allow the components to control the size of their icons.

If you did not hard-code icon sizes inside these components, you should note their sizes adjusted and that's intended, update your reference screenshots if needed.

spacing-13 renamed to spacing-16

This token was wrongfully added as spacing-13 on version 16.6.0 and now has been renamed to spacing-16 correctly represent its value.

It is unlikely that you use this token, but if you do, simply rename it.

Before:

var(--flix-spacing-13) // css
cssvar(spacing-13) // scss

Now:

var(--flix-spacing-16) // css
cssvar(spacing-16) // scss

Removed in v17

flix-btn-group--half-gap and flix-btn-group--1-gap removed

These were deprecated in v16.3.0 and are now removed.

Before:

<div class="flix-btn-group flix-btn-group--half-gap">
  <button class="flix-btn">A</button>
  <button class="flix-btn">B</button>
</div>

Now:

<div class="flix-btn-group flix-btn-group--gap-half">
  <button class="flix-btn">A</button>
  <button class="flix-btn">B</button>
</div>

flix-header-user-widget removed

The prebuilt widget component is no longer provided.

Build your own widget from base components (flix-btn, flix-dropdown, etc.).

Before:

<div class="flix-header__widgets">
  <nav aria-label="John Doe" class="flix-header-user-widget">
    <a href="#" class="flix-avatar">
      <img class="flix-avatar__image" src="/img/avatar-placeholder.png" alt="Picture of John Doe" />
    </a>
    <button type="button" aria-label="Open user menu" class="flix-header-user-widget__toggle" data-dropdown="migration-17-old-user-widget" data-event="hover">
      John Doe
    </button>
    <ul id="migration-17-old-user-widget" class="flix-header-nav-subnav flix-header-nav-subnav--left" hidden>
      <li class="flix-header-nav-subnav__item">
        <a class="flix-header-nav-subnav__link" href="/">
          <span class="flix-header-nav-subnav__text">Profile</span>
        </a>
      </li>
    </ul>
  </nav>
</div>

Now:

<div class="flix-header__widgets">
  <nav aria-label="John Doe user menu">
    <div class="flix-dropdown flix-dropdown--left">
      <button
        type="button"
        aria-label="Open dropdown menu"
        class="flix-btn flix-btn--link flix-arrow-down-toggle"
        data-dropdown="migration-17-new-user-widget-menu"
        data-event="click"
      >
        <span class="flix-avatar">
          <img class="flix-avatar__image" src="/img/avatar-placeholder.png" alt="Picture of John Doe" />
        </span>
        John Doe
      </button>
      <div id="migration-17-new-user-widget-menu" class="flix-dropdown__items-container">
        <ul  class="flix-dropdown__items">
          <li class="flix-dropdown__item">
            <a class="flix-dropdown__link" href="#" ><flix-icon name="profile"  aria-hidden="true"></flix-icon> Profile</a>
          </li>
        </ul>
      </div>
    </div>
  </nav>
</div>

flix-language-switcher__toggle removed

Check the language switcher popup breaking changes entry for details.

Pager --content-fit, --prev, and --next modifiers removed

These were deprecated in v16 and are now removed.

  • Content-fit behavior is now default.
  • Use icon content instead of --prev/--next modifiers.

Before:

<nav class="flix-pager flix-pager--content-fit" aria-label="Pagination">
  <ul class="flix-pager__list">
    <li class="flix-pager__item">
      <a href="#" class="flix-pager__link flix-pager__link--prev">
        <span class="flix-sr-only">Previous page</span>
      </a>
    </li>
    <li class="flix-pager__item">
      <a href="#" class="flix-pager__link flix-pager__link--next">
        <span class="flix-sr-only">Next page</span>
      </a>
    </li>
  </ul>
</nav>

Now:

<nav class="flix-pager" aria-label="Pagination">
  <ul class="flix-pager__list">
    <li class="flix-pager__item">
      <button type="button" class="flix-pager__link flix-pager__link--disabled" disabled>
        <!-- 👇 Choose your favorite UI icon. But we recommend you stick to the traditional arrows. -->
        <flix-icon color="primary" name="arrow-left" title="Back"></flix-icon>
      </button>
    </li>
    <li class="flix-pager__item">
      <button type="button" class="flix-pager__link">
        <flix-icon color="primary" name="arrow-right" title="Next"></flix-icon>
      </button>
    </li>
  </ul>
</nav>

Fieldset markup without flix-fieldset__items is no longer supported

Support for legacy fieldset structure (items directly under flix-fieldset) was removed.

Before:

<fieldset class="flix-fieldset" role="radiogroup">
  <legend class="flix-legend">Options</legend>
  <div class="flix-fieldset__item">Radio A</div>
  <div class="flix-fieldset__item">Radio B</div>
</fieldset>

Now:

<fieldset class="flix-fieldset" role="radiogroup">
  <legend class="flix-legend">Options</legend>
  <!-- 👇 __items is required now -->
  <div class="flix-fieldset__items">
    <div class="flix-fieldset__item">Radio A</div>
    <div class="flix-fieldset__item">Radio B</div>
  </div>
</fieldset>

flix-data-table__header-btn removed for sorter actions

The old modifier simply provided a lot of duplicated styles from the button, so it was replaced with a smaller set of rules that are only needed for fine alignment adjustments. The rest of the button styles should come from the button component, this is the exact set of modifiers:

  • flix-btn flix-btn--link flix-btn--square flix-btn--sm flix-data-table__sorter-btn

Before:

<button class="flix-data-table__header-btn" type="button" aria-label="Sort rows A-Z">
  <flix-icon aria-hidden="true" class="flix-btn__icon" name="arrow-big-down"></flix-icon>
</button>

Now:

<button class="flix-btn flix-btn--link flix-btn--square flix-btn--sm flix-data-table__sorter-btn" type="button" aria-label="Sort rows A-Z">
  <flix-icon aria-hidden="true" class="flix-btn__icon" name="arrow-big-down"></flix-icon>
</button>