-
-
Notifications
You must be signed in to change notification settings - Fork 70
Description
We have ad-hoc started the process of migrating to Bootstrap v5 from Bootstrap v3. Overall, I think updating to Bootstrap 5 is good, however, this mixing of dependencies has caused quite a few breaking changes on the site placing us in a bit of a triage mode.
Related open Issues and PRs:
- #581 Update brand download dropdowns to Bootstrap 5 namespaced attributes #583
- Brand page: download buttons don't work #581
- Fix Dropdown Arrow Direction for Latest New 2025 #580
- Inconsistent About Page & Footer Issue Between Development and Production #579
- Bug: “Latest New 2025” Dropdown Arrow Points Up When Closed #575
My suggestion to resolve is to quickly get PRs
merged to normalize dependencies and finalize the switch to Bootstrap 5. We can then migrate old Bootstrap 3 and sometime 4 references safely.
Here are the migration guidelines from:
Here are the big breaking changes
- Dropped jQuery.
- Upgraded from Popper v1.x to Popper v2.x.
- Replaced Libsass with Dart Sass as our Sass compiler given Libsass was deprecated.
Suggested Issues
- Inventory current Bootstrap usage and version conflicts
- Audit templates and partials to identify Bootstrap 3/4 classes, data attributes, and JS usage.
- Key Bootstrap 3/4 patterns currently in the theme:
- jQuery + Bootstrap bundle loaded together in head: head.html (jquery.slim.min.js, bootstrap.bundle.min.js concatenated), implying reliance on jQuery-based data-API.
- Navbar uses BS3/4 attributes and classes: navigation.html (data-toggle, data-target, .navbar-toggler, .navbar-collapse, .navbar-nav, .dropdown-menu), and uses ml-auto (BS4 spacing).
- Tabs use BS4 data-API: tabs.html (data-toggle="tab", .nav-tabs, .tab-pane, .fade, .show).
- Collapse/Accordion usage with BS3 data-API: script.js ($("#news .panel-collapse:first").collapse();) and gallery toggler uses jQuery events.
- Grid classes with BS3/4 naming: multiple layouts (e.g., allnews.html, index.html, team.html, list.html) use .col-lg-, .col-sm-, .row, .container; spacing utilities like .mt-5, .mb-4 (BS4 utility naming).
- Buttons use BS3/4 classes: theme.md demonstrates .btn, .btn-primary, .btn-outline-*, .btn-link, .btn-warning, etc.
- Legacy helpers visible: .pull-right in data.html and os.html; .navbar padding overrides in style.css.
- Dropdowns in brand download partial use .dropdown-menu, .dropdown-item, .dropdown-header: brandDownloadIconDropdownButton.html.
- Carousel uses BS3/4 classes: index.html (carousel, carousel-item, carousel-indicators).
- Form/tab JS initialization relies on jQuery .tab('show'): script.js download tab handler.
These locations indicate active BS3/4-era data attributes (data-toggle, data-target), jQuery plugin calls (.collapse(), .tab('show')), and class names (glyph-like .pull-right, ml-auto).
- Standardize Bootstrap 5 asset loading
- Replace concatenated vendor bundle using jQuery + legacy bootstrap.bundle.min.js with a single Bootstrap 5 bundle import.
- Remove jQuery dependency if not otherwise required.
- Migrate navigation components to Bootstrap 5
- Update .navbar-, .navbar-toggle, .navbar-default patterns to .navbar-expand-, .navbar-toggler, and BS5 data attributes.
- Check custom nav partials: navigation.html (and other layout files that embed it: e.g., list.html, index.html).
- Update grid and spacing utilities
- Replace deprecated .row-fluid, .col-xs-, .col-sm- patterns with BS5 grid classes; swap .offset-/.pull-/.push-* with offset-* and flex utilities.
- Ensure custom spacing classes in style.css don’t conflict with BS5.
- Migrate forms to Bootstrap 5
- Update .form-group, .form-control-static, .input-group-addon, .custom-* to BS5 equivalents.
- I search for them with
rg --no-heading -n "form-group|form-control|input-group|custom-" .
./themes/grass/assets/css/style.css:1081:.form-control {
./themes/grass/assets/css/style.css:1087:.form-control:focus {
./themes/grass/assets/css/style.css:1091:textarea.form-control {
./themes/grass/layouts/contribute/devel.html:42: <li><i class="fa fa-file-code"></i>  <a href="https://github.com/wenzeslaus/foss4g-2022-developing-custom-grass-tools" target="_blank">Write your own tools</a></li>
./content/about/theme.md:1141:<span class="custom-span">This is a custom span.</span>
./content/about/theme.md:1144:<span class="custom-span">This is a custom span.</span>- Ensure validation classes use .is-valid/.is-invalid.
- Update components: dropdowns, modals, tooltips, popovers, carousels
- Replace data-toggle/data-target with data-bs-toggle/data-bs-target.
rg -no-heading -n "data-toggle|data-target|custom-" .
./content/about/history.md:16:<h4 class="panel-title"><a role="button" data-toggle="collapse" data-parent="#accordion" href="#eighties" aria-expanded="true" aria-controls="eighties">The eighties</a></h4>
./content/about/history.md:51:<h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#nineties" aria-expanded="false" aria-controls="nineties">The nineties</a></h4>
./content/about/history.md:78: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#millennium" aria-expanded="false" aria-controls="millennium">The new millennium</a></h4>
./content/about/history.md:107: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#tens" aria-expanded="false" aria-controls="millennium">The 2010s and beyond</a></h4>
./content/about/theme.md:1141:<span class="custom-span">This is a custom span.</span>
./content/about/theme.md:1144:<span class="custom-span">This is a custom span.</span>
./content/about/history/web-evolution.md:16: <h4 class="panel-title"><a role="button" data-toggle="collapse" data-parent="#accordion" href="#1997" aria-expanded="true" aria-controls="1997">1997</a></h4>
./content/about/history/web-evolution.md:43: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#1998" aria-expanded="false" aria-controls="1998">1998</a></h4>
./content/about/history/web-evolution.md:69: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#1999" aria-expanded="false" aria-controls="1999">1999</a></h4>
./content/about/history/web-evolution.md:110: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#2000" aria-expanded="false" aria-controls="2000">2000</a></h4>
./content/about/history/web-evolution.md:152: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#2001" aria-expanded="false" aria-controls="2001">2001</a></h4>
./content/about/history/web-evolution.md:194: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#2002" aria-expanded="false" aria-controls="2002">2002</a></h4>
./content/about/history/web-evolution.md:236: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#2012" aria-expanded="false" aria-controls="2012">2012</a></h4>
./content/about/history/web-evolution.md:277: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#2019" aria-expanded="false" aria-controls="2019">2019</a></h4>
./content/about/history/web-evolution.md:304: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#2020" aria-expanded="false" aria-controls="2020">2020</a></h4>
./content/about/history/releases.md:17: <h4 class="panel-title"><a role="button" data-toggle="collapse" data-parent="#accordion" href="#2025" aria-expanded="true" aria-controls="2025">2025</a></h4>
./content/about/history/releases.md:35: <h4 class="panel-title"><a role="button" data-toggle="collapse" data-parent="#accordion" href="#2024" aria-expanded="true" aria-controls="2024">2024</a></h4>
./content/about/history/releases.md:55: <h4 class="panel-title"><a role="button" data-toggle="collapse" data-parent="#accordion" href="#2023" aria-expanded="true" aria-controls="2023">2023</a></h4>
./content/about/history/releases.md:80: <h4 class="panel-title"><a role="button" data-toggle="collapse" data-parent="#accordion" href="#2022" aria-expanded="true" aria-controls="2022">2022</a></h4>
./content/about/history/releases.md:101: <h4 class="panel-title"><a role="button" data-toggle="collapse" data-parent="#accordion" href="#2021" aria-expanded="true" aria-controls="2021">2021</a></h4>
./content/about/history/releases.md:118: <h4 class="panel-title"><a role="button" data-toggle="collapse" data-parent="#accordion" href="#2020" aria-expanded="true" aria-controls="2020">2020</a></h4>
./content/about/history/releases.md:135: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#2019" aria-expanded="false" aria-controls="2019">2019</a></h4>
./content/about/history/releases.md:157: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#2018" aria-expanded="false" aria-controls="2018">2018</a></h4>
./content/about/history/releases.md:177: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#2017" aria-expanded="false" aria-controls="2017">2017</a></h4>
./content/about/history/releases.md:195: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#2016" aria-expanded="false" aria-controls="2016">2016</a></h4>
./content/about/history/releases.md:219: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#2015" aria-expanded="false" aria-controls="2015">2015</a></h4>
./content/about/history/releases.md:244: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#2014" aria-expanded="false" aria-controls="2014">2014</a></h4>
./content/about/history/releases.md:261: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#2013" aria-expanded="false" aria-controls="2013">2013</a></h4>
./content/about/history/releases.md:277: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#2012" aria-expanded="false" aria-controls="2012">2012</a></h4>
./content/about/history/releases.md:295: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#2011" aria-expanded="false" aria-controls="2011">2011</a></h4>
./content/about/history/releases.md:313: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#2010" aria-expanded="false" aria-controls="2010">2010</a></h4>
./content/about/history/releases.md:330: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#2009" aria-expanded="false" aria-controls="2009">2009</a></h4>
./content/about/history/releases.md:348: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#2008" aria-expanded="false" aria-controls="2008">2008</a></h4>
./content/about/history/releases.md:369: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#2007" aria-expanded="false" aria-controls="2007">2007</a></h4>
./content/about/history/releases.md:391: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#2006" aria-expanded="false" aria-controls="2006">2006</a></h4>
./content/about/history/releases.md:422: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#2005" aria-expanded="false" aria-controls="2005">2005</a></h4>
./content/about/history/releases.md:443: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#2004" aria-expanded="false" aria-controls="2004">2004</a></h4>
./content/about/history/releases.md:460: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#2003" aria-expanded="false" aria-controls="2003">2003</a></h4>
./content/about/history/releases.md:478: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#2002" aria-expanded="false" aria-controls="2002">2002</a></h4>
./content/about/history/releases.md:496: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#2001" aria-expanded="false" aria-controls="2001">2001</a></h4>
./content/about/history/releases.md:514: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#2000" aria-expanded="false" aria-controls="2000">2000</a></h4>
./content/about/history/releases.md:534: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#1999" aria-expanded="false" aria-controls="1999">1999</a></h4>
./content/about/history/releases.md:561: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#1998" aria-expanded="false" aria-controls="1998">1998</a></h4>
./content/about/history/releases.md:596: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#1997" aria-expanded="false" aria-controls="1997">1997</a></h4>
./content/about/history/releases.md:611: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#1996" aria-expanded="false" aria-controls="1996">1996</a></h4>
./content/about/history/releases.md:627: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#1995" aria-expanded="false" aria-controls="1995">1995</a></h4>
./content/about/history/releases.md:643: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#1993" aria-expanded="false" aria-controls="1993">1993</a></h4>
./content/about/history/releases.md:658: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#1991" aria-expanded="false" aria-controls="1991">1991</a></h4>
./content/about/history/releases.md:674: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#1990" aria-expanded="false" aria-controls="199 0">1990</a></h4>
./content/about/history/releases.md:689: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#1989" aria-expanded="false" aria-controls="1989">1989</a></h4>
./content/about/history/releases.md:704: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#1988" aria-expanded="false" aria-controls="1988">1988</a></h4>
./content/about/history/releases.md:719: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#1987" aria-expanded="false" aria-controls="1987">1987</a></h4>
./content/about/history/releases.md:734: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#1986" aria-expanded="false" aria-controls="1986">1986</a></h4>
./content/about/history/releases.md:749: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#1985" aria-expanded="false" aria-controls="1985">1985</a></h4>
./content/about/history/releases.md:765: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#1984" aria-expanded="false" aria-controls="1984">1984</a></h4>
./content/about/history/releases.md:780: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#1983" aria-expanded="false" aria-controls="1983">1983</a></h4>
./content/about/history/releases.md:795: <h4 class="panel-title"><a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#1982" aria-expanded="false" aria-controls="1982">1982</a></h4>
./themes/grass/layouts/about/team.html:111: <button class="btn btn-primary" type="button" data-toggle="collapse" data-target="#collapseFormerPSCMembers" aria-expanded="false" aria-controls="collapseFormerPSCMembers">
./themes/grass/layouts/partials/brandDownloadIconDropdownButton.html:52: data-toggle="dropdown"
./themes/grass/layouts/partials/brandDownloadIconDropdownButton.html:143: data-toggle="dropdown"
./themes/grass/layouts/partials/brandDownloadIconDropdownButton.html:185: data-toggle="dropdown"
./themes/grass/layouts/download/tabs.html:29: <a class="nav-link active" id="linux-tab" data-toggle="tab" href="#linux" role="tab" aria-controls="linux" aria-selected="true">Linux</a>
./themes/grass/layouts/download/tabs.html:32: <a class="nav-link" id="mac-tab" data-toggle="tab" href="#mac" role="tab" aria-controls="mac" aria-selected="false">macOS</a>
./themes/grass/layouts/download/tabs.html:35: <a class="nav-link" id="windows-tab" data-toggle="tab" href="#windows" role="tab" aria-controls="windows" aria-selected="false">Windows</a>
./themes/grass/layouts/download/tabs.html:38: <a class="nav-link" id="windows-tab" data-toggle="tab" href="#docker" role="tab" aria-controls="docker" aria-selected="false">Docker</a>
./themes/grass/layouts/download/tabs.html:68: <button class="btn btn-secondary" type="button" data-toggle="collapse" data-target="#collapseWindowsAdditionalOptions" aria-expanded="false" aria-controls="collapseWindowsAdditionalOptions">
./themes/grass/layouts/contribute/devel.html:42: <li><i class="fa fa-file-code"></i>  <a href="https://github.com/wenzeslaus/foss4g-2022-developing-custom-grass-tools" target="_blank">Write your own tools</a></li>
./themes/grass/layouts/partials/navigation.html:12: data-target="#navigation"
./themes/grass/layouts/partials/navigation.html:13: data-toggle="collapse"
./themes/grass/layouts/partials/navigation.html:25: data-toggle="dropdown"
./themes/grass/layouts/shortcodes/donateDialog.html:5: <button data-toggle="modal" data-target="#donateToGrassModal" style="background:none;border:none;padding:0;margin:0;">- Verify JS initialization matches BS5.
- Replace glyphicons and legacy icon hooks
- Remove any Bootstrap 3 glyphicon references; ensure Font Awesome is used consistently.
- Files: search in layouts and style.css for glyphicon.
- Adapt utilities and helpers
- Replace .pull-, .center-block, .img-responsive, .hidden-, .visible-* with BS5 display utilities and .img-fluid.
rg --no-heading -n "\b(pull-[\w-]+|center-block|img-responsive|hidden-[\w-]+|visible-[\w-]+)\b" .
./content/learn/gallery.md:14:<a href="#" class="gallery-toggler pull-right">View more</a>
./content/learn/gallery.md:20:{{< gallery dir="/images/gallery/vector/" />}}<a href="#" class="gallery-toggler pull-right">View more</a>
./content/learn/gallery.md:26:{{< gallery dir="/images/gallery/raster/" />}}<a href="#" class="gallery-toggler pull-right">View more</a>
./content/learn/gallery.md:32:{{< gallery dir="/images/gallery/3D/" />}}<a href="#" class="gallery-toggler pull-right">View more</a>
./content/learn/gallery.md:38:{{< gallery dir="/images/gallery/lidar/" />}}<a href="#" class="gallery-toggler pull-right">View more</a>
./content/learn/gallery.md:44:{{< gallery dir="/images/gallery/remote_sensing/" />}}<a href="#" class="gallery-toggler pull-right">View more</a>
./content/learn/gallery.md:50:{{< gallery dir="/images/gallery/cartography/" />}}<a href="#" class="gallery-toggler pull-right">View more</a>
./themes/grass/layouts/partials/logo.html:2:<img src="{{.Site.BaseURL}}/images/logos/grass-logo/grass-green.svg" class="img-responsive" alt="GRASS">
./themes/grass/layouts/download/os.html:24: <img src="{{.Site.BaseURL}}/images/logos/grass-{{.Title}}.jpg" width="110" class="pull-right">
./content/about/governance.md:96:<i class="fa fa-code-pull-request fa-7x"
./themes/grass/layouts/download/data.html:23: <img src="{{.Site.BaseURL}}/images/logos/grass-SampleData.jpg" class="pull-right">
./themes/grass/assets/css/style.css:1045:.ui-helper-hidden-accessible {- Verify custom helper classes in style.css for overlaps.
- Update tables and cards
- Migrate .table-condensed/.table-hover variations to BS5 semantics; ensure .card usage matches BS5 (if any legacy .panel-* exist, rewrite to .card).
- Search layouts for panel/well classes (e.g., allnews.html).
rg --no-heading -n 'class="[^"]*\b(table-(condensed|hover)|panel-[\w-]+|well|card)\b[^"]*"' .
The command produces a lot of output but here is the general summary.
- Cards: used in brandColor shortcode (color swatch), grass-download partial (card-text), and multiple quicklinks cards.
- Legacy panels/accordions (BS3): extensive panel-group, panel panel-default, panel-heading, panel-title, panel-collapse, panel-body with data-toggle="collapse" across:
- history.md
- releases.md
- web-evolution.md
- No table-condensed/table-hover or well hits in these results.
- Purge deprecated JS plugins and data-API patterns
- Ensure no reliance on BS3-only JS behaviors; move to BS5 bundle.
- Remove any manual $.fn.* Bootstrap plugin calls; replace with BS5 bootstrap.* API if still needed.
rg --no-heading -n '\$\.fn\.' .
./themes/grass/assets/js/script.js:5: $.fn.lastWord = function() {- Rebuild and fingerprint assets
- After migration, rebuild Hugo pipelines for CSS/JS bundles and verify integrity hashes in head.html.
- Confirm no mixed versions remain in the final public output.
- Regression pass and browser testing
- Add a checklist for visual QA (nav, forms, carousel, dropdowns, modals) across key pages: home, news listing, about pages (e.g., roadmap.html), learn pages (e.g., overview.html), and contribute pages (e.g., list.html).