docs/Bootstrap5Migration.md
This document outlines the step-by-step process for migrating Compiler Explorer from Bootstrap 4 to Bootstrap 5.3.5. The migration will be completed incrementally to allow for testing between steps.
We'll break down the migration into smaller, testable chunks rather than making all changes at once. This approach allows for:
Progress tracking will be maintained in this document.
bootstrap-utils.ts as a compatibility layerdata-bs-toggle instead of data-toggleThese insights were gathered during the migration process and may be helpful for future reference:
data-bs-* prefix..close class with a × entity inside a
span, while Bootstrap 5 uses .btn-close class with a background image and no inner content..popover() and .dropdown('toggle') need to be replaced with
code that uses the Bootstrap 5 API through a compatibility layer. Always use BootstrapUtils helper methods rather
than direct jQuery plugin calls..form-row to .row.
This can cause subtle template selector issues in code that relies on these class names.data-bs-toggle="modal" on the trigger element unless you also add a
matching data-bs-target attribute pointing to a valid modal element.Modal
type from bootstrap and use Modal.Event type..on() method. Replace $(selector).on('shown.bs.modal', handler) with
domElement.addEventListener('shown.bs.modal', handler). This is particularly important for modal events like '
shown.bs.modal'.window.bootstrap.Tooltip reference no longer exists. Import the Tooltip class
directly from bootstrap instead..input-group-prepend and
.input-group-append wrapper divs. Buttons and other controls can now be direct children of the .input-group
container. This simplifies the markup but requires template updates..btn-block class. Instead, the recommended approach is to wrap
buttons in a container with .d-grid and use standard .btn classes. This affects any full-width buttons in the
application.BootstrapUtils methods rather than jQuery objects, as this provides more consistent behavior..btn-close).dropdown-menu-end).list-group-flush).btn-block with .d-grid approach)filter: invert(100%) to make btn-close buttons visible in dark themes).custom-select to .form-select in theme files)data-bs-toggle="tab").on('shown.bs.modal') to native DOM addEventListener('shown.bs.modal')).form-row
which changed to .row in Bootstrap 5)dropdown('toggle') in
main.ts with BootstrapUtils.getDropdownInstance() and .toggle()).custom-runtimetool) and overrides selection (.custom-override) -
removed as they were superfluous.form-row still used in theme files (dark-theme.scss, one-dark-theme.scss, pink-theme.scss) - replaced with
standard .rowborder-inline-start and
border radius logical properties with appropriate fallbacks for older browsers.input-group-prepend and .input-group-append
have already been updated to use Bootstrap 5's simplified approach.btn-close consistently for toast
componentsbootstrap-utils.ts compatibility layerinert attributez-index can't fix it. Needs a rethink of how this is done.This section provides documentation for the custom Bootstrap component implementations developed during the migration.
The bootstrap-utils.ts file serves as a temporary compatibility layer between jQuery-based Bootstrap 4 code and the new Bootstrap 5 JavaScript API. It provides methods for initializing and controlling various Bootstrap components.
Methods:
showModal(selector): Displays a modal using a CSS selector or jQuery objecthideModal(selector): Hides a modal using a CSS selector or jQuery objectsetModalHiddenHandler(selector, handler): Sets a handler for the 'hidden.bs.modal' eventsetModalShownHandler(selector, handler): Sets a handler for the 'shown.bs.modal' eventgetModalInstance(selector): Gets the Bootstrap Modal instance for a given elementKey Changes from Bootstrap 4:
bootstrap.Modal.getInstance() or new bootstrap.Modal().modal('show') is replaced with modalInstance.show()Methods:
getDropdownInstance(selector): Gets the Bootstrap Dropdown instance for a given elementinitializeAllDropdowns(): Initializes all dropdowns on the pageKey Changes from Bootstrap 4:
.dropdown('toggle') is replaced with dropdownInstance.toggle()data-toggle="dropdown" to data-bs-toggle="dropdown"Methods:
createTooltip(element, options): Creates a tooltip instance on an elementinitializeAllTooltips(selector, options): Initializes all tooltips matching a selectorKey Changes from Bootstrap 4:
new bootstrap.Tooltip()$.fn.tooltip to direct import from bootstrapdata-toggle="tooltip" to data-bs-toggle="tooltip"Methods:
createPopover(element, options): Creates a popover instance on an elementinitializeAllPopovers(selector, options): Initializes all popovers matching a selectorKey Changes from Bootstrap 4:
new bootstrap.Popover()data-toggle="popover" to data-bs-toggle="popover"Methods:
activateTab(selector): Activates a specific tabKey Changes from Bootstrap 4:
$(selector).tab('show') to tabInstance.show()data-toggle="tab" to data-bs-toggle="tab"Methods:
createToast(element, options): Creates a toast instance on an elementshowToast(selector): Shows a toast using a CSS selector or jQuery objectKey Changes from Bootstrap 4:
new bootstrap.Toast()Key Changes:
.on(), .off(), etc.) should be replaced with native DOM methodsbs prefix (e.g., shown.bs.modal)Several Bootstrap CSS classes were renamed in version 5:
ml-* → ms-*, mr-* → me-*, etc.float-left → float-start, float-right → float-endtext-left → text-start, text-right → text-endcustom-select → form-select, form-row → row.close → .btn-close (with completely different HTML structure).dropdown-menu-right → .dropdown-menu-end.btn-block → Container with .d-gridTomSelect Integration:
Modal Focus Management:
inert attribute is now supported for better accessibilityThe following Bootstrap 4 features were deprecated or removed in Bootstrap 5:
.modal('show') no longer exist$.fn.modal or similar.form-row replaced by standard .row.btn-block removed in favor of .d-grid.close replaced by .btn-close with different HTML structureBefore considering the Bootstrap 5 migration complete, a comprehensive UI testing checklist was created and used to verify functionality. This checklist has been completed with all tests passing. The tests cover all major UI components that could be affected by the Bootstrap migration.
The checklist included:
A permanent version of this UI testing checklist has been created as a separate document and can be used for testing future UI changes or upgrades: UI Testing Checklist