MIGRATE-BS5.md
humhub\modules\content\widgets\WallCreateContentForm: replace renderActiveForm(\humhub\modules\ui\form\widgets\ActiveForm $form) with renderActiveForm(\humhub\widgets\form\ActiveForm $form)humhub\widgets\ActiveForm use humhub\widgets\form\ActiveForm insteadhumhub\modules\content\widgets\WallEntryLabels use humhub\modules\content\widgets\WallEntryBadges insteadhumhub\modules\ui\view\bootstrap\ThemeLoader use humhub\components\bootstrap\ThemeLoader insteadhumhub\modules\ui\view\components\ThemeVariables use humhub\components\ThemeVariables insteadhumhub\modules\ui\view\components\ThemeViews use humhub\components\ThemeViews insteadhumhub\modules\ui\view\components\ViewMeta use humhub\components\ViewMeta insteadjs/humhub/legacy/jquery.loader.jshumhub\helpers\ScssHelperWidgets in these new folders:
humhub\widgets\bootstraphumhub\widgets\formhumhub\widgets\modalAnd especially:
humhub\widgets\bootstrap\Badge (see https://getbootstrap.com/docs/5.3/components/badge/)humhub\widgets\bootstrap\Alert (see https://getbootstrap.com/docs/5.3/components/alerts/)humhub\widgets\bootstrap\Button::accent() (same for Badge and Label)humhub\widgets\bootstrap\Button::secondary() (same for Badge and Label)humhub\widgets\bootstrap\Button::light() (same for Badge and Label)humhub\widgets\bootstrap\Button::dark() (same for Badge and Label)humhub\widgets\bootstrap\Button::cssBgColor() (same for Badge and Label)humhub\widgets\bootstrap\Button::cssTextColor() (same for Badge and Label)humhub\widgets\bootstrap\Button::outline()humhub\widgets\bootstrap\Button::asBadge()humhub\widgets\bootstrap\Button::loading('Custom loading message')Colors: accent, secondary, light and dark are the new Bootstrap theme colors (default is deprecated).
The new accent color replaces the old info usage.
CSS Class: .filter-toggle-link for "Filter" toggle link
Bootstrap 3 components are removed from Bootstrap 5, but those used in HumHub are still supported for a while via the static/scss/_bootstrap3.scss compatibility stylesheet
Widgets & helpers:
humhub\widgets\BootstrapComponenthumhub\widgets\Tabs use humhub\widgets\bootstrap\Tabs insteadhumhub\widgets\Button use humhub\widgets\bootstrap\Button insteadhumhub\widgets\LinkPager use humhub\widgets\bootstrap\LinkPager insteadhumhub\widgets\Link use humhub\widgets\bootstrap\Link insteadhumhub\widgets\Label use humhub\widgets\bootstrap\Badge instead (watch out for class name changes!)humhub\modules\topic\widgets\TopicLabel use humhub\modules\topic\widgets\TopicBadge instead (watch out for class name changes!)humhub\libs\Html use humhub\helpers\Html insteadhumhub\modules\ui\view\components\View use humhub\components\View insteadhumhub\modules\ui\view\helpers\ThemeHelper use humhub\helpers\ThemeHelper insteadWidget methods & properties:
humhub\widgets\bootstrap\Button::xs() & humhub\widgets\bootstrap\Badge::xs() use ::sm() insteadhumhub\widgets\bootstrap\Button::defaultType() & humhub\widgets\bootstrap\Badge::defaultType() use ::light() or ::secondary() insteadhumhub\widgets\bootstrap\Button::htmlOptions & humhub\widgets\bootstrap\Badge::htmlOptions use ::options insteadhumhub\widgets\bootstrap\Button::color() & humhub\widgets\bootstrap\Badge::color() use ::instance($text, $color) instead for a Bootstrap color, or ::cssBgColor() for a custom color (Hexadecimal, RGB, RGBA, HSL, HSLA) (same for Badge)humhub\widgets\bootstrap\Button::textColor() & humhub\widgets\bootstrap\Badge::textColor() use ::cssTextColor() insteadName spaces starting with yii\bootstrap\: use yii\bootstrap5\ instead (but see "HumHub widgets" below)
Forms and Modal Dialog: see below.
SCSS and CSS variables: see below.
If available, use HumHub widgets instead of the native library widgets. This will make it easier to migrate to new versions of the external libraries (see Code Style wiki page).
E.g.:
yii\bootstrap5\Html, use humhub\helpers\Html instead.yii\bootstrap5\Button, use humhub\widgets\bootstrap\Button instead.yii\bootstrap5\Alert, use humhub\widgets\bootstrap\Alert instead (check the class documentation for the new recommended syntax).yii\bootstrap5\Badge, use humhub\widgets\bootstrap\Badge instead.yii\bootstrap5\Tabs, use humhub\widgets\bootstrap\Tabs instead.yii\bootstrap5\Modal, use humhub\widgets\modal\Modal insteadyii\bootstrap5\ActiveForm, use humhub\widgets\form\ActiveForm instead.yii\bootstrap5\ActiveField, use humhub\widgets\form\ActiveField instead.If a Bootstrap widget is not available, create an issue on https://github.com/humhub/humhub/issues).
humhub\widgets\modal\ModalButton::outline() (doc)humhub\widgets\ModalDialog use humhub\widgets\modal\Modal instead, which is different, as it's for the full Modal box, not just the dialog part of ithumhub\widgets\ModalButton use humhub\widgets\modal\ModalButton insteadhumhub\widgets\modal\ModalButton::submitModal($url, $label) use humhub\widgets\modal\ModalButton::save($label)->submit($url) insteadhumhub\widgets\ModalClose use humhub\widgets\modal\ModalClose insteadhumhub\widgets\GlobalModal use humhub\widgets\modal\GlobalModal insteadhumhub\widgets\GlobalConfirmModal use humhub\widgets\modal\GlobalConfirmModal insteadhumhub\widgets\Modal use humhub\widgets\modal\JsModal insteadhumhub\widgets\ModalDialog::begin() use humhub\widgets\modal\Modal::beginDialog() instead (see changes in the "Modal Dialog" chapter below)humhub\widgets\ModalDialog::end() use humhub\widgets\modal\Modal::endDialog() insteadhumhub\widgets\modal\Modal::header & humhub\widgets\modal\JsModal::header: use title instead (search for 'header' =>)humhub\widgets\modal\Modal::animation & humhub\widgets\modal\JsModal::animation (all modal boxes are opened with the fade animation) (search for 'animation' =>)humhub\widgets\modal\Modal::centerText & humhub\widgets\modal\JsModal::centerText (search for 'centerText' =>)humhub\widgets\modal\Modal::showClose: use closeButton instead (but works differently, see yii\bootstrap5\Modal::closeButton doc) (search for 'showClose' =>)humhub\widgets\modal\JsModal::size & humhub\widgets\modal\Modal::size values: use Modal::SIZE_DEFAULT, Modal::SIZE_SMALL, Modal::SIZE_LARGE, Modal::SIZE_EXTRA_LARGE instead of (normal, extra-small, small, medium, and large) (search for 'size' =>)data-backdrop => data-bs-backdropdata-keyboard => data-bs-keyboardModal::beginDialog() (formerly ModalDialog::begin()) now includes <div class="modal-body"> and the footer must be defined as a parameter, similar to the header which has been renamed to title.
Before:
<?php ModalDialog::begin([
'header' => Yii::t('ModuleIdModule.base', 'Title'),
]) ?>
<div class="modal-body">
Content
</div>
<div class="modal-footer">
<?= ModalButton::cancel(Yii::t('base', 'Close')) ?>
</div>
<?php ModalDialog::end() ?>
Now:
<?php Modal::beginDialog([
'title' => Yii::t('ModuleIdModule.base', 'Title'),
'footer' => ModalButton::cancel(Yii::t('base', 'Close')),
]) ?>
Content
<?php Modal::endDialog() ?>
Or:
<?= Modal::widget([
'title' => Yii::t('ModuleIdModule.base', 'Title'),
'body' => 'Content',
'footer' => ModalButton::cancel(Yii::t('base', 'Close')),
]); ?>
If the footer contains a "Submit" button, the modal dialog must be included in the form by using the Modal::beginFormDialog() and Modal::endFormDialog() methods:
<?php $form = Modal::beginFormDialog([
'title' => Yii::t('ModuleIdModule.base', 'Title'),
'footer' => ModalButton::cancel() . ' ' . ModalButton::save()->submit(),
'form' => [], // configuration for the form (optional)
]) ?>
Content and the form inputs for $form
<?php Modal::endFormDialog()?>
Search also for <div class="modal-dialog in the code to find modal dialogs not using the Modal::beginDialog() method.
Modals have three other optional sizes, see https://getbootstrap.com/docs/5.3/components/modal/#optional-sizes
Use 'size' => Modal::SIZE_LARGE, in the Modal::beginFormDialog() param array to change the size (or SIZE_EXTRA_LARGE, but SIZE_SMALL is not recommended).
Affirmative buttons (i.e., CTA buttons that perform an action) should always be placed on the right side, whereas dismissive buttons should be placed on the left.
E.g., "Close" should be on the left, and "Save" should be on the right.
Affirmative Buttons (Action-Taking):
Dismissive Buttons (Non-Action, Exit, or Revert):
When it is not possible to place the buttons in the modal footer param, use the modal-body-footer class:
<?php $form = Modal::beginDialog() ?>
Content
<div class="modal-body-footer">
<?= ModalButton::cancel(Yii::t('base', 'Close')) ?>
<?= ModalButton::save()->submit() ?>
</div>
<?php Modal::endDialog()?>
humhub\modules\ui\form\widgets\ColorPicker and humhub\widgets\ColorPickerField input widget: use ->colorInput() instead (see documentation)yii\widgets\ActiveForm, yii\bootstrap\ActiveForm, yii\bootstrap5\ActiveForm, kartik\widgets\ActiveForm, kartik\form\ActiveForm, humhub\modules\ui\form\widgets\ActiveForm: use humhub\widgets\form\ActiveForm insteadyii\widgets\ActiveField, yii\bootstrap\ActiveField, yii\bootstrap5\ActiveField, humhub\modules\ui\form\widgets\ActiveField: use humhub\widgets\form\ActiveField insteadhumhub\modules\ui\form\widgets\SortOrderField use humhub\widgets\form\SortOrderField insteadhumhub\modules\ui\form\widgets\ContentHiddenCheckbox use humhub\widgets\form\ContentHiddenCheckbox insteadhumhub\modules\ui\form\widgets\ContentVisibilitySelect use humhub\widgets\form\ContentVisibilitySelect insteadhumhub\modules\ui\form\widgets\FormTabs use humhub\widgets\bootstrap\FormTabs insteadkartik\widgets\ColorInput use ->colorInput() instead (see documentation)Remove <span class="input-group-btn"> button wrapper inside <div class="input-group">.
Before:
<div class="input-group">
<span class="input-group-btn">
<button class="btn btn-default">My action</button>
</span>
</div>
Now:
<div class="input-group">
<button class="btn btn-light">My action</button>
</div>
dropdown-menu in the code and add a dropdown-header class to header items, and a dropdown-item class to all link items (usually a and button tags ; see documentation with example).divider classes (search regex expression for HTML tags: <\w+\s+[^>]*class\s*=\s*["'](?:[^"']*\s)?divider(?:\s[^"']*)?["'][^>]*>), replace with dropdown-divider, and move them to a hr child tag of li.dropdown-header class to a child tag of li (usually in a h6 tag)dropdown-menu-left -> dropdown-menu-startdropdown-menu-right -> dropdown-menu-enddropdown-menu float-start (or pull-left) -> dropdown-menu dropdown-menu-startdropdown-menu float-end (or pull-right) -> dropdown-menu dropdown-menu-end<span class="caret"></span> and <b class="caret"></b> in dropdown buttons (as there are already added by Bootstrap 5 via the :after pseudo-element)Before:
<li class="dropdown">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
Dropdown button
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><h6>Dropdown header</h6></li>
<li role="separator" class="divider"></li>
<li><a href="#">Action</a></li>
</ul>
</li>
Now:
<div class="dropdown">
<button type="button" class="btn btn-secondary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
Dropdown button
</button>
<ul class="dropdown-menu">
<li><h6 class="dropdown-header">Dropdown header</h6></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#">Action</a></li>
</ul>
</li>
To remove the right caret, add the dropdown-toggle-no-caret class to the button: dropdown-toggle dropdown-toggle-no-caret.
The jQuery .dropdown() method is removed. Use BS5 vanilla JS API instead. Example for a close button:
$('#hideDropdownButton').on('click', function () {
const $dropdown = $('#my-dropdown'); // which has the `dropdown` class
const bsDropdown = new bootstrap.Dropdown(dropdownElement); // Bootstrap's API
bsDropdown.hide(); // https://getbootstrap.com/docs/5.3/components/dropdowns/#methods
});
Make sure the required classes nav-item and nav-link exist in HTML tags about nav & tabs (see documentation with examples).
Search regex expression for HTML tags: <\w+\s+[^>]*class\s*=\s*["'](?:[^"']*\s)?nav(?:\s[^"']*)?["'][^>]*>.
The active class must be added to the nav-link element (and not the nav-item).
Example:
<ul class="nav">
<li class="nav-item">
<a class="nav-link active" href="#">Link</a>
</li>
...
</ul>
So in CSS, li.active a must be replaced by li a.active.
Example:
<ul class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false">Dropdown</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><hr class="dropdown-divider"></li>
</ul>
</li>
</ul>
If you cannot use the humhub\widgets\bootstrap\Button widget, remove space between the icon and the label, because a right margin has been added to the icon.
Before:
<button type="button" class="btn-primary btn"><?= Icon::get('circle') ?> Label</button>
Now:
<button type="button" class="btn-primary btn"><?= Icon::get('circle') ?>Label</button>
By default, links are black.
To emphasize a link, use the link-accent class.
Search for the class breadcrumb.
Search for "Show more" or toggle buttons and use Bootstrap 5 collapse component instead.
These replacements must be done in PHP, SCSS (formerly LESS) and JS files.
img-responsive -> img-fluid (use the humhub\modules\ui\widgets\BaseImage widget when possible)alert-default -> alert-light or alert-secondary (use the humhub\widgets\bootstrap\Alert widget when possible)btn-xs -> btn-sm (use the humhub\widgets\bootstrap\Button widget when possible)btn-default -> btn-light (the new btn-secondary can also be used, but it will be a darker gray)pull-left (or style="float:left") -> float-startpull-right (or style="float:right") -> float-endcenter-block -> mx-auto (image, inline or inline-block elements: d-block mx-auto)btn-block -> d-grid gap-2text-left -> text-starttext-right -> text-endbtn-group-xs -> btn-group-smmedia-object img-rounded -> roundedimg-rounded -> roundeddata-toggle -> data-bs-toggledata-original-title -> data-bs-titledata-target -> data-bs-targetdata-dismiss -> data-bs-dismissno-space -> m-0 p-0align-center -> text-center or d-flex justify-content-centerinput-group-addon -> input-group-text (or input-group-prepend or input-group-append)form-group -> mb-3well (search regex expression for HTML tags: <\w+\s+[^>]*class\s*=\s*["'](?:[^"']*\s)?well(?:\s[^"']*)?["'][^>]*>) -> bg-light p-3 for a simple inset container or card (with a card-body child element)has-error, has-warning, and has-success -> is-invalid or is-valid, but the new classes are now appended to the input instead of the previous form-group (the input is a child of the form group)help-block help-block-error -> invalid-feedbackhelp-block -> text-body-secondary or form-text if in a formjumbotron classBootstrap 3:
xs: < 768pxsm: ≥ 768pxmd: ≥ 992pxlg: ≥ 1200pxBootstrap 5:
xs: removed (default when not specified)sm: ≥ 576px (new)md: ≥ 768pxlg: ≥ 992pxxl: ≥ 1200pxxxl: ≥ 1400px (new)So replacements are (to be done in this order):
col-lg- -> col-xl-col-md- -> col-lg-col-sm- -> col-md-col-xs- -> col- Make sure:
row classcontainer classUse the new d-none class instead of the display: none; style (except for email views).
In the following class replacements, you can also use inline, flex, etc. instead of block (depending on the desired display mode).
E.g., d-sm-inline or d-sm-flex instead of d-sm-block (see all available)
In Bootstrap 3, the class applies only to the defined screen size, while in Bootstrap 5, the class applies to the defined screen size and larger sizes.
And visible will hide the element for other screen sizes, while in Bootstrap 5, you need to add d-none to hide for other screen sizes.
Remplacement examples (must be adapted to the specific situation):
hidden-xs -> d-none d-sm-block or d-none d-sm-inline or d-none d-sm-flex (depending on the desired display mode)hidden-sm (hide on small screens only) → d-sm-none d-md-block (hide on small screens, but show on medium or above ; idem, replace block with inline or flex)hidden-md (hide on medium screens only) → d-md-none d-lg-block (hide on medium screens, but show on large or above)hidden-lg (hide on large screens) → d-lg-none (hide on large screens and above, including extra large screens which doesn't exist in Bootstrap 3)hidden (search regex expression for HTML tags: <\w+\s+[^>]*class\s*=\s*["'](?:[^"']*\s)?hidden(?:\s[^"']*)?["'][^>]*> ; search also in JS for strings such as Class('hidden'), Class("hidden"), Class' => 'hidden') -> d-none and othersvisible-xs (hide on small screens and above) → d-block d-sm-none or d-sm-none if the element is visible by defaultvisible-sm (visible on small screens only) → d-none d-sm-block d-md-none (hide on all screens except small screens)visible-xs visible-sm -> d-md-none (hide on large screens of above)visible-md → d-none d-md-block d-lg-none (show on medium screens only)visible-lg → d-none d-lg-block (show on large screens or above)visible-md visible-lg -> d-none d-md-block (show on medium screens of above)visible (search regex expression for HTML tags: <\w+\s+[^>]*class\s*=\s*["'](?:[^"']*\s)?visible(?:\s[^"']*)?["'][^>]*> ; search also in JS for strings such as Class('visible'), Class("visible") and Class' => 'visible') → d-blockd-noneIn Bootstrap 5 CSS, the d-flex class is set to flex !important, and the d-none class to display: none !important;.
So, the jQuery hide() and show() functions won't work anymore, because of the !important.
Replacements to do on these elements:
.hide() -> .addClass('d-none').show() -> .removeClass('d-none').toggle() -> .toggleClass('d-none').fadeIn() -> .removeClass('d-none').fadeOut() -> .addClass('d-none').fadeToggle() -> .toggleClass('d-none').slideDown() -> .removeClass('d-none').slideUp() -> .addClass('d-none').slideToggle() -> .toggleClass('d-none')Search for sk-.
Before:
<div class="sk-spinner sk-spinner-three-bounce">
<div class="sk-bounce1"></div>
<div class="sk-bounce2"></div>
<div class="sk-bounce3"></div>
</div>
After, for a button:
<span class="spinner-border spinner-border-sm"></span>
After, in a container:
<div class="text-center">
<div class="spinner-border" role="status">
<span class="visually-hidden"><?= Yii::t('base', 'Loading...') ?></span>
</div>
</div>
If wrapped in an HTML element having loader (search for the <\w+\s+[^>]*class\s*=\s*["'](?:[^"']*\s)?loader(?:\s[^"']*)?["'][^>]*> regex expression) or humhub-ui-loader classes, replace the hole HTML code with the LoaderWidget widget.
See documentation for more options and examples.
The tt class is deprecated.
Use the data-bs-toggle="tooltip" data-bs-title="My tooltip text" instead.
Doc: https://getbootstrap.com/docs/5.3/components/tooltips/
When using Button, Link, Badge or Icon widgets, use the ->tooltip('My tooltip text') method.
In a future HumHub version, panels will be replaced with cards.
Currently, you should continue using them (a compatibility layer is provided for BS3 panels).
Search for all label classes (label label- and the regex expression <\w+\s+[^>]*class\s*=\s*["'](?:[^"']*\s)?label(?:\s[^"']*)?["'][^>]*>) and use the new humhub\widgets\bootstrap\Badge widget instead
Use the humhub\widgets\bootstrap\Badge widget when possible.
Replacements:
badge-default -> text-bg-light or text-bg-secondarybadge-primary -> text-bg-primarybadge-danger -> text-bg-dangerbadge-warning -> text-bg-warningbadge-info -> text-bg-accentbadge-success -> text-bg-successDoc: https://getbootstrap.com/docs/5.3/components/badge/
media-list and remove the HTML element, or, to keep a similar style, use the class hh-list and replace the ul tag with a div. E.g. <ul class="media-list"> -> <div class="hh-list">li tags with div or a tags. E.g. <li class="media"> -> <div class="d-flex">media classes (search regex expression for HTML tags: <\w+\s+[^>]*class\s*=\s*["'](?:[^"']*\s)?media(?:\s[^"']*)?["'][^>]*>) and replace with d-flex.media in CSS files and replace with d-fleximg-space classes and surround the UserImage and SpaceImage with the img-profile-space (see example in protected/humhub/modules/content/widgets/views/wallEntry.php)media-heading -> mt-0 (removes the top margin, keeping it close to the top of the content area) ; the related HTML tag can be replaced with h5 or h4media-body -> flex-grow-1media-left -> flex-shrink-0 me-2media-right -> flex-shrink-0 ms-2 order-lastmedia-object -> flex-shrink-0 (if on an image, encapsulate the image in a div tag with flex-shrink-0 class)float-start (or pull-left) class for images inside a <div class="flex-shrink-0">Doc: https://getbootstrap.com/docs/5.3/utilities/flex/#media-object
The .clearfix class works differently in Bootstrap 5.
Now, the clear: both; is done with a :after pseudo-element.
Before:
<div>
<div class="pull-right">...</div>
<div class="clearfix"></div>
</div>
After:
<div class="clearfix">
<div class="float-end">...</div>
</div>
Dropped the Glyphicons icon font (source).
Use Font Awesome instead.
Search for glyphicon in the code and replace with Font Awesome, by using the \humhub\modules\ui\icon\widgets\Icon widget.
LESS format is not supported anymore. Use SCSS instead.
Doc: https://getbootstrap.com/docs/5.3/customize/sass/
Rename less folder to scss and rename all .less files to .scss
Prefix all SCSS files with _ except the build.scss and variables.scss files.
E.g.: less/theme.less -> scss/_theme.scss
Linux command: for file in *.less; do mv "$file" "_${file%.less}.scss"; done and remove the _ for the build.scss file
You can use the following tool to convert LESS to SCSS: https://less2scss.awk5.com/ An AI might be more powerful to convert, but still requires manual checks (use a DIFF tool).
Check the output manually, mainly functions and syntaxes such as:
color: fade(@color, 20%); -> tint-color($color, 80%);color: lighten(@color, 20%); -> tint-color($color, 20%);color: darken(@color, 20%); -> shade-color($color, 20%);transition:: remove the @include added after the conversionGrunt compiler has been removed.
The CSS is automatically generated by the new compiler in the assets folder, each time the cache is flushed, or the theme is changed.
Update Gruntfile.js and package.json to use the new SaaS compiler:
Gruntfile.js: replace less with saas section, and update loadNpmTasks and registerTaskpackage.json: remove grunt-contrib-less package and add grunt-sass and saasTake the Wiki module as an example: https://github.com/humhub/wiki/tree/bs5
Deprecated SCSS variables:
$default: use $light instead$info: use $accent instead$link: use $primary instead (or $link-color if it's about a link but not a a HTML tag)$text-color-contrast use $text-color-accent-contrast, $text-color-primary-contrast, etc. insteadNew SCSS variables:
$accent$secondary$light$dark$text-color-accent-contrast, $text-color-primary-contrast, etc. (one for each Bootstrap color)Use the new variables starting with --bs- for Bootstrap variables, and --hh- for HumHub variables.
E.g.: color: $primary -> color: var(--bs-primary)
Full deprecation list in static/scss/_root.scss.
In modules or custom themes, if you need new variables, prefix them with --hh-xx- where xx are the first letters of your module or theme ID. E.g. my-module will use hh-mm-.
CSS variables allow changing the value dynamically on the browser side without having to refresh the page, e.g. to switch to High contrast or Dark mode.
Replace all SCSS variables with CSS variables when available. You can use regex:
\$([a-zA-Z0-9-_]+)var(--bs-$1) (mainly for base colors such as $primary) or var(--hh-$1)For color variation, check if a CSS variable already exists. If not, create a new CSS variable (see "Custom colors" section below).
Root variables (see doc) are global variables that can be used in any component.
They are stored in this file: static/scss/__root.scss
Component variables only apply to the HTML elements having the related class (e.g. .badge for Badge CSS variables), and HTML elements inside of it.
Their values can be overwritten in the component-related SCSS file (e.g. _badge.scss). Example:
.badge {
--bs-badge-padding-x: 0.8em;
}
Doc: https://getbootstrap.com/docs/5.3/customize/color/
Availability:
$primary)--bs-primary).bg-primary)CSS color variations:
--bs-primary-bg-subtle--bs-primary-border-subtle--bs-primary-text-emphasisExample for alerts: https://getbootstrap.com/docs/5.3/components/alerts/#variables
Availability:
--bs-alert-bg, etc.alert-primary, etcIn components:
.alertCSS classes:
.link-{$color}: https://getbootstrap.com/docs/5.3/helpers/colored-links.text-bg-{$color}: https://getbootstrap.com/docs/5.3/helpers/color-background/CSS variables for contrast colors:
--hh-accent-contrast--hh-primary-contrast--hh-secondary-contrast--hh-info-contrast--hh-success-contrast--hh-warning-contrast--hh-danger-contrast--hh-light-contrast--hh-dark-contrastExample of CSS if it's not possible tu use the .text-bg-{$color} class:
#target {
background-color: var(--bs-primary);
color: var(--hh-primary-contrast);
}
--bs) : https://getbootstrap.com/docs/5.3/customize/css-variables/--bs-componentName) : See component page (e.g. https://getbootstrap.com/docs/5.3/components/alerts/#variables)--hh) : static/scss/_root.scss--hh-componentName) : See component SCSS file in static/scssIf a color is not available for your module or theme:
tint-color() and shade-color() functions (which uses Saasmix()) instead of lighten() and darken() (See https://codepen.io/emdeoh/pen/zYOQOPB)Example for "My Module" (-hh-mm prefix):
:root { // Or, if possible, a component such as button (see example in _buttons.scss), alert, etc.
--hh-mm-custom-color: shade-color($some-color, $percentage);
}
Search for @media and replace with SCSS functions:
// X-Small devices (portrait phones and up)
// No media query necessary for xs breakpoint as it's effectively `@media (min-width: 0) { ... }`
// Small devices (landscape phones and up)
@include media-breakpoint-up(sm) { ... } // @media (min-width: 576px) { ... }
// Medium devices (tablets and up)
@include media-breakpoint-up(md) { ... } // @media (min-width: 768px) { ... }
// Large devices (desktops and up)
@include media-breakpoint-up(lg) { ... } // @media (min-width: 992px) { ... }
// X-Large devices (large desktops and up)
@include media-breakpoint-up(xl) { ... } // @media (min-width: 1200px) { ... }
// XX-Large devices (larger desktops)
@include media-breakpoint-up(xxl) { ... } // @media (min-width: 1400px) { ... }
It is also possible to use max-width (should be occasionally used) using media-breakpoint-down. E.g.:
// `sm` applies to x-small devices (portrait phones and down)
@include media-breakpoint-down(sm) { ... } // @media (max-width: 575.98px) { ... }
// `md` applies to small devices (landscape phones and down)
@include media-breakpoint-down(md) { ... } // @media (max-width: 767.98px) { ... }
// etc...
Doc: https://getbootstrap.com/docs/5.3/layout/breakpoints
Depending on your needs, you might have to import the Boostrap SCSS functions, variables, mixins or breakpoints:
@import "/opt/humhub/protected/vendor/twbs/bootstrap/scss/functions";
@import "/opt/humhub/protected/vendor/twbs/bootstrap/scss/variables";
@import "/opt/humhub/protected/vendor/twbs/bootstrap/scss/mixins";
@import "/opt/humhub/protected/vendor/twbs/bootstrap/scss/mixins/breakpoints";
Make sure you have a symbolic link of HumHub root directory in /opt/humhub:
sudo ln -s /path/to/humhub /opt/humhub
Search for the regex expression (color|background|border)(Default|Primary|Info|Success|Warning|Danger)|(colorLink)|(colorFont[1-5])
And replace with the BS5 equivalent.
E.g.:
backgroundSuccess -> bg-successcolorInfo -> text-infostatic/css/select2Theme folder has been removed, and the SCSS file moved and renamed to static/scss/_select2.scss
Many styles have been refactored. Please review all your overwritten CSS selectors and values.
All theme folders must be moved to a new resources folder, except the scss and views folders.
Structure example:
There is no css folder anymore.
In the variables.scss, all variables must have the !default flag to allow being overwritten by a child-theme.
The build.scss file mustn't import the parent theme files anymore, as it is automatically done by the new compiler.
Most of the views have been refactored to use the new Bootstrap 5 HTML tags and classes.
Please review all overwritten view files. See Migration: Identify Template Changes wiki for more information.
The most important change concerns the protected/humhub/views/layouts/main.php file, which has been refactored with bs5 flex logic (instead of floating right elements).
Search in all files for this regex expression:
(humhub\\widgets\\(Tabs|Button|Link|Label)|humhub\\libs\\Html|humhub\\modules\\ui\\view\\components\\View|humhub\\modules\\ui\\view\\helpers\\ThemeHelper|humhub\\widgets\\Modal|yii\\widgets\\Active(Form|Field)|humhub\\modules\\ui\\form\\widgets\\Active(Form|Field)|humhub\\modules\\ui\\form\\widgets\\FormTabs|yii\\bootstrap\\|xs\(|-xs|defaultType\(|btn-default|class="divider"|pull-(left|right)|form-group|help-block)
It doesn't search for all migration changes, but it will find most of the important ones.