Empty-column absorption stops working as soon as a column has an explicit responsive width, so a fixed-width main column leaves a gap when its sibling module position is empty
My environment: Helix Ultimate Framework 2.2.6, Joomla 6.1.1, PHP 8.4.17.
Helix already has a nice behaviour: in a layout row, when a column that holds a module position has no published modules, Helix drops that column and lets the remaining column take over the freed space, so the main/component column fills the full width. This works perfectly when the columns are left on Inherit for their grid widths.
The problem is that this absorption is silently disabled the moment I give a column an explicit responsive width. If I open the component column settings and set, for example, the Large Desktop grid to 9 (so the row is a 9 + 3 main/sidebar split), then on a page where the sidebar module position has no modules, the component column stays at col-lg-9 and leaves an empty 3-column gap on the right. It no longer expands to fill the space, even though the sidebar column has been removed. To get the expansion back I had to clear every responsive width on the component column (set Large, Tablet, Larger Phone and Phone all back to Inherit) and rely only on the base Column Width. So in practice I can either control the responsive widths of the main column, or have it auto-expand when the sidebar position is empty, but not both.
The cause is visible in plugins/system/helixultimate/src/Core/HelixUltimate.php, in get_current_row(). When a non-component column has no modules, Helix adds its grid size to an $inactive_col accumulator and removes the column:
if (!$column->settings->column_type) {
if (!$this->count_modules($column->settings->name)) {
$inactive_col += $column->settings->grid_size;
unset($row->attr[$key]);
}
}
Then the component column absorbs that freed width into $col_grid_size:
$col_grid_size = $options->grid_size;
...
if (!empty($options->column_type)) {
$col_grid_size += $inactive_col;
}
But when the CSS classes are built, the absorbed $col_grid_size is only used as the fallback when the responsive width is empty:
if (isset($options->lg_col) && $options->lg_col) {
$className = $className . ' col-lg-' . $options->lg_col;
} else {
$className = 'col-lg-' . $col_grid_size;
}
The xxl_col, xl_col, md_col, sm_col and xs_col classes are only added when their explicit value is set, and none of them ever use the absorbed $col_grid_size. So any explicit responsive width takes priority over the absorbed width at that breakpoint, and the column keeps its fixed size instead of expanding into the empty space.
To reproduce: build a layout row with a main/component column and a second column bound to a module position (for example the right sidebar). Leave the component column widths on Inherit, publish no modules in that position, and open a page using this layout: the component fills the full width. Now set an explicit Large Desktop width on the component column (for example 9), keep the position empty, and reload: the component stays at 9 columns and a 3-column gap appears on the right.
My humble request is to make the empty-column absorption also apply when responsive widths are set, so that the absorbed $inactive_col is added to the explicit lg_col/md_col/etc. as well, or alternatively to add a per-column option such as "expand to fill when the sibling module position is empty" that works together with explicit responsive widths. At the very least it would help to document that setting any explicit responsive grid width on a column disables the automatic expansion into an empty neighbouring position.
Thank you.