Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/twbs/bootstrap.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Otto <markd.otto@gmail.com>2022-04-18 08:17:50 +0300
committerGitHub <noreply@github.com>2022-04-18 08:17:50 +0300
commit195440f2fb1e94c014a9cf08f3eae40f3d224620 (patch)
tree28b6e15b4bc9af353083ba300474aa6e187a6f7a
parent26ea6f1649c51d2a7edc796221bd5b46b289bb28 (diff)
v5.2.0 design refresh, plus responsive offcanvas classes (#35736)
* Add responsive offcanvas classes - Updates navbar-expand classes to de-dupe some styles—these shouldn't interfere now. - Adds some JS to the offcanvas component to help with responsiveness Co-Authored-By: GeoSot <geo.sotis@gmail.com> * Redesign homepage, docs, and examples Homepage: - New Bootstrap purple navbar - Redesigned masthead - Rewrote and redesigned homepage content - Replace Copy text with icons like Bootstrap Icons site across all ClipboardJS instances - Fixed padding issues in site footer - Match homepage button styles to examples page, use gap instead of tons of responsive margin utils Docs: - New navbar, no more subnav. Migrated search and version picker into the main navbar and refreshed the design of it all, including the responsive toggles. - New sidebar navigation is always expanded, and now features Bootstrap Icons alongside section headings - Sidebar navigation autoscrolls to active link for better usability - Subnav and navbar padding issues ironed out - Enhanced the version picker in anticipation of v5.2: we can now link right to the same page in the previous version. - Redesign callouts to add more color to our pages - Collapse table of contents on mobile - Cleanup and redesign button styles with CSS variables - Update design for subnav version dropdown - Update highlight and example to be full-width until md - Improve the Added In badges - Turn the ToC into a well on mobile - Redesign code snippets to better house two action buttons Examples: - Redesign Examples page layout - Add new example for responsive offcanvases in navbars * Convert offcanvas to CSS vars * Feat: add resize handler to Offcanvas.js. If we could use as default the `.offcanvas` class without modifiers, we then, could add a simplified selector The selector itself, ignores the .offcanvas class as it doesn't have any responsive behavior The `aria-modal` addon is to protect us, selection backdrop elements * Separate examples code, Add some selectors, fix stackblitz btn Co-authored-by: GeoSot <geo.sotis@gmail.com>
-rw-r--r--.bundlewatch.config.json4
-rw-r--r--js/src/offcanvas.js9
-rw-r--r--js/tests/unit/offcanvas.spec.js22
-rw-r--r--scss/_navbar.scss46
-rw-r--r--scss/_offcanvas.scss179
-rw-r--r--scss/_spinners.scss2
-rw-r--r--site/assets/js/application.js74
-rw-r--r--site/assets/js/code-examples.js88
-rw-r--r--site/assets/js/search.js7
-rw-r--r--site/assets/scss/_ads.scss5
-rw-r--r--site/assets/scss/_algolia.scss7
-rw-r--r--site/assets/scss/_buttons.scss16
-rw-r--r--site/assets/scss/_callouts.scss30
-rw-r--r--site/assets/scss/_clipboard-js.scss37
-rw-r--r--site/assets/scss/_component-examples.scss42
-rw-r--r--site/assets/scss/_content.scss59
-rw-r--r--site/assets/scss/_layout.scss19
-rw-r--r--site/assets/scss/_masthead.scss77
-rw-r--r--site/assets/scss/_navbar.scss85
-rw-r--r--site/assets/scss/_search.scss62
-rw-r--r--site/assets/scss/_sidebar.scss90
-rw-r--r--site/assets/scss/_subnav.scss82
-rw-r--r--site/assets/scss/_syntax.scss2
-rw-r--r--site/assets/scss/_toc.scss45
-rw-r--r--site/assets/scss/_variables.scss12
-rw-r--r--site/assets/scss/docs.scss2
-rw-r--r--site/content/docs/5.1/components/offcanvas.md57
-rw-r--r--site/content/docs/5.1/examples/_index.md57
-rw-r--r--site/content/docs/5.1/examples/navbars-offcanvas/index.html147
-rw-r--r--site/content/docs/5.1/examples/navbars-offcanvas/navbar.css7
-rw-r--r--site/content/docs/5.1/utilities/api.md2
-rw-r--r--site/content/docs/5.1/utilities/spacing.md4
-rw-r--r--site/data/examples.yml2
-rw-r--r--site/data/plugins.yml47
-rw-r--r--site/data/sidebar.yml20
-rw-r--r--site/layouts/_default/baseof.html1
-rw-r--r--site/layouts/_default/docs.html38
-rw-r--r--site/layouts/_default/single.html17
-rw-r--r--site/layouts/partials/docs-navbar.html103
-rw-r--r--site/layouts/partials/docs-sidebar.html37
-rw-r--r--site/layouts/partials/docs-subnav.html14
-rw-r--r--site/layouts/partials/docs-versions.html26
-rw-r--r--site/layouts/partials/favicons.html4
-rw-r--r--site/layouts/partials/footer.html5
-rw-r--r--site/layouts/partials/home/masthead-followup.html342
-rw-r--r--site/layouts/partials/home/masthead.html50
-rw-r--r--site/layouts/partials/icons.html72
-rw-r--r--site/layouts/partials/scripts.html3
-rw-r--r--site/layouts/shortcodes/example.html39
-rw-r--r--site/static/docs/5.1/assets/img/examples/navbars-offcanvas.pngbin0 -> 6919 bytes
-rw-r--r--site/static/docs/5.1/assets/img/examples/navbars-offcanvas@2x.pngbin0 -> 17121 bytes
51 files changed, 1572 insertions, 625 deletions
diff --git a/.bundlewatch.config.json b/.bundlewatch.config.json
index 19c4b99994..b864477107 100644
--- a/.bundlewatch.config.json
+++ b/.bundlewatch.config.json
@@ -26,11 +26,11 @@
},
{
"path": "./dist/css/bootstrap.css",
- "maxSize": "27.75 kB"
+ "maxSize": "28.5 kB"
},
{
"path": "./dist/css/bootstrap.min.css",
- "maxSize": "26.0 kB"
+ "maxSize": "26.5 kB"
},
{
"path": "./dist/js/bootstrap.bundle.js",
diff --git a/js/src/offcanvas.js b/js/src/offcanvas.js
index b5afc0c87b..0ae5dbfdab 100644
--- a/js/src/offcanvas.js
+++ b/js/src/offcanvas.js
@@ -41,6 +41,7 @@ const EVENT_SHOWN = `shown${EVENT_KEY}`
const EVENT_HIDE = `hide${EVENT_KEY}`
const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY}`
const EVENT_HIDDEN = `hidden${EVENT_KEY}`
+const EVENT_RESIZE = `resize${EVENT_KEY}`
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`
@@ -263,6 +264,14 @@ EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
}
})
+EventHandler.on(window, EVENT_RESIZE, () => {
+ for (const element of SelectorEngine.find('[aria-modal][class*=show][class*=offcanvas-]')) {
+ if (getComputedStyle(element).position !== 'fixed') {
+ Offcanvas.getOrCreateInstance(element).hide()
+ }
+ }
+})
+
enableDismissTrigger(Offcanvas)
/**
diff --git a/js/tests/unit/offcanvas.spec.js b/js/tests/unit/offcanvas.spec.js
index a98a8c13e3..ad0595a866 100644
--- a/js/tests/unit/offcanvas.spec.js
+++ b/js/tests/unit/offcanvas.spec.js
@@ -155,6 +155,28 @@ describe('Offcanvas', () => {
offCanvas.show()
})
})
+
+ it('should call `hide` on resize, if element\'s position is not fixed any more', () => {
+ return new Promise(resolve => {
+ fixtureEl.innerHTML = '<div class="offcanvas-lg"></div>'
+
+ const offCanvasEl = fixtureEl.querySelector('div')
+ const offCanvas = new Offcanvas(offCanvasEl)
+
+ spyOn(offCanvas, 'hide').and.callThrough()
+
+ offCanvasEl.addEventListener('shown.bs.offcanvas', () => {
+ const resizeEvent = createEvent('resize')
+ offCanvasEl.style.removeProperty('position')
+
+ window.dispatchEvent(resizeEvent)
+ expect(offCanvas.hide).toHaveBeenCalled()
+ resolve()
+ })
+
+ offCanvas.show()
+ })
+ })
})
describe('config', () => {
diff --git a/scss/_navbar.scss b/scss/_navbar.scss
index 6db562519c..bd140ae099 100644
--- a/scss/_navbar.scss
+++ b/scss/_navbar.scss
@@ -222,41 +222,31 @@
display: none;
}
- .offcanvas-header {
- display: none;
- }
-
.offcanvas {
- position: inherit;
- bottom: 0;
+ // stylelint-disable declaration-no-important
+ position: static;
z-index: auto;
flex-grow: 1;
- visibility: visible !important; // stylelint-disable-line declaration-no-important
- background-color: transparent;
- border-right: 0;
- border-left: 0;
+ width: auto !important;
+ height: auto !important;
+ visibility: visible !important;
+ background-color: transparent !important;
+ border: 0 !important;
+ transform: none !important;
@include box-shadow(none);
@include transition(none);
- transform: none;
- }
- .offcanvas-top,
- .offcanvas-bottom {
- height: auto;
- border-top: 0;
- border-bottom: 0;
- }
+ // stylelint-enable declaration-no-important
- .offcanvas-body {
- display: flex;
- flex-grow: 0;
- padding: 0;
- overflow-y: visible;
- }
+ .offcanvas-header {
+ display: none;
+ }
- // Reset `background-color` in case `.bg-*` classes are used in offcanvas
- .offcanvas,
- .offcanvas-body {
- background-color: transparent !important; // stylelint-disable-line declaration-no-important
+ .offcanvas-body {
+ display: flex;
+ flex-grow: 0;
+ padding: 0;
+ overflow-y: visible;
+ }
}
}
}
diff --git a/scss/_offcanvas.scss b/scss/_offcanvas.scss
index 5288fa9ce6..e923db2f24 100644
--- a/scss/_offcanvas.scss
+++ b/scss/_offcanvas.scss
@@ -1,27 +1,115 @@
-.offcanvas {
- position: fixed;
- bottom: 0;
- z-index: $zindex-offcanvas;
- display: flex;
- flex-direction: column;
- max-width: 100%;
- color: $offcanvas-color;
- visibility: hidden;
- background-color: $offcanvas-bg-color;
- background-clip: padding-box;
- outline: 0;
- @include box-shadow($offcanvas-box-shadow);
- @include transition(transform $offcanvas-transition-duration ease-in-out);
-
- &.showing,
- &.show:not(.hiding) {
- transform: none;
+// stylelint-disable function-disallowed-list
+
+%offcanvas-css-vars {
+ // scss-docs-start offcanvas-css-vars
+ --#{$prefix}offcanvas-width: #{$offcanvas-horizontal-width};
+ --#{$prefix}offcanvas-height: #{$offcanvas-vertical-height};
+ --#{$prefix}offcanvas-padding-x: #{$offcanvas-padding-x};
+ --#{$prefix}offcanvas-padding-y: #{$offcanvas-padding-y};
+ --#{$prefix}offcanvas-color: #{$offcanvas-color};
+ --#{$prefix}offcanvas-bg: #{$offcanvas-bg-color};
+ --#{$prefix}offcanvas-border-width: #{$offcanvas-border-width};
+ --#{$prefix}offcanvas-border-color: #{$offcanvas-border-color};
+ --#{$prefix}offcanvas-box-shadow: #{$offcanvas-box-shadow};
+ // scss-docs-end offcanvas-css-vars
+}
+
+@each $breakpoint in map-keys($grid-breakpoints) {
+ $next: breakpoint-next($breakpoint, $grid-breakpoints);
+ $infix: breakpoint-infix($next, $grid-breakpoints);
+
+ .offcanvas#{$infix} {
+ @extend %offcanvas-css-vars;
}
+}
+
+@each $breakpoint in map-keys($grid-breakpoints) {
+ $next: breakpoint-next($breakpoint, $grid-breakpoints);
+ $infix: breakpoint-infix($next, $grid-breakpoints);
+
+ .offcanvas#{$infix} {
+ @include media-breakpoint-down($next) {
+ position: fixed;
+ bottom: 0;
+ z-index: $zindex-offcanvas;
+ display: flex;
+ flex-direction: column;
+ max-width: 100%;
+ color: var(--#{$prefix}offcanvas-color);
+ visibility: hidden;
+ background-color: var(--#{$prefix}offcanvas-bg);
+ background-clip: padding-box;
+ outline: 0;
+ @include box-shadow(var(--#{$prefix}offcanvas-box-shadow));
+ @include transition(transform $offcanvas-transition-duration ease-in-out);
+
+ &.showing,
+ &.show:not(.hiding) {
+ transform: none;
+ }
+
+ &.showing,
+ &.hiding,
+ &.show {
+ visibility: visible;
+ }
+
+ &.offcanvas-start {
+ top: 0;
+ left: 0;
+ width: var(--#{$prefix}offcanvas-width);
+ border-right: var(--#{$prefix}offcanvas-border-width) solid var(--#{$prefix}offcanvas-border-color);
+ transform: translateX(-100%);
+ }
+
+ &.offcanvas-end {
+ top: 0;
+ right: 0;
+ width: var(--#{$prefix}offcanvas-width);
+ border-left: var(--#{$prefix}offcanvas-border-width) solid var(--#{$prefix}offcanvas-border-color);
+ transform: translateX(100%);
+ }
- &.showing,
- &.hiding,
- &.show {
- visibility: visible;
+ &.offcanvas-top {
+ top: 0;
+ right: 0;
+ left: 0;
+ height: var(--#{$prefix}offcanvas-height);
+ max-height: 100%;
+ border-bottom: var(--#{$prefix}offcanvas-border-width) solid var(--#{$prefix}offcanvas-border-color);
+ transform: translateY(-100%);
+ }
+
+ &.offcanvas-bottom {
+ right: 0;
+ left: 0;
+ height: var(--#{$prefix}offcanvas-height);
+ max-height: 100%;
+ border-top: var(--#{$prefix}offcanvas-border-width) solid var(--#{$prefix}offcanvas-border-color);
+ transform: translateY(100%);
+ }
+ }
+
+ @if not ($infix == "") {
+ @include media-breakpoint-up($next) {
+ --#{$prefix}offcanvas-height: auto;
+ --#{$prefix}offcanvas-border-width: 0;
+ background-color: transparent !important; // stylelint-disable-line declaration-no-important
+
+ .offcanvas-header {
+ display: none;
+ }
+
+ .offcanvas-body {
+ display: flex;
+ flex-grow: 0;
+ padding: 0;
+ overflow-y: visible;
+ // Reset `background-color` in case `.bg-*` classes are used in offcanvas
+ background-color: transparent !important; // stylelint-disable-line declaration-no-important
+ }
+ }
+ }
}
}
@@ -33,13 +121,13 @@
display: flex;
align-items: center;
justify-content: space-between;
- padding: $offcanvas-padding-y $offcanvas-padding-x;
+ padding: var(--#{$prefix}offcanvas-padding-y) var(--#{$prefix}offcanvas-padding-x);
.btn-close {
- padding: ($offcanvas-padding-y * .5) ($offcanvas-padding-x * .5);
- margin-top: $offcanvas-padding-y * -.5;
- margin-right: $offcanvas-padding-x * -.5;
- margin-bottom: $offcanvas-padding-y * -.5;
+ padding: calc(var(--#{$prefix}offcanvas-padding-y) * .5) calc(var(--#{$prefix}offcanvas-padding-x) * .5);
+ margin-top: calc(var(--#{$prefix}offcanvas-padding-y) * -.5);
+ margin-right: calc(var(--#{$prefix}offcanvas-padding-x) * -.5);
+ margin-bottom: calc(var(--#{$prefix}offcanvas-padding-y) * -.5);
}
}
@@ -50,41 +138,6 @@
.offcanvas-body {
flex-grow: 1;
- padding: $offcanvas-padding-y $offcanvas-padding-x;
+ padding: var(--#{$prefix}offcanvas-padding-y) var(--#{$prefix}offcanvas-padding-x);
overflow-y: auto;
}
-
-.offcanvas-start {
- top: 0;
- left: 0;
- width: $offcanvas-horizontal-width;
- border-right: $offcanvas-border-width solid $offcanvas-border-color;
- transform: translateX(-100%);
-}
-
-.offcanvas-end {
- top: 0;
- right: 0;
- width: $offcanvas-horizontal-width;
- border-left: $offcanvas-border-width solid $offcanvas-border-color;
- transform: translateX(100%);
-}
-
-.offcanvas-top {
- top: 0;
- right: 0;
- left: 0;
- height: $offcanvas-vertical-height;
- max-height: 100%;
- border-bottom: $offcanvas-border-width solid $offcanvas-border-color;
- transform: translateY(-100%);
-}
-
-.offcanvas-bottom {
- right: 0;
- left: 0;
- height: $offcanvas-vertical-height;
- max-height: 100%;
- border-top: $offcanvas-border-width solid $offcanvas-border-color;
- transform: translateY(100%);
-}
diff --git a/scss/_spinners.scss b/scss/_spinners.scss
index 2fc7d3edc5..ec8473207e 100644
--- a/scss/_spinners.scss
+++ b/scss/_spinners.scss
@@ -29,7 +29,7 @@
--#{$prefix}spinner-animation-name: spinner-border;
// scss-docs-end spinner-border-css-vars
- border: var(--#{$prefix}spinner-border-width) solid currentColor;
+ border: var(--#{$prefix}spinner-border-width) solid currentcolor;
border-right-color: transparent;
}
diff --git a/site/assets/js/application.js b/site/assets/js/application.js
index c14dc57c22..55e8969802 100644
--- a/site/assets/js/application.js
+++ b/site/assets/js/application.js
@@ -10,11 +10,26 @@
* For details, see https://creativecommons.org/licenses/by/3.0/.
*/
-/* global ClipboardJS: false, bootstrap: false */
+/* global bootstrap: false */
(() => {
'use strict'
+ // Scroll the active sidebar link into view
+ const sidenav = document.querySelector('.bd-sidebar')
+ if (sidenav) {
+ const sidenavHeight = sidenav.clientHeight
+ const sidenavActiveLink = document.querySelector('.bd-links-nav .active')
+ const sidenavActiveLinkTop = sidenavActiveLink.offsetTop
+ const sidenavActiveLinkHeight = sidenavActiveLink.clientHeight
+ const viewportTop = sidenavActiveLinkTop
+ const viewportBottom = viewportTop - sidenavHeight + sidenavActiveLinkHeight
+
+ if (sidenav.scrollTop > viewportTop || sidenav.scrollTop < viewportBottom) {
+ sidenav.scrollTop = viewportTop - (sidenavHeight / 2) + (sidenavActiveLinkHeight / 2)
+ }
+ }
+
// Tooltip and popover demos
document.querySelectorAll('.tooltip-demo')
.forEach(tooltip => {
@@ -116,61 +131,4 @@
modalBodyInput.value = recipient
})
}
-
- // Insert copy to clipboard button before .highlight
- const btnTitle = 'Copy to clipboard'
- const btnEdit = 'Edit on StackBlitz'
- const btnHtml = '<div class="bd-clipboard"><button type="button" class="btn-clipboard">Copy</button></div>'
- document.querySelectorAll('div.highlight')
- .forEach(element => {
- element.insertAdjacentHTML('beforebegin', btnHtml)
- })
-
- /**
- *
- * @param {string} selector
- * @param {string} title
- */
- function snippetButtonTooltip(selector, title) {
- document.querySelectorAll(selector).forEach(btn => {
- const tooltipBtn = new bootstrap.Tooltip(btn, { title })
-
- btn.addEventListener('mouseleave', () => {
- // Explicitly hide tooltip, since after clicking it remains
- // focused (as it's a button), so tooltip would otherwise
- // remain visible until focus is moved away
- tooltipBtn.hide()
- })
- })
- }
-
- snippetButtonTooltip('.btn-clipboard', btnTitle)
- snippetButtonTooltip('.btn-edit', btnEdit)
-
- const clipboard = new ClipboardJS('.btn-clipboard', {
- target(trigger) {
- return trigger.parentNode.nextElementSibling
- }
- })
-
- clipboard.on('success', event => {
- const tooltipBtn = bootstrap.Tooltip.getInstance(event.trigger)
-
- tooltipBtn.setContent({ '.tooltip-inner': 'Copied!' })
- event.trigger.addEventListener('hidden.bs.tooltip', () => {
- tooltipBtn.setContent({ '.tooltip-inner': btnTitle })
- }, { once: true })
- event.clearSelection()
- })
-
- clipboard.on('error', event => {
- const modifierKey = /mac/i.test(navigator.userAgent) ? '\u2318' : 'Ctrl-'
- const fallbackMsg = `Press ${modifierKey}C to copy`
- const tooltipBtn = bootstrap.Tooltip.getInstance(event.trigger)
-
- tooltipBtn.setContent({ '.tooltip-inner': fallbackMsg })
- event.trigger.addEventListener('hidden.bs.tooltip', () => {
- tooltipBtn.setContent({ '.tooltip-inner': btnTitle })
- }, { once: true })
- })
})()
diff --git a/site/assets/js/code-examples.js b/site/assets/js/code-examples.js
new file mode 100644
index 0000000000..4a61fa09b7
--- /dev/null
+++ b/site/assets/js/code-examples.js
@@ -0,0 +1,88 @@
+// NOTICE!! DO NOT USE ANY OF THIS JAVASCRIPT
+// IT'S ALL JUST JUNK FOR OUR DOCS!
+// ++++++++++++++++++++++++++++++++++++++++++
+
+/*!
+ * JavaScript for Bootstrap's docs (https://getbootstrap.com/)
+ * Copyright 2011-2022 The Bootstrap Authors
+ * Copyright 2011-2022 Twitter, Inc.
+ * Licensed under the Creative Commons Attribution 3.0 Unported License.
+ * For details, see https://creativecommons.org/licenses/by/3.0/.
+ */
+
+/* global ClipboardJS: false, bootstrap: false */
+
+(() => {
+ 'use strict'
+ // Insert copy to clipboard button before .highlight
+ const btnTitle = 'Copy to clipboard'
+ const btnEdit = 'Edit on StackBlitz'
+
+ const btnHtml = [
+ '<div class="bd-code-snippet">',
+ ' <div class="bd-clipboard">',
+ ' <button type="button" class="btn-clipboard">',
+ ' <svg class="bi" width="1em" height="1em" fill="currentColor" role="img" aria-label="Copy"><use xlink:href="#clipboard"/></svg>',
+ ' </button>',
+ ' </div>',
+ '</div>'
+ ].join('')
+
+ // wrap programmatically code blocks and add copy btn.
+ document.querySelectorAll('.highlight')
+ .forEach(element => {
+ if (!element.closest('.bd-example-snippet')) { // Ignore examples made be shortcode
+ element.insertAdjacentHTML('beforebegin', btnHtml)
+ element.previousElementSibling.append(element)
+ }
+ })
+
+ /**
+ *
+ * @param {string} selector
+ * @param {string} title
+ */
+ function snippetButtonTooltip(selector, title) {
+ document.querySelectorAll(selector).forEach(btn => {
+ bootstrap.Tooltip.getOrCreateInstance(btn, { title })
+ })
+ }
+
+ snippetButtonTooltip('.btn-clipboard', btnTitle)
+ snippetButtonTooltip('.btn-edit', btnEdit)
+
+ const clipboard = new ClipboardJS('.btn-clipboard', {
+ target: trigger => trigger.closest('.bd-code-snippet').querySelector('.highlight')
+ })
+
+ clipboard.on('success', event => {
+ const iconFirstChild = event.trigger.querySelector('.bi').firstChild
+ const tooltipBtn = bootstrap.Tooltip.getInstance(event.trigger)
+ const namespace = 'http://www.w3.org/1999/xlink'
+ const originalXhref = iconFirstChild.getAttributeNS(namespace, 'href')
+ const originalTitle = event.trigger.title
+
+ tooltipBtn.setContent({ '.tooltip-inner': 'Copied!' })
+ event.trigger.addEventListener('hidden.bs.tooltip', () => {
+ tooltipBtn.setContent({ '.tooltip-inner': btnTitle })
+ }, { once: true })
+ event.clearSelection()
+ iconFirstChild.setAttributeNS(namespace, 'href', originalXhref.replace('clipboard', 'check2'))
+
+ setTimeout(() => {
+ iconFirstChild.setAttributeNS(namespace, 'href', originalXhref)
+ event.trigger.title = originalTitle
+ }, 2000)
+ })
+
+ clipboard.on('error', event => {
+ const modifierKey = /mac/i.test(navigator.userAgent) ? '\u2318' : 'Ctrl-'
+ const fallbackMsg = `Press ${modifierKey}C to copy`
+ const tooltipBtn = bootstrap.Tooltip.getInstance(event.trigger)
+
+ tooltipBtn.setContent({ '.tooltip-inner': fallbackMsg })
+ event.trigger.addEventListener('hidden.bs.tooltip', () => {
+ tooltipBtn.setContent({ '.tooltip-inner': btnTitle })
+ }, { once: true })
+ })
+})()
diff --git a/site/assets/js/search.js b/site/assets/js/search.js
index 15197bfd9a..6c90a20872 100644
--- a/site/assets/js/search.js
+++ b/site/assets/js/search.js
@@ -14,12 +14,17 @@
const siteDocsVersion = inputElement.getAttribute('data-bd-docs-version')
document.addEventListener('keydown', event => {
- if (event.ctrlKey && event.key === '/') {
+ if ((((event.ctrlKey || event.metaKey) && event.key === 'k')) || (event.ctrlKey && event.key === '/')) {
event.preventDefault()
inputElement.focus()
}
})
+ if (navigator.platform.includes('Win') || navigator.platform.includes('Linux')) {
+ const searchShortcut = document.querySelector('.bd-search')
+ searchShortcut.setAttribute('data-shortcut', '⌃K')
+ }
+
window.docsearch({
apiKey: '5990ad008512000bba2cf951ccf0332f',
indexName: 'bootstrap',
diff --git a/site/assets/scss/_ads.scss b/site/assets/scss/_ads.scss
index 026d1a17a7..b9369eb19c 100644
--- a/site/assets/scss/_ads.scss
+++ b/site/assets/scss/_ads.scss
@@ -14,7 +14,7 @@
@include font-size(.8125rem);
line-height: 1.4;
text-align: left;
- background-color: rgba(0, 0, 0, .05);
+ background-color: $gray-100;
a {
color: $gray-800;
@@ -22,8 +22,7 @@
}
@include media-breakpoint-up(sm) {
- max-width: 330px;
- @include border-radius(4px);
+ @include border-radius(.5rem);
}
}
diff --git a/site/assets/scss/_algolia.scss b/site/assets/scss/_algolia.scss
index 9c457d2e37..ab22ad9a7e 100644
--- a/site/assets/scss/_algolia.scss
+++ b/site/assets/scss/_algolia.scss
@@ -12,12 +12,15 @@
margin: $dropdown-spacer 0 0;
@include font-size(.875rem);
background-color: $dropdown-bg;
+ background-clip: padding-box;
border: $dropdown-border-width solid $dropdown-border-color;
@include border-radius($dropdown-border-radius);
- @include box-shadow($dropdown-box-shadow);
+ box-shadow: $dropdown-box-shadow;
@include media-breakpoint-up(md) {
- width: 400px;
+ width: 500px;
+ margin-top: .5rem;
+ margin-left: -110px;
}
}
diff --git a/site/assets/scss/_buttons.scss b/site/assets/scss/_buttons.scss
index 93ffa83ed5..13bd6e48a3 100644
--- a/site/assets/scss/_buttons.scss
+++ b/site/assets/scss/_buttons.scss
@@ -8,10 +8,14 @@
--bs-btn-color: var(--bs-white);
--bs-btn-bg: var(--bd-violet);
--bs-btn-border-color: var(--bd-violet);
+ --bs-btn-border-radius: .5rem;
--bs-btn-hover-color: var(--bs-white);
- --bs-btn-hover-bg: #{shade-color($bd-violet, 20%)};
- --bs-btn-hover-border-color: #{shade-color($bd-violet, 20%)};
+ --bs-btn-hover-bg: #{shade-color($bd-violet, 10%)};
+ --bs-btn-hover-border-color: #{shade-color($bd-violet, 10%)};
--bs-btn-focus-shadow-rgb: var(--bd-violet-rgb);
+ --bs-btn-active-color: var(--bs-btn-hover-color);
+ --bs-btn-active-bg: #{shade-color($bd-violet, 20%)};
+ --bs-btn-active-border-color: #{shade-color($bd-violet, 20%)};
}
// scss-docs-end btn-css-vars-example
@@ -23,13 +27,19 @@
--bs-btn-hover-bg: var(--bd-accent);
--bs-btn-hover-border-color: var(--bd-accent);
--bs-btn-focus-shadow-rgb: var(--bd-accent-rgb);
+ --bs-btn-active-color: var(--bs-btn-hover-color);
+ --bs-btn-active-bg: var(--bs-btn-hover-bg);
+ --bs-btn-active-border-color: var(--bs-btn-hover-border-color);
}
.btn-bd-light {
--bs-btn-color: var(--bs-gray-600);
- --bs-btn-border-color: var(--bs-gray-300);
+ --bs-btn-border-color: var(--bs-gray-400);
+ --bs-btn-hover-color: var(--bd-violet);
+ --bs-btn-hover-border-color: var(--bd-violet);
--bs-btn-active-color: var(--bd-violet);
--bs-btn-active-bg: var(--bs-white);
--bs-btn-active-border-color: var(--bd-violet);
+ --bs-btn-focus-border-color: var(--bd-violet);
--bs-btn-focus-shadow-rgb: var(--bd-violet-rgb);
}
diff --git a/site/assets/scss/_callouts.scss b/site/assets/scss/_callouts.scss
index aff91f18b6..4513a7d1d5 100644
--- a/site/assets/scss/_callouts.scss
+++ b/site/assets/scss/_callouts.scss
@@ -6,36 +6,30 @@
padding: 1.25rem;
margin-top: 1.25rem;
margin-bottom: 1.25rem;
- border: 1px solid $gray-200;
- border-left-width: .25rem;
- @include border-radius();
+ background-color: var(--bd-callout-bg, var(--bs-gray-100));
+ border-left: .25rem solid var(--bd-callout-border, var(--bs-gray-300));
h4 {
margin-bottom: .25rem;
}
- p:last-child {
+ > :last-child {
margin-bottom: 0;
}
- code {
- @include border-radius();
- }
-
+ .bd-callout {
margin-top: -.25rem;
}
-}
-// Variations
-.bd-callout-info {
- border-left-color: $bd-info;
-}
-
-.bd-callout-warning {
- border-left-color: $bd-warning;
+ .highlight {
+ background-color: rgba($black, .05);
+ }
}
-.bd-callout-danger {
- border-left-color: $bd-danger;
+// Variations
+@each $variant in $bd-callout-variants {
+ .bd-callout-#{$variant} {
+ --bd-callout-bg: rgba(var(--bs-#{$variant}-rgb), .075);
+ --bd-callout-border: rgba(var(--bs-#{$variant}-rgb), .5);
+ }
}
diff --git a/site/assets/scss/_clipboard-js.scss b/site/assets/scss/_clipboard-js.scss
index b2b0854dc4..7acf90f0b7 100644
--- a/site/assets/scss/_clipboard-js.scss
+++ b/site/assets/scss/_clipboard-js.scss
@@ -19,26 +19,29 @@
.btn-clipboard,
.btn-edit {
- position: absolute;
- top: .65rem;
- right: .65rem;
- z-index: 10;
display: block;
- padding: .25rem .5rem;
- @include font-size(.65em);
- color: $primary;
- white-space: nowrap;
- background-color: $white;
- border: 1px solid;
- @include border-radius();
+ padding: .5em;
+ line-height: 1;
+ color: $gray-900;
+ background-color: $gray-100;
+ border: 0;
+ @include border-radius(.25rem);
- &:hover,
- &:focus {
- color: $white;
- background-color: $primary;
+ &:hover {
+ color: $primary;
}
}
-.btn-edit {
- right: 3.65rem;
+.btn-clipboard {
+ position: relative;
+ z-index: 2;
+ margin-top: .75rem;
+ margin-right: .75rem;
+}
+
+.highlight-toolbar {
+ .btn-clipboard {
+ margin-top: 0;
+ margin-right: 0;
+ }
}
diff --git a/site/assets/scss/_component-examples.scss b/site/assets/scss/_component-examples.scss
index 330bd43bac..b305f088f9 100644
--- a/site/assets/scss/_component-examples.scss
+++ b/site/assets/scss/_component-examples.scss
@@ -85,21 +85,17 @@
.bd-example {
position: relative;
padding: 1rem;
- margin: 1rem ($bd-gutter-x * -1) 0;
- border: solid $gray-300;
+ margin: 1rem ($bd-gutter-x * -.5) 0;
+ border: solid $border-color;
border-width: 1px 0 0;
@include clearfix();
- @include media-breakpoint-up(sm) {
+ @include media-breakpoint-up(md) {
padding: 1.5rem;
margin-right: 0;
margin-left: 0;
border-width: 1px;
- @include border-top-radius(.25rem);
-
- + .bd-clipboard + .highlight {
- @include border-bottom-radius(.25rem);
- }
+ @include border-top-radius(var(--bs-border-radius));
}
+ p {
@@ -348,12 +344,14 @@
//
.highlight {
- padding: var(--bs-gutter-x) $bd-gutter-x;
+ position: relative;
+ padding: .75rem ($bd-gutter-x * .5);
margin-bottom: 1rem;
background-color: var(--bs-gray-100);
- @include media-breakpoint-up(sm) {
- padding: 1rem 1.5rem;
+ @include media-breakpoint-up(md) {
+ padding: .75rem 1.25rem;
+ @include border-radius(var(--bs-border-radius));
}
pre {
@@ -363,6 +361,11 @@
white-space: pre;
background-color: transparent;
border: 0;
+
+ // Undo tabindex that's automatically added by Hugo
+ &:focus {
+ outline: 0;
+ }
}
pre code {
@@ -372,11 +375,22 @@
}
}
+.bd-example-snippet {
+ .highlight {
+ @include border-top-radius(0);
+ border: 1px solid $border-color;
+ }
+ .highlight-toolbar {
+ border: solid $border-color;
+ border-width: 0 1px;
+ }
+}
+
.bd-content .highlight {
- margin-right: $bd-gutter-x * -1;
- margin-left: $bd-gutter-x * -1;
+ margin-right: $bd-gutter-x * -.5;
+ margin-left: $bd-gutter-x * -.5;
- @include media-breakpoint-up(sm) {
+ @include media-breakpoint-up(md) {
margin-right: 0;
margin-left: 0;
}
diff --git a/site/assets/scss/_content.scss b/site/assets/scss/_content.scss
index d796c491e0..cd594335a6 100644
--- a/site/assets/scss/_content.scss
+++ b/site/assets/scss/_content.scss
@@ -2,14 +2,13 @@
// Bootstrap docs content theming
//
-// Offset for the sticky header
-@include media-breakpoint-up(md) {
- :root {
- scroll-padding-top: 4rem;
+.bd-content {
+ // Offset content from fixed navbar when jumping to headings
+ > :target {
+ padding-top: 5rem;
+ margin-top: -5rem;
}
-}
-.bd-content {
> h2:not(:first-child) {
margin-top: 3rem;
}
@@ -46,6 +45,10 @@
border-bottom: 2px solid currentcolor;
}
+ tbody:not(:first-child) {
+ border-top: 2px solid currentcolor;
+ }
+
th,
td {
&:first-child {
@@ -59,12 +62,24 @@
// Prevent breaking of code
// stylelint-disable-next-line selector-max-compound-selectors
+ th,
td:first-child > code {
white-space: nowrap;
}
}
}
+.table-options {
+ td:nth-child(2) {
+ min-width: 160px;
+ }
+}
+
+.table-options td:last-child,
+.table-utilities td:last-child {
+ min-width: 280px;
+}
+
.bd-title {
@include font-size(3rem);
}
@@ -77,3 +92,35 @@
.bd-bg-violet {
background-color: $bd-violet;
}
+
+.bi {
+ width: 1em;
+ height: 1em;
+ fill: currentcolor;
+}
+
+.icon-link {
+ display: flex;
+ align-items: center;
+ text-decoration-color: rgba($primary, .5);
+ text-underline-offset: .5rem;
+ backface-visibility: hidden;
+
+ .bi {
+ width: 1.5em;
+ height: 1.5em;
+ transition: .2s ease-in-out transform; // stylelint-disable-line property-disallowed-list
+ }
+
+ &:hover {
+ .bi {
+ transform: translate3d(5px, 0, 0);
+ }
+ }
+}
+
+.border-lg-start {
+ @include media-breakpoint-up(lg) {
+ border-left: $border-width solid $border-color;
+ }
+}
diff --git a/site/assets/scss/_layout.scss b/site/assets/scss/_layout.scss
index f83cf094c9..d0482d9b71 100644
--- a/site/assets/scss/_layout.scss
+++ b/site/assets/scss/_layout.scss
@@ -1,16 +1,14 @@
+.bd-gutter {
+ --bs-gutter-x: #{$bd-gutter-x};
+}
+
.bd-layout {
- padding-right: $bd-gutter-x;
- padding-left: $bd-gutter-x;
- @include media-breakpoint-up(md) {
+ @include media-breakpoint-up(lg) {
display: grid;
grid-template-areas: "sidebar main";
- grid-template-columns: 1fr 3fr;
- gap: $grid-gutter-width;
- }
-
- @include media-breakpoint-up(lg) {
grid-template-columns: 1fr 5fr;
+ gap: $grid-gutter-width;
}
}
@@ -21,6 +19,11 @@
.bd-main {
grid-area: main;
+ @include media-breakpoint-down(lg) {
+ max-width: 760px;
+ margin-inline: auto;
+ }
+
@include media-breakpoint-up(md) {
display: grid;
grid-template-areas:
diff --git a/site/assets/scss/_masthead.scss b/site/assets/scss/_masthead.scss
index 2e742e76d1..42ad0f3853 100644
--- a/site/assets/scss/_masthead.scss
+++ b/site/assets/scss/_masthead.scss
@@ -1,38 +1,87 @@
.bd-masthead {
+ --bd-pink-rgb: #{to-rgb($pink)};
padding: 3rem 0;
- background: linear-gradient(165deg, tint-color($bd-purple-light, 85%) 50%, $white 50%);
+ // stylelint-disable
+ background-image: linear-gradient(180deg, rgba(var(--bs-body-bg-rgb), .01), rgba(var(--bs-body-bg-rgb), 1) 85%),
+ radial-gradient(ellipse at top left, rgba(var(--bs-primary-rgb), .5), transparent 50%),
+ radial-gradient(ellipse at top right, rgba(var(--bd-accent-rgb), .5), transparent 50%),
+ radial-gradient(ellipse at center right, rgba(var(--bd-violet-rgb), .5), transparent 50%),
+ radial-gradient(ellipse at center left, rgba(var(--bd-pink-rgb), .5), transparent 50%);
+ // stylelint-enable
h1 {
@include font-size(4rem);
line-height: 1;
}
- p:not(.lead) {
+ .lead {
+ @include font-size(1rem);
+ font-weight: 400;
color: $gray-700;
}
- .btn {
- padding: .8rem 2rem;
- font-weight: 600;
+ .highlight {
+ padding: .5rem 4rem .5rem 1rem;
+ margin-bottom: 0;
+ line-height: 1.25;
+ background-color: rgba(var(--bs-body-color-rgb), .075);
+ @include border-radius(.5rem);
+ }
+ .btn-clipboard {
+ margin-top: .4rem;
+ background-color: transparent;
+ }
+
+ #carbonads { // stylelint-disable-line selector-max-id
+ margin-right: auto;
+ margin-left: auto;
}
+
+ @include media-breakpoint-up(md) {
+ .lead {
+ @include font-size(1.5rem);
+ }
+ }
+}
+
+.masthead-followup {
.lead {
- @include font-size(1.5rem);
- font-weight: 400;
- color: $gray-700;
+ @include font-size(1rem);
+ }
+
+ .highlight {
+ @include border-radius(.5rem);
+ }
+
+ @include media-breakpoint-up(md) {
+ .lead {
+ @include font-size(1.25rem);
+ }
}
}
-@include media-breakpoint-up(md) {
- .mw-md-75 { max-width: 75%; }
+.bd-btn-lg {
+ padding: .8rem 2rem;
}
.masthead-followup-icon {
- padding: .75rem;
- background-image: linear-gradient(to bottom right, rgba(255, 255, 255, .2), rgba(255, 255, 255, .01));
- @include border-radius(.75rem);
- box-shadow: 0 .125rem .25rem rgba(0, 0, 0, .1);
+ padding: 1rem;
+ color: rgba(var(--bg-rgb), 1);
+ background-color: rgba(var(--bg-rgb), .1);
+ background-blend-mode: multiple;
+ @include border-radius(1rem);
+ mix-blend-mode: darken;
+
+ svg {
+ filter: drop-shadow(0 1px 1px #fff);
+ }
}
.masthead-followup-svg {
filter: drop-shadow(0 1px 0 rgba(0, 0, 0, .125));
}
+
+.masthead-notice {
+ background-color: var(--bd-accent);
+ box-shadow: inset 0 -1px 1px rgba(var(--bs-body-color-rgb), .15), 0 .25rem 1.5rem rgba(var(--bs-body-bg-rgb), .75);
+}
diff --git a/site/assets/scss/_navbar.scss b/site/assets/scss/_navbar.scss
index 401731ae19..4f9f3f8290 100644
--- a/site/assets/scss/_navbar.scss
+++ b/site/assets/scss/_navbar.scss
@@ -1,44 +1,85 @@
.bd-navbar {
- --bs-gutter-x: $bd-gutter-x;
- --bs-gutter-y: $bd-gutter-x;
-
padding: .75rem 0;
- background-color: $bd-violet;
+ background-color: transparent;
+ background-image: linear-gradient(to bottom, rgba(var(--bd-violet-rgb), 1), rgba(var(--bd-violet-rgb), .95));
+ box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .15), inset 0 -1px 0 rgba(0, 0, 0, .15);
.navbar-toggler {
padding: 0;
+ margin-right: -.5rem;
border: 0;
+
+ &:first-child {
+ margin-left: -.5rem;
+ }
+
+ .bi {
+ width: 1.5rem;
+ height: 1.5rem;
+ }
+
+ &:focus {
+ box-shadow: none;
+ }
}
- .navbar-nav {
- .nav-link {
- padding-right: $spacer * .25;
- padding-left: $spacer * .25;
- color: rgba($white, .85);
+ .navbar-brand {
+ transition: .2s ease-in-out transform; // stylelint-disable-line property-disallowed-list
+
+ &:hover {
+ transform: rotate(-5deg) scale(1.1);
+ }
+ }
- &:hover,
- &:focus {
- color: $white;
- }
+ .navbar-toggler,
+ .nav-link {
+ padding-right: $spacer * .25;
+ padding-left: $spacer * .25;
+ color: rgba($white, .85);
- &.active {
- font-weight: 600;
- color: $white;
- }
+ &:hover,
+ &:focus {
+ color: $white;
+ }
+
+ &.active {
+ font-weight: 600;
+ color: $white;
}
}
.navbar-nav-svg {
- width: 1rem;
- height: 1rem;
+ display: inline-block;
+ vertical-align: -.125rem;
}
- .offcanvas {
- background-color: $bd-violet;
+ .offcanvas-lg {
+ background-color: var(--bd-violet);
border-left: 0;
- @include media-breakpoint-down(md) {
+ @include media-breakpoint-down(lg) {
box-shadow: $box-shadow-lg;
}
}
+
+ .dropdown-toggle {
+ &:focus {
+ outline: 0;
+ }
+ }
+
+ .dropdown-menu {
+ --#{$variable-prefix}dropdown-min-width: 12rem;
+ --#{$variable-prefix}dropdown-link-hover-bg: rgba(var(--bd-violet-rgb), .1);
+ @include rfs(.875rem, --#{$variable-prefix}dropdown-font-size);
+ box-shadow: $dropdown-box-shadow;
+ }
+
+ .dropdown-item.current {
+ font-weight: 600;
+ background-image: escape-svg($dropdown-active-icon);
+ background-repeat: no-repeat;
+ background-position: right $dropdown-item-padding-x top .6rem;
+ background-size: .75rem .75rem;
+ }
}
diff --git a/site/assets/scss/_search.scss b/site/assets/scss/_search.scss
new file mode 100644
index 0000000000..1825337a00
--- /dev/null
+++ b/site/assets/scss/_search.scss
@@ -0,0 +1,62 @@
+.bd-search {
+ position: relative;
+ width: 100%;
+
+ &::after {
+ position: absolute;
+ top: .4rem;
+ right: .4rem;
+ bottom: .4rem;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding-right: .3125rem;
+ padding-left: .3125rem;
+ @include font-size(.75rem);
+ color: rgba($white, .65);
+ // content: "⌘K";
+ content: attr(data-shortcut);
+ background-color: rgba($white, .1);
+ @include border-radius(.125rem);
+ }
+
+ @include media-breakpoint-up(lg) {
+ position: absolute;
+ top: .75rem;
+ left: 50%;
+ width: 200px;
+ margin-left: -100px;
+ }
+
+ @include media-breakpoint-up(xl) {
+ width: 280px;
+ margin-left: -140px;
+ }
+
+ .form-control {
+ padding-right: 2.75rem;
+ color: $white;
+ background-color: rgba($black, .1);
+ border-color: rgba($white, .4);
+ transition-property: background-color, border-color, box-shadow;
+
+ &::placeholder {
+ color: rgba($white, .65);
+ }
+
+ &::-webkit-search-cancel-button {
+ appearance: none;
+ width: 1rem;
+ height: 1rem;
+ cursor: pointer;
+ background: escape-svg($search-clear-icon) no-repeat 0 0;
+ background-size: 100% 100%;
+ }
+
+ &:focus {
+ background-color: rgba($black, .25);
+ border-color: rgba($bd-accent, 1);
+ box-shadow: 0 0 0 .25rem rgba($bd-accent, .4);
+ }
+ }
+}
diff --git a/site/assets/scss/_sidebar.scss b/site/assets/scss/_sidebar.scss
index 452b155ffa..ed76b3ca82 100644
--- a/site/assets/scss/_sidebar.scss
+++ b/site/assets/scss/_sidebar.scss
@@ -1,87 +1,53 @@
.bd-sidebar {
- @include media-breakpoint-down(md) {
- margin: 0 ($bd-gutter-x * -1) 1rem;
- }
-}
-
-.bd-links {
- overflow: auto;
- font-weight: 600;
-
- @include media-breakpoint-up(md) {
+ @include media-breakpoint-up(lg) {
position: sticky;
top: 5rem;
// Override collapse behaviors
// stylelint-disable-next-line declaration-no-important
display: block !important;
- height: subtract(100vh, 7rem);
+ height: subtract(100vh, 6rem);
// Prevent focus styles to be cut off:
padding-left: .25rem;
margin-left: -.25rem;
overflow-y: auto;
}
+}
- > ul {
- @include media-breakpoint-down(md) {
- padding: 1.5rem .75rem;
- background-color: $gray-100;
- border-bottom: 1px solid $gray-200;
- }
- }
-
- a {
- padding: .1875rem .5rem;
- margin-top: .125rem;
- margin-left: 1.25rem;
- color: rgba($black, .65);
- text-decoration: if($link-decoration == none, null, none);
-
- &:hover,
- &:focus {
- color: rgba($black, .85);
- text-decoration: if($link-hover-decoration == underline, none, null);
- background-color: rgba($bd-violet, .1);
- }
+.bd-links-nav {
+ @include media-breakpoint-down(lg) {
+ font-size: .875rem;
}
- .btn {
- // Custom styles (as we don't have a completely neutral button style)
- padding: .25rem .5rem;
- font-weight: 600;
- color: rgba($black, .65);
- background-color: transparent;
- border: 0;
+ @include media-breakpoint-between(xs, lg) {
+ column-count: 2;
+ column-gap: 1.5rem;
- &:hover,
- &:focus {
- color: rgba($black, .85);
- background-color: rgba($bd-violet, .1);
+ .bd-links-group {
+ break-inside: avoid;
}
- &:focus {
- box-shadow: 0 0 0 1px rgba($bd-violet, .7);
- }
-
- // Add chevron if there's a submenu
- &::before {
- width: 1.25em;
- line-height: 0; // Align in the middle
- content: escape-svg($sidebar-collapse-icon);
- @include transition(transform .35s ease);
- transform-origin: .5em 50%;
+ .bd-links-span-all {
+ column-span: all;
}
+ }
+}
- &[aria-expanded="true"] {
- color: rgba($black, .85);
+.bd-links-link {
+ padding: .1875rem .5rem;
+ margin-top: .125rem;
+ margin-left: 1rem;
+ color: rgba($black, .65);
+ text-decoration: if($link-decoration == none, null, none);
- &::before {
- transform: rotate(90deg);
- }
- }
+ &:hover,
+ &:focus,
+ &.active {
+ color: rgba($black, .85);
+ text-decoration: if($link-hover-decoration == underline, none, null);
+ background-color: rgba(var(--bd-violet-rgb), .1);
}
- .active {
+ &.active {
font-weight: 600;
- color: rgba($black, .85);
}
}
diff --git a/site/assets/scss/_subnav.scss b/site/assets/scss/_subnav.scss
deleted file mode 100644
index db183ff6a8..0000000000
--- a/site/assets/scss/_subnav.scss
+++ /dev/null
@@ -1,82 +0,0 @@
-.bd-subnavbar {
- --bs-gutter-x: $bd-gutter-x;
- --bs-gutter-y: $bd-gutter-x;
-
- // The position and z-index are needed for the dropdown to stay on top of the content
- position: relative;
- z-index: $zindex-sticky;
- background-color: rgba($white, .95);
- box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .05), inset 0 -1px 0 rgba(0, 0, 0, .15);
-
- .dropdown-menu {
- @include font-size(.875rem);
- box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .05);
- }
-
- .dropdown-item.current {
- font-weight: 600;
- background-image: escape-svg($dropdown-active-icon);
- background-repeat: no-repeat;
- background-position: right $dropdown-item-padding-x top .6rem;
- background-size: .75rem .75rem;
- }
-
- @include media-breakpoint-up(md) {
- position: sticky;
- top: 0;
- }
-}
-
-.bd-search {
- position: relative;
-
- &::after {
- position: absolute;
- top: .4rem;
- right: .4rem;
- bottom: .4rem;
- display: flex;
- align-items: center;
- justify-content: center;
- padding-right: .3125rem;
- padding-left: .3125rem;
- @include font-size(.75rem);
- color: $gray-600;
- content: "Ctrl + /";
- background-color: $gray-100;
- @include border-radius(.125rem);
- }
-
- @include media-breakpoint-down(md) {
- width: 100%;
- }
-
- .form-control {
- padding-right: 3.75rem;
-
- &:focus {
- border-color: $bd-violet;
- box-shadow: 0 0 0 3px rgba($bd-violet, .25);
- }
- }
-}
-
-.bd-sidebar-toggle {
- color: $text-muted;
-
- &:hover,
- &:focus {
- color: $bd-violet;
- }
-
- &:focus {
- box-shadow: 0 0 0 3px rgba($bd-violet, .25);
- }
-
- .bi-collapse { display: none; }
-
- &:not(.collapsed) {
- .bi-expand { display: none; }
- .bi-collapse { display: inline-block; }
- }
-}
diff --git a/site/assets/scss/_syntax.scss b/site/assets/scss/_syntax.scss
index 54f0cdaaa8..662f70dc4d 100644
--- a/site/assets/scss/_syntax.scss
+++ b/site/assets/scss/_syntax.scss
@@ -101,7 +101,7 @@
.language-bash,
.language-sh {
&::before {
- color: #009;
+ color: #777;
content: "$ ";
user-select: none;
}
diff --git a/site/assets/scss/_toc.scss b/site/assets/scss/_toc.scss
index 596945628e..512a11b420 100644
--- a/site/assets/scss/_toc.scss
+++ b/site/assets/scss/_toc.scss
@@ -15,6 +15,7 @@
ul {
padding-left: 0;
+ margin-bottom: 0;
list-style: none;
ul {
@@ -40,3 +41,47 @@
}
}
}
+
+.bd-toc-toggle {
+ display: flex;
+ align-items: center;
+
+ @include media-breakpoint-down(sm) {
+ justify-content: space-between;
+ width: 100%;
+ }
+
+ @include media-breakpoint-down(md) {
+ border: 1px solid $border-color;
+ @include border-radius(.4rem);
+
+ &:hover,
+ &:focus,
+ &:active,
+ &[aria-expanded="true"] {
+ color: var(--bd-violet);
+ background-color: $white;
+ border-color: var(--bd-violet);
+ }
+
+ &:focus,
+ &[aria-expanded="true"] {
+ box-shadow: 0 0 0 3px rgba(var(--bd-violet-rgb), .25);
+ }
+ }
+}
+
+.bd-toc-collapse {
+ @include media-breakpoint-down(md) {
+ nav {
+ padding: 1.25rem;
+ background-color: var(--bs-gray-100);
+ border: 1px solid $border-color;
+ @include border-radius(.25rem);
+ }
+ }
+
+ @include media-breakpoint-up(md) {
+ display: block !important; // stylelint-disable-line declaration-no-important
+ }
+}
diff --git a/site/assets/scss/_variables.scss b/site/assets/scss/_variables.scss
index 0c40b17e9e..8f74f94d0b 100644
--- a/site/assets/scss/_variables.scss
+++ b/site/assets/scss/_variables.scss
@@ -1,17 +1,15 @@
// stylelint-disable scss/dollar-variable-default
// Local docs variables
-$bd-purple: #563d7c;
+$bd-purple: #4c0bce;
$bd-violet: lighten(saturate($bd-purple, 5%), 15%); // stylelint-disable-line function-disallowed-list
$bd-purple-light: lighten(saturate($bd-purple, 5%), 45%); // stylelint-disable-line function-disallowed-list
$bd-accent: #ffe484;
-$bd-info: #5bc0de;
-$bd-warning: #f0ad4e;
-$bd-danger: #d9534f;
$dropdown-active-icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'><path fill='#292b2c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/></svg>");
-$sidebar-collapse-icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path fill='none' stroke='rgba(0,0,0,.5)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 14l6-6-6-6'/></svg>");
+$search-clear-icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path fill='rgba(255,255,255,.75)' d='M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM5.354 4.646a.5.5 0 1 0-.708.708L7.293 8l-2.647 2.646a.5.5 0 0 0 .708.708L8 8.707l2.646 2.647a.5.5 0 0 0 .708-.708L8.707 8l2.647-2.646a.5.5 0 0 0-.708-.708L8 7.293 5.354 4.646z'/></svg>");
-$bd-gutter-x: 1.25rem;
+$bd-gutter-x: 3rem;
+$bd-callout-variants: info, warning, danger !default;
:root {
--bd-purple: #{$bd-purple};
@@ -19,4 +17,6 @@ $bd-gutter-x: 1.25rem;
--bd-accent: #{$bd-accent};
--bd-violet-rgb: #{to-rgb($bd-violet)};
--bd-accent-rgb: #{to-rgb($bd-accent)};
+ --bd-pink-rgb: #{to-rgb($pink-500)};
+ --bd-teal-rgb: #{to-rgb($teal-500)};
}
diff --git a/site/assets/scss/docs.scss b/site/assets/scss/docs.scss
index 0029e83af9..f1390e2fae 100644
--- a/site/assets/scss/docs.scss
+++ b/site/assets/scss/docs.scss
@@ -37,7 +37,7 @@ $enable-cssgrid: true; // stylelint-disable-line scss/dollar-variable-default
// Load docs components
@import "variables";
@import "navbar";
-@import "subnav";
+@import "search";
@import "masthead";
@import "ads";
@import "content";
diff --git a/site/content/docs/5.1/components/offcanvas.md b/site/content/docs/5.1/components/offcanvas.md
index 7a8cbc68a7..6ad9b6e893 100644
--- a/site/content/docs/5.1/components/offcanvas.md
+++ b/site/content/docs/5.1/components/offcanvas.md
@@ -137,9 +137,54 @@ When backdrop is set to static, the offcanvas will not close when clicking outsi
</div>
{{< /example >}}
+## Responsive
+
+<small class="d-inline-flex px-2 py-1 fw-semibold text-success bg-success bg-opacity-10 rounded-2">Added in v5.2.0</small>
+
+Responsive offcanvas classes hide content outside the viewport from a specified breakpoint and down. Above that breakpoint, the contents within will behave as usual. For example, `.offcanvas-lg` hides content in an offcanvas below the `lg` breakpoint, but shows the content above the `lg` breakpoint.
+
+<div class="bd-example">
+ <button class="btn btn-primary d-lg-none" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasResponsive" aria-controls="offcanvasResponsive">Toggle offcanvas</button>
+
+ <div class="alert alert-info d-none d-lg-block">Resize your browser to show the responsive offcanvas toggle.</div>
+
+ <div class="offcanvas-lg offcanvas-end" tabindex="-1" id="offcanvasResponsive" aria-labelledby="offcanvasResponsiveLabel">
+ <div class="offcanvas-header">
+ <h5 class="offcanvas-title" id="offcanvasResponsiveLabel">Responsive offcanvas</h5>
+ <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
+ </div>
+ <div class="offcanvas-body">
+ <p class="mb-0">This is content within an <code>.offcanvas-lg</code>.</p>
+ </div>
+ </div>
+</div>
+
+```html
+<button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasResponsive" aria-controls="offcanvasResponsive">Toggle offcanvas</button>
+
+<div class="offcanvas-lg offcanvas-end" tabindex="-1" id="offcanvasResponsive" aria-labelledby="offcanvasResponsiveLabel">
+ <div class="offcanvas-header">
+ <h5 class="offcanvas-title" id="offcanvasResponsiveLabel">Responsive offcanvas</h5>
+ <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
+ </div>
+ <div class="offcanvas-body">
+ <p class="mb-0">This is content within an <code>.offcanvas-lg</code>.</p>
+ </div>
+</div>
+```
+
+Responsive offcanvas classes are available across for each breakpoint.
+
+- `.offcanvas`
+- `.offcanvas-sm`
+- `.offcanvas-md`
+- `.offcanvas-lg`
+- `.offcanvas-xl`
+- `.offcanvas-xxl`
+
## Placement
-There's no default placement for offcanvas components, so you must add one of the modifier classes below;
+There's no default placement for offcanvas components, so you must add one of the modifier classes below.
- `.offcanvas-start` places offcanvas on the left of the viewport (shown above)
- `.offcanvas-end` places offcanvas on the right of the viewport
@@ -194,10 +239,18 @@ Try the top, right, and bottom examples out below.
Since the offcanvas panel is conceptually a modal dialog, be sure to add `aria-labelledby="..."`—referencing the offcanvas title—to `.offcanvas`. Note that you don’t need to add `role="dialog"` since we already add it via JavaScript.
-## Sass
+## CSS
### Variables
+<small class="d-inline-flex px-2 py-1 fw-semibold text-success bg-success bg-opacity-10 rounded-2">Added in v5.2.0</small>
+
+As part of Bootstrap's evolving CSS variables approach, offcanvas now uses local CSS variables on `.offcanvas` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too.
+
+{{< scss-docs name="offcanvas-css-vars" file="scss/_offcanvas.scss" >}}
+
+### Sass variables
+
{{< scss-docs name="offcanvas-variables" file="scss/_variables.scss" >}}
## Usage
diff --git a/site/content/docs/5.1/examples/_index.md b/site/content/docs/5.1/examples/_index.md
index 3d5bfab2fb..39102f3646 100644
--- a/site/content/docs/5.1/examples/_index.md
+++ b/site/content/docs/5.1/examples/_index.md
@@ -7,30 +7,39 @@ aliases: "/examples/"
{{< list-examples.inline >}}
{{ range $entry := $.Site.Data.examples -}}
- <h2 id="{{ $entry.category | urlize }}">{{ $entry.category }}</h2>
- <p>{{ $entry.description }}</p>
- {{ if eq $entry.category "RTL" -}}
- <div class="bd-callout bd-callout-warning">
- <p>The RTL feature is still <strong>experimental</strong> and will probably evolve according to user feedback. Spotted something or have an improvement to suggest? <a href="{{ $.Site.Params.repo }}/issues/new">Open an issue</a>, we'd love to get your insights.</p>
- </div>
- {{ end -}}
-
- {{ range $i, $example := $entry.examples -}}
- {{- $len := len $entry.examples -}}
- {{ if (eq $i 0) }}<div class="row">{{ end }}
- <div class="col-sm-6 col-md-4 col-xl-3 mb-3">
- <a class="d-block" href="/docs/{{ $.Site.Params.docs_version }}/examples/{{ $example.name | urlize }}/"{{ if in $example.name "RTL" }} hreflang="ar"{{ end }}>
- <img class="img-thumbnail mb-3" srcset="/docs/{{ $.Site.Params.docs_version }}/assets/img/examples/{{ $example.name | urlize }}.png,
- /docs/{{ $.Site.Params.docs_version }}/assets/img/examples/{{ $example.name | urlize }}@2x.png 2x"
- src="/docs/{{ $.Site.Params.docs_version }}/assets/img/examples/{{ $example.name | urlize }}.png"
- alt=""
- width="480" height="300"
- loading="lazy">
- <h3 class="h5 mb-1">{{ $example.name }}</h3>
- </a>
- <p class="text-muted">{{ $example.description }}</p>
+<div class="row g-lg-5 mb-5">
+ <div class="col-lg-3">
+ <h2 id="{{ $entry.category | urlize }}">{{ $entry.category }}</h2>
+ <p>{{ $entry.description }}</p>
+ {{ if eq $entry.category "RTL" -}}
+ <div class="bd-callout bd-callout-warning small">
+ <p>
+ <strong>RTL is still experimental</strong> and will evolve with feedback. Spotted something or have an improvement to suggest?
+ </p>
+ <p><a href="{{ $.Site.Params.repo }}/issues/new">Please open an issue.</a></p>
</div>
- {{ if (eq (add $i 1) $len) }}</div>{{ end }}
- {{ end -}}
+ {{ end -}}
+ </div>
+
+ <div class="col-lg-9">
+ {{ range $i, $example := $entry.examples -}}
+ {{- $len := len $entry.examples -}}
+ {{ if (eq $i 0) }}<div class="row">{{ end }}
+ <div class="col-sm-6 col-md-4 mb-3">
+ <a class="d-block" href="/docs/{{ $.Site.Params.docs_version }}/examples/{{ $example.name | urlize }}/"{{ if in $example.name "RTL" }} hreflang="ar"{{ end }}>
+ <img class="img-thumbnail mb-3" srcset="/docs/{{ $.Site.Params.docs_version }}/assets/img/examples/{{ $example.name | urlize }}.png,
+ /docs/{{ $.Site.Params.docs_version }}/assets/img/examples/{{ $example.name | urlize }}@2x.png 2x"
+ src="/docs/{{ $.Site.Params.docs_version }}/assets/img/examples/{{ $example.name | urlize }}.png"
+ alt=""
+ width="480" height="300"
+ loading="lazy">
+ <h3 class="h5 mb-1">{{ $example.name }}</h3>
+ </a>
+ <p class="text-muted">{{ $example.description }}</p>
+ </div>
+ {{ if (eq (add $i 1) $len) }}</div>{{ end }}
+ {{ end -}}
+ </div>
+</div>
{{ end -}}
{{< /list-examples.inline >}}
diff --git a/site/content/docs/5.1/examples/navbars-offcanvas/index.html b/site/content/docs/5.1/examples/navbars-offcanvas/index.html
new file mode 100644
index 0000000000..47041fa011
--- /dev/null
+++ b/site/content/docs/5.1/examples/navbars-offcanvas/index.html
@@ -0,0 +1,147 @@
+---
+layout: examples
+title: Navbar Template
+extra_css:
+ - "navbar.css"
+---
+
+<main>
+ <nav class="navbar navbar-dark bg-dark" aria-label="Dark offcanvas navbar">
+ <div class="container-fluid">
+ <a class="navbar-brand" href="#">Dark offcanvas navbar</a>
+ <button class="navbar-toggler" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasNavbarDark" aria-controls="offcanvasNavbarDark">
+ <span class="navbar-toggler-icon"></span>
+ </button>
+ <div class="offcanvas offcanvas-end text-white bg-dark" tabindex="-1" id="offcanvasNavbarDark" aria-labelledby="offcanvasNavbarDarkLabel">
+ <div class="offcanvas-header">
+ <h5 class="offcanvas-title" id="offcanvasNavbarDarkLabel">Offcanvas</h5>
+ <button type="button" class="btn-close btn-close-white" data-bs-dismiss="offcanvas" aria-label="Close"></button>
+ </div>
+ <div class="offcanvas-body">
+ <ul class="navbar-nav justify-content-end flex-grow-1 pe-3">
+ <li class="nav-item">
+ <a class="nav-link active" aria-current="page" href="#">Home</a>
+ </li>
+ <li class="nav-item">
+ <a class="nav-link" href="#">Link</a>
+ </li>
+ <li class="nav-item dropdown">
+ <a class="nav-link dropdown-toggle" href="#" id="offcanvasNavbarDarkDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
+ Dropdown
+ </a>
+ <ul class="dropdown-menu" aria-labelledby="offcanvasNavbarDarkDropdown">
+ <li><a class="dropdown-item" href="#">Action</a></li>
+ <li><a class="dropdown-item" href="#">Another action</a></li>
+ <li>
+ <hr class="dropdown-divider">
+ </li>
+ <li><a class="dropdown-item" href="#">Something else here</a></li>
+ </ul>
+ </li>
+ </ul>
+ <form class="d-flex mt-3" role="search">
+ <input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
+ <button class="btn btn-outline-success" type="submit">Search</button>
+ </form>
+ </div>
+ </div>
+ </div>
+ </nav>
+
+ <nav class="navbar bg-light" aria-label="Light offcanvas navbar">
+ <div class="container-fluid">
+ <a class="navbar-brand" href="#">Light offcanvas navbar</a>
+ <button class="navbar-toggler" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasNavbarLight" aria-controls="offcanvasNavbarLight">
+ <span class="navbar-toggler-icon"></span>
+ </button>
+ <div class="offcanvas offcanvas-end" tabindex="-1" id="offcanvasNavbarLight" aria-labelledby="offcanvasNavbarLightLabel">
+ <div class="offcanvas-header">
+ <h5 class="offcanvas-title" id="offcanvasNavbarLightLabel">Offcanvas</h5>
+ <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
+ </div>
+ <div class="offcanvas-body">
+ <ul class="navbar-nav justify-content-end flex-grow-1 pe-3">
+ <li class="nav-item">
+ <a class="nav-link active" aria-current="page" href="#">Home</a>
+ </li>
+ <li class="nav-item">
+ <a class="nav-link" href="#">Link</a>
+ </li>
+ <li class="nav-item dropdown">
+ <a class="nav-link dropdown-toggle" href="#" id="offcanvasNavbarLightDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
+ Dropdown
+ </a>
+ <ul class="dropdown-menu" aria-labelledby="offcanvasNavbarLightDropdown">
+ <li><a class="dropdown-item" href="#">Action</a></li>
+ <li><a class="dropdown-item" href="#">Another action</a></li>
+ <li>
+ <hr class="dropdown-divider">
+ </li>
+ <li><a class="dropdown-item" href="#">Something else here</a></li>
+ </ul>
+ </li>
+ </ul>
+ <form class="d-flex mt-3" role="search">
+ <input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
+ <button class="btn btn-outline-success" type="submit">Search</button>
+ </form>
+ </div>
+ </div>
+ </div>
+ </nav>
+
+ <nav class="navbar navbar-expand-lg navbar-dark bg-dark" aria-label="Offcanvas navbar large">
+ <div class="container-fluid">
+ <a class="navbar-brand" href="#">Responsive offcanvas navbar</a>
+ <button class="navbar-toggler" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasNavbar2" aria-controls="offcanvasNavbar2">
+ <span class="navbar-toggler-icon"></span>
+ </button>
+ <div class="offcanvas offcanvas-end text-white bg-dark" tabindex="-1" id="offcanvasNavbar2" aria-labelledby="offcanvasNavbar2Label">
+ <div class="offcanvas-header">
+ <h5 class="offcanvas-title" id="offcanvasNavbar2Label">Offcanvas</h5>
+ <button type="button" class="btn-close btn-close-white" data-bs-dismiss="offcanvas" aria-label="Close"></button>
+ </div>
+ <div class="offcanvas-body">
+ <ul class="navbar-nav justify-content-end flex-grow-1 pe-3">
+ <li class="nav-item">
+ <a class="nav-link active" aria-current="page" href="#">Home</a>
+ </li>
+ <li class="nav-item">
+ <a class="nav-link" href="#">Link</a>
+ </li>
+ <li class="nav-item dropdown">
+ <a class="nav-link dropdown-toggle" href="#" id="offcanvasNavbarLgDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
+ Dropdown
+ </a>
+ <ul class="dropdown-menu" aria-labelledby="offcanvasNavbarLgDropdown">
+ <li><a class="dropdown-item" href="#">Action</a></li>
+ <li><a class="dropdown-item" href="#">Another action</a></li>
+ <li>
+ <hr class="dropdown-divider">
+ </li>
+ <li><a class="dropdown-item" href="#">Something else here</a></li>
+ </ul>
+ </li>
+ </ul>
+ <form class="d-flex mt-3 mt-lg-0" role="search">
+ <input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
+ <button class="btn btn-outline-success" type="submit">Search</button>
+ </form>
+ </div>
+ </div>
+ </div>
+ </nav>
+
+ <div class="container my-5">
+ <div class="bg-light p-5 rounded">
+ <div class="col-sm-8 py-5 mx-auto">
+ <h1 class="display-5 fw-normal">Navbar with offcanvas examples</h1>
+ <p class="fs-5">This example shows how responsive offcanvas menus work within the navbar. For positioning of navbars, checkout the <a href="{{< docsref "/examples/navbar-static" >}}">top</a> and <a href="{{< docsref "/examples/navbar-fixed" >}}">fixed top</a> examples.</p>
+ <p>From the top down, you'll see a dark navbar, light navbar and a responsive navbar—each with offcanvases built in. Resize your browser window to the large breakpoint to see the toggle for the offcanvas.</p>
+ <p>
+ <a class="btn btn-primary" href="{{< docsref "/components/navbar#offcanvas" >}}" role="button">Learn more about offcanvas navbars &raquo;</a>
+ </p>
+ </div>
+ </div>
+ </div>
+</main>
diff --git a/site/content/docs/5.1/examples/navbars-offcanvas/navbar.css b/site/content/docs/5.1/examples/navbars-offcanvas/navbar.css
new file mode 100644
index 0000000000..70d209409d
--- /dev/null
+++ b/site/content/docs/5.1/examples/navbars-offcanvas/navbar.css
@@ -0,0 +1,7 @@
+body {
+ padding-bottom: 20px;
+}
+
+.navbar {
+ margin-bottom: 20px;
+}
diff --git a/site/content/docs/5.1/utilities/api.md b/site/content/docs/5.1/utilities/api.md
index 16270ad511..86cf329381 100644
--- a/site/content/docs/5.1/utilities/api.md
+++ b/site/content/docs/5.1/utilities/api.md
@@ -11,7 +11,7 @@ Bootstrap utilities are generated with our utility API and can be used to modify
The `$utilities` map contains all our utilities and is later merged with your custom `$utilities` map, if present. The utility map contains a keyed list of utility groups which accept the following options:
-{{< bs-table "table text-start" >}}
+{{< bs-table "table table-utilities" >}}
| Option | Type | Default&nbsp;value | Description |
| --- | --- | --- | --- |
| [`property`](#property) | **Required** | – | Name of the property, this can be a string or an array of strings (e.g., horizontal paddings or margins). |
diff --git a/site/content/docs/5.1/utilities/spacing.md b/site/content/docs/5.1/utilities/spacing.md
index 70fbe76945..1e5f6d32f4 100644
--- a/site/content/docs/5.1/utilities/spacing.md
+++ b/site/content/docs/5.1/utilities/spacing.md
@@ -10,7 +10,9 @@ toc: true
Assign responsive-friendly `margin` or `padding` values to an element or a subset of its sides with shorthand classes. Includes support for individual properties, all properties, and vertical and horizontal properties. Classes are built from a default Sass map ranging from `.25rem` to `3rem`.
-Using the CSS Grid layout module? Consider using [the gap utility](#gap).
+{{< callout >}}
+**Using the CSS Grid layout module?** Consider using [the gap utility](#gap) instead.
+{{< /callout >}}
### Notation
diff --git a/site/data/examples.yml b/site/data/examples.yml
index 6d6419d218..38644ef4a0 100644
--- a/site/data/examples.yml
+++ b/site/data/examples.yml
@@ -63,6 +63,8 @@
examples:
- name: Navbars
description: "Demonstration of all responsive and container options for the navbar."
+ - name: Navbars offcanvas
+ description: "Same as the Navbars example, but with our offcanvas component."
- name: Navbar static
description: "Single navbar example of a static top navbar along with some additional content."
- name: Navbar fixed
diff --git a/site/data/plugins.yml b/site/data/plugins.yml
new file mode 100644
index 0000000000..22cec9877b
--- /dev/null
+++ b/site/data/plugins.yml
@@ -0,0 +1,47 @@
+- name: Alert
+ description: Show and hide alert messages to your users.
+ link: components/alerts/#javascript-behavior
+
+- name: Button
+ description: Programmatically control the active state for buttons.
+ link: components/buttons/#button-plugin
+
+- name: Carousel
+ description: Add slideshows to any page, including support for crossfade.
+ link: components/carousel/
+
+- name: Collapse
+ description: Expand and collapse areas of content, or create accordions.
+ link: components/collapse/
+
+- name: Dropdown
+ description: Create menus of links, actions, forms, and more.
+ link: components/dropdowns/
+
+- name: Modal
+ description: Add flexible and responsive dialogs to your project.
+ link: components/modal/
+
+- name: Offcanvas
+ description: Build and toggle hidden sidebars into any page.
+ link: components/offcanvas/
+
+- name: Popover
+ description: Create custom overlays. Built on Popper.js.
+ link: components/popovers/
+
+- name: Scrollspy
+ description: Automatically update active nav links based on page scroll.
+ link: components/scrollspy/
+
+- name: Tab
+ description: Allow Bootstrap nav components to toggle contents.
+ link: components/navs-tabs/
+
+- name: Toast
+ description: Show and hide notifications to your visitors.
+ link: components/toasts/
+
+- name: Tooltip
+ description: Replace browser tooltips with custom ones. Built on Popper.js.
+ link: components/tooltips/
diff --git a/site/data/sidebar.yml b/site/data/sidebar.yml
index 8aad6027bf..eb03285c5f 100644
--- a/site/data/sidebar.yml
+++ b/site/data/sidebar.yml
@@ -2,6 +2,8 @@
# The logic for the sidebar generation is in "site/layouts/partials/docs-sidebar.html".
- title: Getting started
+ icon: book-half
+ icon_color: indigo
pages:
- title: Introduction
- title: Download
@@ -16,6 +18,8 @@
- title: Contribute
- title: Customize
+ icon: palette2
+ icon_color: pink
pages:
- title: Overview
- title: Sass
@@ -26,6 +30,8 @@
- title: Optimize
- title: Layout
+ icon: grid-fill
+ icon_color: teal
pages:
- title: Breakpoints
- title: Containers
@@ -37,6 +43,8 @@
- title: CSS Grid
- title: Content
+ icon: file-earmark-richtext
+ icon_color: gray
pages:
- title: Reboot
- title: Typography
@@ -45,6 +53,8 @@
- title: Figures
- title: Forms
+ icon: ui-radios
+ icon_color: blue
pages:
- title: Overview
- title: Form control
@@ -57,6 +67,8 @@
- title: Validation
- title: Components
+ icon: menu-button-wide-fill
+ icon_color: cyan
pages:
- title: Accordion
- title: Alerts
@@ -84,6 +96,8 @@
- title: Tooltips
- title: Helpers
+ icon: magic
+ icon_color: orange
pages:
- title: Clearfix
- title: Colored links
@@ -96,6 +110,8 @@
- title: Vertical rule
- title: Utilities
+ icon: braces-asterisk
+ icon_color: red
pages:
- title: API
- title: Background
@@ -116,11 +132,15 @@
- title: Visibility
- title: Extend
+ icon: tools
+ icon_color: blue
pages:
- title: Approach
- title: Icons
- title: About
+ icon: globe2
+ icon_color: indigo
pages:
- title: Overview
- title: Team
diff --git a/site/layouts/_default/baseof.html b/site/layouts/_default/baseof.html
index 713ab2864a..fdf19b31f0 100644
--- a/site/layouts/_default/baseof.html
+++ b/site/layouts/_default/baseof.html
@@ -5,6 +5,7 @@
</head>
{{ block "body_override" . }}<body>{{ end }}
{{ partial "skippy" . }}
+ {{ partial "icons" . }}
{{ partial "docs-navbar" . }}
diff --git a/site/layouts/_default/docs.html b/site/layouts/_default/docs.html
index dd063c5dc8..3c61cd3421 100644
--- a/site/layouts/_default/docs.html
+++ b/site/layouts/_default/docs.html
@@ -1,29 +1,45 @@
{{ define "main" }}
- {{ partial "docs-subnav" . }}
-
- <div class="container-xxl my-md-4 bd-layout">
+ <div class="container-xxl bd-gutter mt-3 my-md-4 bd-layout">
<aside class="bd-sidebar">
- {{ partial "docs-sidebar" . }}
+ <div class="offcanvas-lg offcanvas-start" id="bdSidebar" aria-labelledby="bdSidebarOffcanvasLabel">
+ <div class="offcanvas-header border-bottom">
+ <h5 class="offcanvas-title" id="bdSidebarOffcanvasLabel">Browse docs</h5>
+ <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close" data-bs-target="#bdSidebar"></button>
+ </div>
+
+ <div class="offcanvas-body">
+ {{ partial "docs-sidebar" . }}
+ </div>
+ </div>
</aside>
<main class="bd-main order-1">
- <div class="bd-intro ps-lg-4">
+ <div class="bd-intro pt-2 ps-lg-2">
<div class="d-md-flex flex-md-row-reverse align-items-center justify-content-between">
- <a class="btn btn-sm btn-bd-light mb-2 mb-md-0" href="{{ .Site.Params.repo }}/blob/main/site/content/{{ .Page.File.Path | replaceRE `\\` "/" }}" title="View and edit this file on GitHub" target="_blank" rel="noopener">View on GitHub</a>
- <h1 class="bd-title" id="content">{{ .Title | markdownify }}</h1>
+ <a class="btn btn-sm btn-bd-light mb-3 mb-md-0 rounded-2" href="{{ .Site.Params.repo }}/blob/main/site/content/{{ .Page.File.Path | replaceRE `\\` "/" }}" title="View and edit this file on GitHub" target="_blank" rel="noopener">
+ View on GitHub
+ </a>
+ <h1 class="bd-title mb-0" id="content">{{ .Title | markdownify }}</h1>
</div>
<p class="bd-lead">{{ .Page.Params.Description | markdownify }}</p>
{{ partial "ads" . }}
</div>
{{ if (eq .Page.Params.toc true) }}
- <div class="bd-toc mt-4 mb-5 my-md-0 ps-xl-3 mb-lg-5 text-muted">
- <strong class="d-block h6 my-2 pb-2 border-bottom">On this page</strong>
- {{ .TableOfContents }}
+ <div class="bd-toc mt-3 mb-5 my-lg-0 ps-xl-3 mb-lg-5 text-muted">
+ <button class="btn btn-link link-dark p-md-0 mb-2 mb-md-0 text-decoration-none bd-toc-toggle d-md-none" type="button" data-bs-toggle="collapse" data-bs-target="#tocContents" aria-expanded="false" aria-controls="tocContents">
+ On this page
+ <svg class="bi d-md-none ms-2" aria-hidden="true"><use xlink:href="#chevron-expand"></use></svg>
+ </button>
+ <strong class="d-none d-md-block h6 my-2">On this page</strong>
+ <hr class="d-none d-md-block my-2">
+ <div class="collapse bd-toc-collapse" id="tocContents">
+ {{ .TableOfContents }}
+ </div>
</div>
{{ end }}
- <div class="bd-content ps-lg-4">
+ <div class="bd-content ps-lg-2">
{{ if .Page.Params.sections }}
<div class="row g-3">
{{ range .Page.Params.sections }}
diff --git a/site/layouts/_default/single.html b/site/layouts/_default/single.html
index 8ba99c7188..ae1a41faa7 100644
--- a/site/layouts/_default/single.html
+++ b/site/layouts/_default/single.html
@@ -1,14 +1,19 @@
{{ define "main" }}
<header class="py-5 border-bottom">
- <div class="container pt-md-1 pb-md-4">
+ <div class="container-xxl bd-gutter pt-md-1 pb-md-4">
<div class="row">
<div class="col-xl-8">
<h1 class="bd-title mt-0">{{ .Title | markdownify }}</h1>
<p class="bd-lead">{{ .Page.Params.Description | markdownify }}</p>
{{ if eq .Title "Examples" }}
- <div class="d-flex flex-column flex-sm-row">
- <a href="{{ .Site.Params.download.dist_examples }}" class="btn btn-lg btn-bd-primary" onclick="ga('send', 'event', 'Examples', 'Hero', 'Download Examples');">Download examples</a>
- <a href="{{ .Site.Params.download.source }}" class="btn btn-lg btn-outline-secondary mt-3 mt-sm-0 ms-sm-3" onclick="ga('send', 'event', 'Examples', 'Hero', 'Download');">Download source code</a>
+ <div class="d-flex flex-column flex-md-row gap-3">
+ <a href="{{ .Site.Params.download.dist_examples }}" class="btn btn-lg bd-btn-lg btn-bd-primary d-flex align-items-center justify-content-center fw-semibold" onclick="ga('send', 'event', 'Examples', 'Hero', 'Download Examples');">
+ <svg class="bi me-2" aria-hidden="true"><use xlink:href="#box-seam"></use></svg>
+ Download examples
+ </a>
+ <a href="{{ .Site.Params.download.source }}" class="btn btn-lg bd-btn-lg btn-outline-secondary" onclick="ga('send', 'event', 'Examples', 'Hero', 'Download');">
+ Download source code
+ </a>
</div>
{{ end }}
</div>
@@ -20,7 +25,7 @@
</header>
<main class="bd-content order-1 py-5" id="content">
- <div class="container">
+ <div class="container-xxl bd-gutter">
{{ .Content }}
{{ if eq .Title "Examples" }}
@@ -30,7 +35,7 @@
<div class="masthead-followup-icon d-inline-block mb-2 text-white bg-danger">
{{ partial "icons/droplet-fill.svg" (dict "width" "32" "height" "32") }}
</div>
- <h2 class="display-6 fw-normal">Go further with Bootstrap Themes</h2>
+ <h2 class="display-6 fw-normal">Go further with Bootstrap Themes</h2>
<p class="col-md-10 col-lg-8 mx-auto lead">
Need something more than these examples? Take Bootstrap to the next level with premium themes from the <a href="{{ .Site.Params.themes }}">official Bootstrap Themes marketplace</a>. They’re built as their own extended frameworks, rich with new components and plugins, documentation, and powerful build tools.
</p>
diff --git a/site/layouts/partials/docs-navbar.html b/site/layouts/partials/docs-navbar.html
index 171a2ad73e..441c2bd56a 100644
--- a/site/layouts/partials/docs-navbar.html
+++ b/site/layouts/partials/docs-navbar.html
@@ -1,74 +1,89 @@
-<header class="navbar navbar-expand-md navbar-dark bd-navbar">
- <nav class="container-xxl flex-wrap flex-md-nowrap" aria-label="Main navigation">
- <a class="navbar-brand p-0 me-2" href="/" aria-label="Bootstrap">
+<header class="navbar navbar-expand-lg navbar-dark bd-navbar sticky-top">
+ <nav class="container-xxl bd-gutter flex-wrap flex-lg-nowrap" aria-label="Main navigation">
+ {{- if eq .Layout "docs" }}
+ <button class="navbar-toggler p-2" type="button" data-bs-toggle="offcanvas" data-bs-target="#bdSidebar" aria-controls="bdSidebar" aria-expanded="false" aria-label="Toggle docs navigation">
+ {{ partial "icons/hamburger.svg" (dict "class" "bi" "width" "24" "height" "24") }}
+ <span class="d-none fs-6 pe-1">Browse</span>
+ </button>
+ {{- else }}
+ <div class="d-lg-none" style="width: 2.25rem;"></div>
+ {{- end }}
+
+ <a class="navbar-brand p-0 me-0 me-lg-2" href="/" aria-label="Bootstrap">
{{ partial "icons/bootstrap-white-fill.svg" (dict "class" "d-block my-1" "width" "40" "height" "32") }}
</a>
- <button class="navbar-toggler" type="button" data-bs-toggle="offcanvas" data-bs-target="#bdNavbar" aria-controls="bdNavbar" aria-expanded="false" aria-label="Toggle navigation">
- {{ partial "icons/hamburger.svg" (dict "class" "bi" "width" "32" "height" "32") }}
+ <button class="navbar-toggler d-flex d-lg-none order-3 p-2" type="button" data-bs-toggle="offcanvas" data-bs-target="#bdNavbar" aria-controls="bdNavbar" aria-expanded="false" aria-label="Toggle navigation">
+ <svg class="bi" width="24" height="24" aria-hidden="true"><use xlink:href="#three-dots"></use></svg>
</button>
- <div class="offcanvas offcanvas-end" tabindex="-1" id="bdNavbar" aria-labelledby="bdNavbarOffcanvasLabel">
- <div class="offcanvas-header pb-0">
+ <div class="offcanvas-lg offcanvas-end flex-grow-1" id="bdNavbar" aria-labelledby="bdNavbarOffcanvasLabel">
+ <div class="offcanvas-header px-4 pb-0">
<h5 class="offcanvas-title text-white" id="bdNavbarOffcanvasLabel">Bootstrap</h5>
- <button type="button" class="btn-close btn-close-white" data-bs-dismiss="offcanvas" aria-label="Close"></button>
+ <button type="button" class="btn-close btn-close-white" data-bs-dismiss="offcanvas" aria-label="Close" data-bs-target="#bdNavbar"></button>
</div>
- <div class="offcanvas-body pt-0">
- <hr class="d-md-none text-white-50">
+ <div class="offcanvas-body p-4 pt-0 p-lg-0">
+ <hr class="d-lg-none text-white-50">
<ul class="navbar-nav flex-row flex-wrap bd-navbar-nav">
- <li class="nav-item col-6 col-md-auto">
- <a class="nav-link p-2{{ if .IsHome }} active" aria-current="page{{ end }}" href="/" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Bootstrap');">Home</a>
- </li>
- <li class="nav-item col-6 col-md-auto">
- <a class="nav-link p-2{{ if eq .Page.Layout "docs" }} active" aria-current="true{{ end }}" href="/docs/{{ .Site.Params.docs_version }}/getting-started/introduction/" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Docs');">Docs</a>
+ <li class="nav-item col-6 col-lg-auto">
+ <a class="nav-link py-2 px-0 px-lg-2{{ if eq .Page.Layout "docs" }} active" aria-current="true{{ end }}" href="/docs/{{ .Site.Params.docs_version }}/getting-started/introduction/" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Docs');">Docs</a>
</li>
- <li class="nav-item col-6 col-md-auto">
- <a class="nav-link p-2{{ if eq .Page.Title "Examples" }} active" aria-current="true{{ end }}" href="/docs/{{ .Site.Params.docs_version }}/examples/" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Examples');">Examples</a>
+ <li class="nav-item col-6 col-lg-auto">
+ <a class="nav-link py-2 px-0 px-lg-2{{ if eq .Page.Title "Examples" }} active" aria-current="true{{ end }}" href="/docs/{{ .Site.Params.docs_version }}/examples/" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Examples');">Examples</a>
</li>
- <li class="nav-item col-6 col-md-auto">
- <a class="nav-link p-2" href="{{ .Site.Params.icons }}" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Icons');" target="_blank" rel="noopener">Icons</a>
+ <li class="nav-item col-6 col-lg-auto">
+ <a class="nav-link py-2 px-0 px-lg-2" href="{{ .Site.Params.icons }}" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Icons');" target="_blank" rel="noopener">Icons</a>
</li>
- <li class="nav-item col-6 col-md-auto">
- <a class="nav-link p-2" href="{{ .Site.Params.themes }}" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Themes');" target="_blank" rel="noopener">Themes</a>
+ <li class="nav-item col-6 col-lg-auto">
+ <a class="nav-link py-2 px-0 px-lg-2" href="{{ .Site.Params.themes }}" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Themes');" target="_blank" rel="noopener">Themes</a>
</li>
- <li class="nav-item col-6 col-md-auto">
- <a class="nav-link p-2" href="{{ .Site.Params.blog }}" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Blog');" target="_blank" rel="noopener">Blog</a>
+ <li class="nav-item col-6 col-lg-auto">
+ <a class="nav-link py-2 px-0 px-lg-2" href="{{ .Site.Params.blog }}" onclick="ga('send', 'event', 'Navbar', 'Community links', 'Blog');" target="_blank" rel="noopener">Blog</a>
</li>
</ul>
- <hr class="d-md-none text-white-50">
+ <hr class="d-lg-none text-white-50">
+
+ {{ if eq .Layout "docs" }}
+ <form class="bd-search" data-shortcut="⌘K">
+ <input type="search" class="form-control" id="search-input" placeholder="Search docs..." aria-label="Search docs for..." autocomplete="off" data-bd-docs-version="{{ .Site.Params.docs_version }}">
+ </form>
+
+ <hr class="d-lg-none text-white-50">
+ {{ end }}
<ul class="navbar-nav flex-row flex-wrap ms-md-auto">
- <li class="nav-item col-6 col-md-auto">
- <a class="nav-link p-2" href="{{ .Site.Params.github_org }}" target="_blank" rel="noopener">
- {{ partial "icons/github.svg" (dict "class" "navbar-nav-svg d-inline-block align-text-top" "width" "36" "height" "36") }}
- <small class="d-md-none ms-2">GitHub</small>
+ <li class="nav-item col-6 col-lg-auto">
+ <a class="nav-link py-2 px-0 px-lg-2" href="{{ .Site.Params.github_org }}" target="_blank" rel="noopener">
+ {{ partial "icons/github.svg" (dict "class" "navbar-nav-svg" "width" "16" "height" "16") }}
+ <small class="d-lg-none ms-2">GitHub</small>
</a>
</li>
- <li class="nav-item col-6 col-md-auto">
- <a class="nav-link p-2" href="https://twitter.com/{{ .Site.Params.twitter }}" target="_blank" rel="noopener">
- {{ partial "icons/twitter.svg" (dict "class" "navbar-nav-svg d-inline-block align-text-top" "width" "36" "height" "36") }}
- <small class="d-md-none ms-2">Twitter</small>
+ <li class="nav-item col-6 col-lg-auto">
+ <a class="nav-link py-2 px-0 px-lg-2" href="https://twitter.com/{{ .Site.Params.twitter }}" target="_blank" rel="noopener">
+ {{ partial "icons/twitter.svg" (dict "class" "navbar-nav-svg" "width" "16" "height" "16") }}
+ <small class="d-lg-none ms-2">Twitter</small>
</a>
</li>
- <li class="nav-item col-6 col-md-auto">
- <a class="nav-link p-2" href="{{ .Site.Params.slack }}" target="_blank" rel="noopener">
- {{ partial "icons/slack.svg" (dict "class" "navbar-nav-svg d-inline-block align-text-top" "width" "36" "height" "36") }}
- <small class="d-md-none ms-2">Slack</small>
+ <li class="nav-item col-6 col-lg-auto">
+ <a class="nav-link py-2 px-0 px-lg-2" href="{{ .Site.Params.slack }}" target="_blank" rel="noopener">
+ {{ partial "icons/slack.svg" (dict "class" "navbar-nav-svg" "width" "16" "height" "16") }}
+ <small class="d-lg-none ms-2">Slack</small>
</a>
</li>
- <li class="nav-item col-6 col-md-auto">
- <a class="nav-link p-2" href="{{ .Site.Params.opencollective }}" target="_blank" rel="noopener">
- {{ partial "icons/opencollective.svg" (dict "class" "navbar-nav-svg d-inline-block align-text-top" "width" "36" "height" "36") }}
- <small class="d-md-none ms-2">Open Collective</small>
+ <li class="nav-item col-6 col-lg-auto">
+ <a class="nav-link py-2 px-0 px-lg-2" href="{{ .Site.Params.opencollective }}" target="_blank" rel="noopener">
+ {{ partial "icons/opencollective.svg" (dict "class" "navbar-nav-svg" "width" "16" "height" "16") }}
+ <small class="d-lg-none ms-2">Open Collective</small>
</a>
</li>
+ <li class="nav-item py-1 col-12 col-lg-auto">
+ <div class="vr d-none d-lg-flex h-100 mx-lg-2 text-white"></div>
+ <hr class="d-lg-none text-white-50">
+ </li>
+ {{ partial "docs-versions" . }}
</ul>
-
- <hr class="d-md-none text-white-50">
-
- <a class="btn btn-bd-accent d-lg-inline-block my-2 my-md-0 ms-md-3" href="/docs/{{ .Site.Params.docs_version }}/getting-started/download/">Download</a>
</div>
</div>
</nav>
diff --git a/site/layouts/partials/docs-sidebar.html b/site/layouts/partials/docs-sidebar.html
index eec268ceb2..3ffe9f4d4c 100644
--- a/site/layouts/partials/docs-sidebar.html
+++ b/site/layouts/partials/docs-sidebar.html
@@ -1,8 +1,8 @@
-<nav class="collapse bd-links" id="bd-docs-nav" aria-label="Docs navigation">
+<nav class="bd-links w-100">
{{- $url := split .Permalink "/" -}}
{{- $page_slug := index $url (sub (len $url) 2) -}}
- <ul class="list-unstyled mb-0 py-3 pt-md-1">
+ <ul class="bd-links-nav list-unstyled mb-0 pb-3 pb-md-2 pe-lg-2">
{{- range $group := .Site.Data.sidebar -}}
{{- $link := $group.title -}}
{{- $link_slug := $link | urlize -}}
@@ -16,26 +16,27 @@
{{- $is_active_group := eq $.Page.Params.group $group_slug -}}
{{- if $group.pages }}
- <li class="mb-1">
- <button class="btn d-inline-flex align-items-center rounded{{ if not $is_active_group }} collapsed{{ end }}" data-bs-toggle="collapse" data-bs-target="#{{ $group_slug }}-collapse" aria-expanded="{{ $is_active_group }}"{{ if $is_active_group }} aria-current="true"{{ end }}>
+ <li class="bd-links-group py-2">
+ <strong class="bd-links-heading d-flex w-100 align-items-center fw-semibold">
+ {{- if $group.icon }}
+ <svg class="bi me-2"{{- if $group.icon_color }} style="color: var(--bs-{{ $group.icon_color }});"{{- end }} aria-hidden="true"><use xlink:href="#{{ $group.icon }}"></use></svg>
+ {{- end }}
{{ $group.title }}
- </button>
+ </strong>
- <div class="collapse{{ if $is_active_group }} show{{ end }}" id="{{ $group_slug }}-collapse">
- <ul class="list-unstyled fw-normal pb-1 small">
- {{- range $doc := $group.pages -}}
- {{- $doc_slug := $doc.title | urlize -}}
- {{- $is_active := and $is_active_group (eq $page_slug $doc_slug) -}}
- {{- $href := printf "/docs/%s/%s/%s/" $.Site.Params.docs_version $group_slug $doc_slug }}
- <li><a href="{{ $href }}" class="d-inline-flex align-items-center rounded{{ if $is_active }} active{{ end }}"{{ if $is_active }} aria-current="page"{{ end }}>{{ $doc.title }}</a></li>
- {{- end }}
- </ul>
- </div>
+ <ul class="list-unstyled fw-normal pb-2 small">
+ {{- range $doc := $group.pages -}}
+ {{- $doc_slug := $doc.title | urlize -}}
+ {{- $is_active := and $is_active_group (eq $page_slug $doc_slug) -}}
+ {{- $href := printf "/docs/%s/%s/%s/" $.Site.Params.docs_version $group_slug $doc_slug }}
+ <li><a href="{{ $href }}" class="bd-links-link d-inline-block rounded{{ if $is_active }} active{{ end }}"{{ if $is_active }} aria-current="page"{{ end }}>{{ $doc.title }}</a></li>
+ {{- end }}
+ </ul>
</li>
{{- else }}
- <li class="my-3 mx-4 border-top"></li>
- <li>
- <a href="/docs/{{ $.Site.Params.docs_version }}/{{ $group_slug }}/" class="d-inline-flex align-items-center rounded{{ if $is_active_group }} active{{ end }}"{{ if $is_active_group }} aria-current="page"{{ end }}>
+ <li class="bd-links-span-all mt-1 mb-3 mx-4 border-top"></li>
+ <li class="bd-links-span-all">
+ <a href="/docs/{{ $.Site.Params.docs_version }}/{{ $group_slug }}/" class="bd-links-link d-inline-block rounded small {{ if $is_active_group }} active{{ end }}"{{ if $is_active_group }} aria-current="page"{{ end }}>
{{ $group.title }}
</a>
</li>
diff --git a/site/layouts/partials/docs-subnav.html b/site/layouts/partials/docs-subnav.html
deleted file mode 100644
index 9f2faf3e28..0000000000
--- a/site/layouts/partials/docs-subnav.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<nav class="bd-subnavbar py-2" aria-label="Secondary navigation">
- <div class="container-xxl d-flex align-items-md-center">
- <form class="bd-search position-relative me-auto">
- <input type="search" class="form-control" id="search-input" placeholder="Search docs..." aria-label="Search docs for..." autocomplete="off" data-bd-docs-version="{{ .Site.Params.docs_version }}">
- </form>
-
- {{ partial "docs-versions" . }}
-
- <button class="btn bd-sidebar-toggle d-md-none py-0 px-1 ms-3 order-3 collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#bd-docs-nav" aria-controls="bd-docs-nav" aria-expanded="false" aria-label="Toggle docs navigation">
- {{ partial "icons/expand.svg" (dict "class" "bi bi-expand" "width" "24" "height" "24") }}
- {{ partial "icons/collapse.svg" (dict "class" "bi bi-collapse" "width" "24" "height" "24") }}
- </button>
- </div>
-</nav>
diff --git a/site/layouts/partials/docs-versions.html b/site/layouts/partials/docs-versions.html
index a38a818230..dd234c387b 100644
--- a/site/layouts/partials/docs-versions.html
+++ b/site/layouts/partials/docs-versions.html
@@ -1,14 +1,30 @@
-<div class="dropdown ms-3">
- <button class="btn btn-bd-light dropdown-toggle" id="bd-versions" data-bs-toggle="dropdown" aria-expanded="false" data-bs-display="static">
- <span class="d-none d-lg-inline">Bootstrap</span> v{{ .Site.Params.docs_version }}
- </button>
+{{- $url := split .Permalink "/" -}}
+{{- $group_slug := index $url (sub (len $url) 3) -}}
+{{- $page_slug := index $url (sub (len $url) 2) -}}
+
+<li class="nav-item dropdown">
+ <a href="#" class="nav-link py-2 px-0 px-lg-2 dropdown-toggle" id="bd-versions" data-bs-toggle="dropdown" aria-expanded="false" data-bs-display="static">
+ <span class="d-lg-none">Bootstrap</span> v{{ .Site.Params.docs_version }}
+ </a>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="bd-versions">
+ <li><h6 class="dropdown-header">v5 releases</h6></li>
<li><a class="dropdown-item current" aria-current="true" href="/docs/{{ .Site.Params.docs_version }}/">Latest ({{ .Site.Params.docs_version }}.x)</a></li>
+ <li>
+ <a class="dropdown-item" href="https://getbootstrap.com/docs/5.1/{{ $group_slug }}/{{ $page_slug }}/">v5.1.3</a>
+ </li>
+ <li>
+ {{- if eq .Page.Params.added "5.1" }}
+ <div class="dropdown-item disabled">v5.0.2</div>
+ {{- else }}
+ <a class="dropdown-item" href="https://getbootstrap.com/docs/5.0/{{ $group_slug }}/{{ $page_slug }}/">v5.0.2</a>
+ {{- end }}
+ </li>
<li><hr class="dropdown-divider"></li>
+ <li><h6 class="dropdown-header">Previous releases</h6></li>
<li><a class="dropdown-item" href="https://getbootstrap.com/docs/4.6/">v4.6.x</a></li>
<li><a class="dropdown-item" href="https://getbootstrap.com/docs/3.4/">v3.4.1</a></li>
<li><a class="dropdown-item" href="https://getbootstrap.com/2.3.2/">v2.3.2</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="/docs/versions/">All versions</a></li>
</ul>
-</div>
+</li>
diff --git a/site/layouts/partials/favicons.html b/site/layouts/partials/favicons.html
index 50f6a5bbba..58bdb8b8b3 100644
--- a/site/layouts/partials/favicons.html
+++ b/site/layouts/partials/favicons.html
@@ -3,6 +3,6 @@
<link rel="icon" href="/docs/{{ .Site.Params.docs_version }}/assets/img/favicons/favicon-32x32.png" sizes="32x32" type="image/png">
<link rel="icon" href="/docs/{{ .Site.Params.docs_version }}/assets/img/favicons/favicon-16x16.png" sizes="16x16" type="image/png">
<link rel="manifest" href="/docs/{{ .Site.Params.docs_version }}/assets/img/favicons/manifest.json">
-<link rel="mask-icon" href="/docs/{{ .Site.Params.docs_version }}/assets/img/favicons/safari-pinned-tab.svg" color="#7952b3">
+<link rel="mask-icon" href="/docs/{{ .Site.Params.docs_version }}/assets/img/favicons/safari-pinned-tab.svg" color="#712cf9">
<link rel="icon" href="/docs/{{ .Site.Params.docs_version }}/assets/img/favicons/favicon.ico">
-<meta name="theme-color" content="#7952b3">
+<meta name="theme-color" content="#712cf9">
diff --git a/site/layouts/partials/footer.html b/site/layouts/partials/footer.html
index e3d0f13e41..2cd5fc2bc3 100644
--- a/site/layouts/partials/footer.html
+++ b/site/layouts/partials/footer.html
@@ -1,5 +1,5 @@
-<footer class="bd-footer py-5 mt-5 bg-light">
- <div class="container py-5">
+<footer class="bd-footer py-4 py-md-5 mt-5 bg-light">
+ <div class="container py-4 py-md-5 px-4 px-md-3">
<div class="row">
<div class="col-lg-3 mb-3">
<a class="d-inline-flex align-items-center mb-2 link-dark text-decoration-none" href="/" aria-label="Bootstrap">
@@ -20,6 +20,7 @@
<li class="mb-2"><a href="/docs/{{ .Site.Params.docs_version }}/examples/">Examples</a></li>
<li class="mb-2"><a href="{{ .Site.Params.themes }}">Themes</a></li>
<li class="mb-2"><a href="{{ .Site.Params.blog }}">Blog</a></li>
+ <li class="mb-2"><a href="{{ .Site.Params.swag }}">Swag Store</a></li>
</ul>
</div>
<div class="col-6 col-lg-2 mb-3">
diff --git a/site/layouts/partials/home/masthead-followup.html b/site/layouts/partials/home/masthead-followup.html
index 48f77f4704..95f394f5ad 100644
--- a/site/layouts/partials/home/masthead-followup.html
+++ b/site/layouts/partials/home/masthead-followup.html
@@ -1,37 +1,39 @@
-<div class="container masthead-followup px-4 px-md-3">
- <section class="row mb-5 pb-md-4 align-items-center">
- <div class="col-md-5">
- <div class="masthead-followup-icon d-inline-block mb-2 text-white bg-success">
- {{ partial "icons/code.svg" (dict "width" "32" "height" "32") }}
- </div>
- <h2 class="display-5 fw-normal">Installation</h2>
- <p class="lead fw-normal">
- Install Bootstrap’s source Sass and JavaScript files via npm, Composer, or Meteor.
- </p>
- <p>Package managed installs don’t include documentation or our full build scripts. You can also <a href="https://github.com/twbs/bootstrap-npm-starter">use our npm template repo</a> to quickly generate a Bootstrap project via npm.</p>
- <a class="btn btn-lg btn-outline-primary mb-3" href="/docs/{{ .Site.Params.docs_version }}/getting-started/download/">Read installation docs</a>
- </div>
- <div class="col-md-7 ps-md-5">
- {{ highlight "npm install bootstrap" "sh" "" }}
- {{ highlight (printf ("gem install bootstrap -v %s") .Site.Params.current_ruby_version) "sh" "" }}
+<div class="container-xxl bd-gutter masthead-followup">
+ <div class="col-lg-7 mx-auto pb-3 mb-3 mb-md-5 text-md-center">
+ <div class="masthead-followup-icon d-inline-block mb-3" style="--bg-rgb: var(--bd-violet-rgb);">
+ <svg class="bi fs-1"><use xlink:href="#code"></use></svg>
</div>
- </section>
+ <h2 class="display-5 mb-3 fw-semibold lh-sm">Get started any way you&nbsp;want</h2>
+ <p class="lead fw-normal">
+ Jump right into building with Bootstrap—use the CDN, install it via package manager, or download the source code.
+ </p>
+ <p class="d-flex justify-content-md-start justify-content-md-center lead fw-normal">
+ <a href="/docs/{{ .Site.Params.docs_version }}/getting-started/download/" class="icon-link fw-semibold justify-content-center ps-md-4">
+ Read installation docs
+ <svg class="bi"><use xlink:href="#arrow-right-short"></use></svg>
+ </a>
+ </p>
+ </div>
- <section class="row mb-5 pb-md-4 align-items-center">
- <div class="col-md-5">
- <div class="masthead-followup-icon d-inline-block mb-2 text-white bg-primary">
- {{ partial "icons/cloud-fill.svg" (dict "width" "32" "height" "32") }}
- </div>
- <h2 class="display-5 fw-normal">jsDelivr</h2>
- <p class="lead fw-normal">
- When you only need to include Bootstrap’s compiled CSS or JS, you can use <a href="https://www.jsdelivr.com/">jsDelivr</a>.
+ <section class="row g-3 g-md-5 mb-5 pb-5 justify-content-center">
+ <div class="col-lg-6 py-lg-4 pe-lg-5">
+ <svg class="bi mb-2 fs-2 text-muted"><use xlink:href="#box-seam"></use></svg>
+ <h3 class="fw-semibold">Install via package manager</h3>
+ <p class="pe-lg-5">
+ Install Bootstrap’s source Sass and JavaScript files via npm, RubyGems, Composer, or Meteor. Package managed installs don’t include documentation or our full build scripts. You can also <a href="https://github.com/twbs/bootstrap-npm-starter">use our npm template repo</a> to quickly generate a Bootstrap project via npm.
</p>
+ {{ highlight "npm install bootstrap" "sh" "" }}
+ {{ highlight (printf ("gem install bootstrap -v %s") .Site.Params.current_ruby_version) "sh" "" }}
<p>
- See it in action with our simple <a href="/docs/{{ .Site.Params.docs_version }}/getting-started/introduction/#starter-template">starter template</a>, or <a href="/docs/{{ .Site.Params.docs_version }}/examples/">browse the examples</a> to jumpstart your next project. You can also choose to include Popper and our JS <a href="/docs/{{ .Site.Params.docs_version }}/getting-started/introduction/#separate">separately</a>.
+ <a href="/docs/{{ .Site.Params.docs_version }}/getting-started/download/">Read our installation docs</a> for more info and additional package managers.
</p>
- <a class="btn btn-lg btn-outline-primary mb-3" href="/docs/{{ .Site.Params.docs_version }}/getting-started/introduction/">Explore the docs</a>
</div>
- <div class="col-md-7 ps-md-5">
+ <div class="col-lg-6 py-lg-4 ps-lg-5 border-lg-start">
+ <svg class="bi mb-2 fs-2 text-muted"><use xlink:href="#globe2"></use></svg>
+ <h3 class="fw-semibold">Include via CDN</h3>
+ <p class="pe-lg-5">
+ When you only need to include Bootstrap’s compiled CSS or JS, you can use <a href="https://www.jsdelivr.com/package/npm/bootstrap">jsDelivr</a>. See it in action with our simple <a href="/docs/{{ .Site.Params.docs_version }}/getting-started/introduction/#starter-template">starter template</a>, or <a href="/docs/{{ .Site.Params.docs_version }}/examples/">browse the examples</a> to jumpstart your next project. You can also choose to include Popper and our JS <a href="/docs/{{ .Site.Params.docs_version }}/getting-started/introduction/#separate">separately</a>.
+ </p>
{{ highlight (printf (`<!-- CSS only -->
<link href="%s" rel="stylesheet" integrity=%q crossorigin="anonymous">
`) .Site.Params.cdn.css (.Site.Params.cdn.css_hash | safeHTMLAttr)) "html" "" }}
@@ -41,21 +43,267 @@
</div>
</section>
- <section class="row mb-5 pb-md-4 align-items-center">
- <div class="col-md-5">
- <div class="masthead-followup-icon d-inline-block mb-2 text-white bd-bg-violet">
+ <section class="col-lg-7 mb-5">
+ <div class="masthead-followup-icon d-inline-block mb-3" style="--bg-rgb: var(--bs-primary-rgb);">
+ <svg class="bi fs-1"><use xlink:href="#palette2"></use></svg>
+ </div>
+ <h2 class="display-5 mb-3 fw-semibold lh-sm">Customize everything with&nbsp;Sass</h2>
+ <p class="lead fw-normal">
+ Bootstrap utilizes Sass for a modular and customizable architecture. Import only the components you need, enable global options like gradients and shadows, and write your own CSS with our variables, maps, functions, and mixins.
+ </p>
+ <p class="d-flex justify-content-start lead fw-normal">
+ <a href="/docs/{{ .Site.Params.docs_version }}/customize/overview/" class="icon-link fw-semibold">
+ Learn more about customizing
+ <svg class="bi"><use xlink:href="#arrow-right-short"></use></svg>
+ </a>
+ </p>
+ </section>
+
+ <section class="row g-md-5 mb-5 pb-md-5">
+ <div class="col-lg-6">
+ <h3>Include all of Bootstrap’s Sass</h3>
+ <p>Import one stylesheet and you're off to the races with every feature of our CSS.</p>
+ {{ highlight (printf `// Variable overrides first
+$primary: #900;
+$enable-shadows: true;
+$variable-prefix: "mo-";
+
+// Then import Bootstrap
+@import "../node_modules/bootstrap/scss/bootstrap";
+`) "scss" "" }}
+ <p>Learn more about our <a href="/docs/{{ .Site.Params.docs_version }}/customize/options/">global Sass options</a>.</p>
+ </div>
+ <div class="col-lg-6">
+ <h3>Include what you need</h3>
+ <p>The easiest way to customize Bootstrap—include only the CSS you need.</p>
+{{ highlight (printf `// Functions first
+@import "../node_modules/bootstrap/scss/functions";
+
+// Variable overrides second
+$primary: #900;
+$enable-shadows: true;
+$variable-prefix: "mo-";
+
+// Required Bootstrap imports
+@import "../node_modules/bootstrap/scss/variables";
+@import "../node_modules/bootstrap/scss/maps";
+@import "../node_modules/bootstrap/scss/mixins";
+@import "../node_modules/bootstrap/scss/root";
+
+// Optional components
+@import "../node_modules/bootstrap/scss/utilities";
+@import "../node_modules/bootstrap/scss/reboot";
+@import "../node_modules/bootstrap/scss/containers";
+@import "../node_modules/bootstrap/scss/grid";
+@import "../node_modules/bootstrap/scss/helpers";
+@import "../node_modules/bootstrap/scss/utilities/api";
+`) "scss" "" }}
+ <p>Learn more about <a href="/docs/{{ .Site.Params.docs_version }}/customize/sass/">using Bootstrap with Sass</a>.</p>
+ </div>
+ </section>
+
+ <section class="row g-md-5 pb-md-5 mb-5 align-items-center">
+ <div class="col-lg-8 mb-5">
+ <div class="masthead-followup-icon d-inline-block mb-3" style="--bg-rgb: var(--bd-pink-rgb);">
+ <svg class="bi fs-1"><use xlink:href="#braces"></use></svg>
+ </div>
+ <h2 class="display-5 mb-3 fw-semibold lh-sm">Build and extend in real-time with CSS&nbsp;variables</h2>
+ <p class="lead fw-normal">
+ Bootstrap 5 is evolving with each release to better utilize CSS variables for global theme styles, individual components, and even utilities. We provide dozens of variables for colors, font styles, and more at a <code>:root</code> level for use anywhere. On components and utilities, CSS variables are scoped to the relevant class and can easily be modified.
+ </p>
+ <p class="d-flex align-items-start flex-column lead fw-normal mb-0">
+ <a href="/docs/{{ .Site.Params.docs_version }}/customize/css-variables/" class="icon-link fw-semibold mb-3">
+ Learn more about CSS variables
+ <svg class="bi"><use xlink:href="#arrow-right-short"></use></svg>
+ </a>
+ </p>
+ </div>
+ <div class="row gx-md-5">
+ <div class="col-lg-6 mb-3">
+ <h3 class="fw-semibold">Using CSS variables</h3>
+ <p>Use any of our <a href="/docs/{{ .Site.Params.docs_version }}/customize/css-variables/#root-variables">global <code>:root</code> variables</a> to write new styles. CSS variables use the <code>var(--bs-variableName)</code> syntax and can be inherited by children elements.</p>
+ {{ highlight (printf `.component {
+ color: var(--bs-gray-800);
+ background-color: var(--bs-gray-100);
+ border: 1px solid var(--bs-gray-200);
+ border-radius: .25rem;
+}
+
+.component-header {
+ color: var(--bs-purple);
+}`) "scss" "" }}
+ </div>
+ <div class="col-lg-6 mb-3">
+ <h3 class="fw-semibold">Customizing via CSS variables</h3>
+ <p>Override global, component, or utility class variables to customize Bootstrap just how you like. No need to redeclare each rule, just a new variable value.</p>
+ {{ highlight (printf `body {
+ --bs-body-font-family: var(--bs-font-monospace);
+ --bs-body-line-height: 1.4;
+ --bs-body-bg: var(--bs-gray-100);
+}
+
+.table {
+ --bs-table-color: var(--bs-gray-600);
+ --bs-table-bg: var(--bs-gray-100);
+ --bs-table-border-color: transparent;
+}`) "scss" "" }}
+ </div>
+ </div>
+ </section>
+
+ <section class="row g-md-5 pb-md-5 mb-5 align-items-center">
+ <div class="col-lg-6 mb-5 mb-md-0">
+ <div class="masthead-followup-icon d-inline-block mb-3 me-2" style="--bg-rgb: var(--bs-danger-rgb);">
+ <svg class="bi fs-1"><use xlink:href="#menu-button-wide-fill"></use></svg>
+ </div>
+ <svg class="bi me-2 fs-2 text-muted"><use xlink:href="#plus"></use></svg>
+ <div class="masthead-followup-icon d-inline-block mb-3" style="--bg-rgb: var(--bs-info-rgb);">
+ <svg class="bi fs-1"><use xlink:href="#braces-asterisk"></use></svg>
+ </div>
+ <h2 class="display-5 mb-3 fw-semibold lh-sm">Components, meet the Utility&nbsp;API</h2>
+ <p class="lead fw-normal">
+ New in Bootstrap 5, our utilities are now generated by our <a href="/docs/{{ .Site.Params.docs_version }}/utilities/api/">Utility API</a>. We built it as a feature-packed Sass map that can be quickly and easily customized. It's never been easier to add, remove, or modify any utility classes. Make utilities responsive, add pseudo-class variants, and give them custom names.
+ </p>
+ <p class="d-flex align-items-start flex-column lead fw-normal mb-0">
+ <a href="/docs/{{ .Site.Params.docs_version }}/utilities/api/" class="icon-link fw-semibold mb-3">
+ Learn more about utilities
+ <svg class="bi"><use xlink:href="#arrow-right-short"></use></svg>
+ </a>
+ <a href="/docs/{{ .Site.Params.docs_version }}/examples#snippets" class="icon-link fw-semibold">
+ Explore customized components
+ <svg class="bi"><use xlink:href="#arrow-right-short"></use></svg>
+ </a>
+ </p>
+ </div>
+ <div class="col-lg-6">
+ <div class="p-4 border rounded-3 mb-4">
+ <h6>Quickly customize components</h6>
+ <hr class="mb-4">
+ <ul class="nav nav-pills mb-4" id="pillNav" role="tablist">
+ <li class="nav-item" role="presentation">
+ <button class="nav-link active" id="home-tab" data-bs-toggle="tab" type="button" role="tab" aria-selected="true">Home</button>
+ </li>
+ <li class="nav-item" role="presentation">
+ <button class="nav-link" id="profile-tab" data-bs-toggle="tab" type="button" role="tab" aria-selected="false">Profile</button>
+ </li>
+ <li class="nav-item" role="presentation">
+ <button class="nav-link" id="contact-tab" data-bs-toggle="tab" type="button" role="tab" aria-selected="false">Contact</button>
+ </li>
+ </ul>
+ <ul class="nav nav-pills nav-fill gap-2 p-1 small bg-white border rounded-5 shadow-sm" id="pillNav2" role="tablist">
+ <li class="nav-item" role="presentation">
+ <button class="nav-link active rounded-5" id="home-tab2" data-bs-toggle="tab" type="button" role="tab" aria-selected="true">Home</button>
+ </li>
+ <li class="nav-item" role="presentation">
+ <button class="nav-link rounded-5" id="profile-tab2" data-bs-toggle="tab" type="button" role="tab" aria-selected="false">Profile</button>
+ </li>
+ <li class="nav-item" role="presentation">
+ <button class="nav-link rounded-5" id="contact-tab2" data-bs-toggle="tab" type="button" role="tab" aria-selected="false">Contact</button>
+ </li>
+ </ul>
+ </div>
+ {{ highlight (printf `// Create and extend utilities with the Utility API
+
+@import "bootstrap/scss/bootstrap";
+
+$utilities: map-merge(
+ $utilities,
+ (
+ "cursor": (
+ property: cursor,
+ class: cursor,
+ responsive: true,
+ values: auto pointer grab,
+ )
+ )
+);
+`) "scss" "" }}
+ </div>
+ </section>
+
+ <section class="pb-md-5 mb-5">
+ <div class="col-lg-8 mb-5">
+ <div class="masthead-followup-icon d-inline-block mb-3" style="--bg-rgb: var(--bs-warning-rgb);">
+ <svg class="bi fs-1"><use xlink:href="#plugin"></use></svg>
+ </div>
+ <h2 class="display-5 mb-3 fw-semibold lh-sm">Powerful JavaScript plugins without&nbsp;jQuery</h2>
+ <p class="lead fw-normal">
+ Easily add toggleable hidden elements, modals and offcanvas menus, popovers and tooltips, and so much more—all without jQuery. JavaScript in Bootstrap is HTML-first, which means adding plugins is as easy as adding <code>data</code> attributes. Need more control? Include individual plugins programmatically.
+ </p>
+ <p class="d-flex justify-content-start lead fw-normal mb-md-0">
+ <a href="/docs/{{ .Site.Params.docs_version }}/getting-started/javascript/" class="icon-link fw-semibold">
+ Learn more about Bootstrap JavaScript
+ <svg class="bi"><use xlink:href="#arrow-right-short"></use></svg>
+ </a>
+ </p>
+ </div>
+ <div class="row gx-md-5">
+ <div class="col-lg-6 mb-3">
+ <h3 class="fw-semibold">Data attribute API</h3>
+ <p>Why write more JavaScript when you can write HTML? Nearly all of Bootstrap's JavaScript plugins feature a first-class data API, allowing you to use JavaScript just by adding <code>data</code> attributes.</p>
+ <div class="p-4 mb-3 border rounded-3">
+ <div class="dropdown">
+ <button class="btn btn-primary dropdown-toggle" type="button" id="dropdown" data-bs-toggle="dropdown" aria-expanded="false">
+ Dropdown
+ </button>
+ <ul class="dropdown-menu" aria-labelledby="dropdown">
+ <li><a class="dropdown-item" href="#">Dropdown item</a></li>
+ <li><a class="dropdown-item" href="#">Dropdown item</a></li>
+ <li><a class="dropdown-item" href="#">Dropdown item</a></li>
+ </ul>
+ </div>
+ </div>
+
+ {{ highlight (printf `<div class="dropdown">
+ <button class="btn btn-primary dropdown-toggle" type="button" id="dropdown" data-bs-toggle="dropdown" aria-expanded="false">
+ Dropdown
+ </button>
+ <ul class="dropdown-menu" aria-labelledby="dropdown">
+ <li><a class="dropdown-item" href="#">Dropdown item</a></li>
+ <li><a class="dropdown-item" href="#">Dropdown item</a></li>
+ <li><a class="dropdown-item" href="#">Dropdown item</a></li>
+ </ul>
+</div>
+`) "html" "" }}
+ <p>Learn more about <a href="/docs/{{ .Site.Params.docs_version }}/getting-started/javascript/#using-bootstrap-as-a-module">our JavaScript as modules</a> and <a href="/docs/{{ .Site.Params.docs_version }}/getting-started/javascript/#programmatic-api">using the programmatic API</a>.</p>
+ </div>
+ <div class="col-lg-6 mb-3">
+ <h3 class="fw-semibold">Comprehensive set of plugins</h3>
+ <p>Bootstrap features a dozen plugins that you can drop into any project. Drop them in all at once, or choose just the ones you need.</p>
+ <hr class="my-4">
+ <div class="row g-3">
+ {{- range $plugin := .Site.Data.plugins -}}
+ {{- $href := printf "/docs/%s/%s" $.Site.Params.docs_version $plugin.link }}
+ <div class="col-sm-6 mb-2">
+ <a class="d-block pe-lg-4 text-decoration-none lh-sm" href="{{ $href }}">
+ <h4 class="mb-0 fs-5 fw-semibold">{{ $plugin.name }}</h4>
+ <small class="text-muted">{{ $plugin.description }}</small>
+ </a>
+ </div>
+ {{- end }}
+ </div>
+ </div>
+ </div>
+
+ </section>
+
+ <section class="row g-3 g-md-5 pb-md-5 mb-5 align-items-center">
+ <div class="col-lg-6">
+ <div class="masthead-followup-icon d-inline-block mb-3" style="--bg-rgb: var(--bd-teal-rgb);">
{{ partial "icons/circle-square.svg" (dict "width" "32" "height" "32") }}
</div>
- <h2 class="display-5 fw-normal">Bootstrap Icons</h2>
+ <h2 class="display-5 mb-3 fw-semibold lh-sm">Personalize it with Bootstrap&nbsp;Icons</h2>
<p class="lead fw-normal">
- For the first time ever, Bootstrap has its own open source SVG icon library, designed to work best with our components and documentation.
+ <a href="{{ .Site.Params.icons }}">Bootstrap Icons</a> is an open source SVG icon library featuring over 1,500 glyphs, with more added every release. They're designed to work in any project, whether you use Bootstrap itself or not. Use them as SVGs or icon fonts—both options give you vector scaling and easy customization via CSS.
</p>
- <p>
- Bootstrap Icons are designed to work best with Bootstrap components, but they’ll work in any project. They’re SVGs, so they scale quickly and easily, can be implemented in several ways, and can be styled with CSS.
+ <p class="d-flex justify-content-start lead fw-normal mb-md-0">
+ <a href="{{ .Site.Params.icons }}" class="icon-link fw-semibold">
+ Get Bootstrap Icons
+ <svg class="bi"><use xlink:href="#arrow-right-short"></use></svg>
+ </a>
</p>
- <a href="{{ .Site.Params.icons }}" class="btn btn-lg btn-outline-primary mb-3">Get Bootstrap Icons</a>
</div>
- <div class="col-md-7 ps-md-5">
+ <div class="col-lg-6">
<img class="img-fluid mt-3 mx-auto" srcset="/docs/{{ .Site.Params.docs_version }}/assets/img/bootstrap-icons.png,
/docs/{{ .Site.Params.docs_version }}/assets/img/bootstrap-icons@2x.png 2x"
src="/docs/{{ .Site.Params.docs_version }}/assets/img/bootstrap-icons.png"
@@ -63,21 +311,23 @@
</div>
</section>
- <section class="row mb-5 pb-md-4 align-items-center">
- <div class="col-md-5">
- <div class="masthead-followup-icon d-inline-block mb-2 text-white bg-danger">
+ <section class="row g-3 g-md-5 pb-md-5 mb-5 align-items-center">
+ <div class="col-lg-6">
+ <div class="masthead-followup-icon d-inline-block mb-3" style="--bg-rgb: var(--bd-violet-rgb);">
{{ partial "icons/droplet-fill.svg" (dict "width" "32" "height" "32") }}
</div>
- <h2 class="display-5 fw-normal">Official Themes</h2>
+ <h2 class="display-5 mb-3 fw-semibold lh-sm">Make it yours with official Bootstrap Themes</h2>
<p class="lead fw-normal">
- Take Bootstrap to the next level with premium themes from the <a href="{{ .Site.Params.themes }}">official Bootstrap Themes marketplace</a>.
+ Take Bootstrap to the next level with premium themes from the <a href="{{ .Site.Params.themes }}">official Bootstrap Themes marketplace</a>. Themes are built on Bootstrap as their own extended frameworks, rich with new components and plugins, documentation, and powerful build tools.
</p>
- <p>
- Themes are built on Bootstrap as their own extended frameworks, rich with new components and plugins, documentation, and powerful build tools.
+ <p class="d-flex justify-content-start lead fw-normal mb-md-0">
+ <a href="{{ .Site.Params.themes }}" class="icon-link fw-semibold">
+ Browse Bootstrap Themes
+ <svg class="bi"><use xlink:href="#arrow-right-short"></use></svg>
+ </a>
</p>
- <a href="{{ .Site.Params.themes }}" class="btn btn-lg btn-outline-primary mb-3">Browse themes</a>
</div>
- <div class="col-md-7 ps-md-5">
+ <div class="col-lg-6">
<img class="img-fluid mt-3 mx-auto" srcset="/docs/{{ .Site.Params.docs_version }}/assets/img/bootstrap-themes.png,
/docs/{{ .Site.Params.docs_version }}/assets/img/bootstrap-themes@2x.png 2x"
src="/docs/{{ .Site.Params.docs_version }}/assets/img/bootstrap-themes.png"
diff --git a/site/layouts/partials/home/masthead.html b/site/layouts/partials/home/masthead.html
index e5661d9b33..63ce0e3b19 100644
--- a/site/layouts/partials/home/masthead.html
+++ b/site/layouts/partials/home/masthead.html
@@ -1,28 +1,34 @@
<div class="bd-masthead mb-3" id="content">
- <div class="container px-4 px-md-3">
- <div class="row align-items-lg-center">
- <div class="col-8 mx-auto col-md-4 order-md-2 col-lg-5">
- {{ partial "icons/homepage-hero.svg" (dict "class" "img-fluid mb-3 mb-md-0" "width" "600" "height" "533") }}
- </div>
- <div class="col-md-8 order-md-1 col-lg-7 text-center text-md-start">
- <h1 class="mb-3">Build fast, responsive sites with Bootstrap</h1>
- <p class="lead mb-4">
- Quickly design and customize responsive mobile-first sites with Bootstrap, the world’s most popular front-end open source toolkit, featuring Sass variables and mixins, responsive grid system, extensive prebuilt components, and powerful JavaScript plugins.
- </p>
-
- <div class="d-flex flex-column flex-md-row">
- <a href="/docs/{{ .Site.Params.docs_version }}/getting-started/introduction/" class="btn btn-lg btn-bd-primary mb-3 me-md-3" onclick="ga('send', 'event', 'Jumbotron actions', 'Get started', 'Get started');">Get started</a>
- <a href="/docs/{{ .Site.Params.docs_version }}/getting-started/download/" class="btn btn-lg btn-outline-secondary mb-3" onclick="ga('send', 'event', 'Jumbotron actions', 'Download', 'Download {{ .Site.Params.current_version }}');">Download</a>
+ <div class="container-xxl bd-gutter">
+ <div class="col-md-8 mx-auto text-center">
+ <a class="d-flex flex-column flex-lg-row justify-content-center align-items-center mb-4 text-dark lh-sm text-decoration-none" href="https://blog.getbootstrap.com/2021/08/04/bootstrap-5-1-0/">
+ <strong class="d-sm-inline-block p-2 me-2 mb-2 mb-lg-0 rounded-3 masthead-notice">New in v5.1</strong>
+ <span class="text-muted">CSS Grid, offcanvas navbars, improved utilities, and more!</span>
+ </a>
+ <img src="/docs/{{ .Site.Params.docs_version }}/assets/brand/bootstrap-logo-shadow.png" width="200" height="165" alt="Bootstrap" class="d-block mx-auto mb-3">
+ <h1 class="mb-3 fw-semibold">Build fast, responsive sites with&nbsp;Bootstrap</h1>
+ <p class="lead mb-4">
+ Powerful, extensible, and feature-packed frontend toolkit. Build and customize with Sass, utilize prebuilt grid system and components, and bring projects to life with powerful JavaScript plugins.
+ </p>
+ <div class="d-flex flex-column flex-md-row align-items-md-stretch justify-content-md-center gap-3 mb-4">
+ <div class="d-inline-block v-align-middle fs-5" style="min-width: fit-content;">
+ {{ highlight "npm i bootstrap" "sh" "" }}
</div>
- <p class="text-muted mb-0">
- Currently <strong>v{{ .Site.Params.current_version }}</strong>
- <span class="px-1">&middot;</span>
- <a href="https://getbootstrap.com/docs/4.6/getting-started/introduction/" class="link-secondary">v4.6.x docs</a>
- <span class="px-1">&middot;</span>
- <a href="/docs/versions/" class="link-secondary">All releases</a>
- </p>
+ <a href="/docs/{{ .Site.Params.docs_version }}/getting-started/introduction/" class="btn btn-lg bd-btn-lg btn-bd-primary d-flex align-items-center justify-content-center fw-semibold" onclick="ga('send', 'event', 'Jumbotron actions', 'Get started', 'Get started');">
+ <svg class="bi me-2" aria-hidden="true"><use xlink:href="#book-half"></use></svg>
+ Read the docs
+ </a>
</div>
+ <p class="text-muted mb-0">
+ Currently <strong>v{{ .Site.Params.current_version }}</strong>
+ <span class="px-1">&middot;</span>
+ <a href="/docs/{{ .Site.Params.docs_version }}/getting-started/download/" class="link-secondary">Download</a>
+ <span class="px-1">&middot;</span>
+ <a href="https://getbootstrap.com/docs/4.6/getting-started/introduction/" class="link-secondary text-nowrap">v4.6.x docs</a>
+ <span class="px-1">&middot;</span>
+ <a href="/docs/versions/" class="link-secondary text-nowrap">All releases</a>
+ </p>
+ {{ partial "ads" . }}
</div>
- {{ partial "ads" . }}
</div>
</div>
diff --git a/site/layouts/partials/icons.html b/site/layouts/partials/icons.html
new file mode 100644
index 0000000000..9841e143a8
--- /dev/null
+++ b/site/layouts/partials/icons.html
@@ -0,0 +1,72 @@
+<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
+ <symbol id="arrow-right-short" viewBox="0 0 16 16">
+ <path fill-rule="evenodd" d="M4 8a.5.5 0 0 1 .5-.5h5.793L8.146 5.354a.5.5 0 1 1 .708-.708l3 3a.5.5 0 0 1 0 .708l-3 3a.5.5 0 0 1-.708-.708L10.293 8.5H4.5A.5.5 0 0 1 4 8z"/>
+ </symbol>
+ <symbol id="book-half" viewBox="0 0 16 16">
+ <path d="M8.5 2.687c.654-.689 1.782-.886 3.112-.752 1.234.124 2.503.523 3.388.893v9.923c-.918-.35-2.107-.692-3.287-.81-1.094-.111-2.278-.039-3.213.492V2.687zM8 1.783C7.015.936 5.587.81 4.287.94c-1.514.153-3.042.672-3.994 1.105A.5.5 0 0 0 0 2.5v11a.5.5 0 0 0 .707.455c.882-.4 2.303-.881 3.68-1.02 1.409-.142 2.59.087 3.223.877a.5.5 0 0 0 .78 0c.633-.79 1.814-1.019 3.222-.877 1.378.139 2.8.62 3.681 1.02A.5.5 0 0 0 16 13.5v-11a.5.5 0 0 0-.293-.455c-.952-.433-2.48-.952-3.994-1.105C10.413.809 8.985.936 8 1.783z"/>
+ </symbol>
+ <symbol id="box-seam" viewBox="0 0 16 16">
+ <path d="M8.186 1.113a.5.5 0 0 0-.372 0L1.846 3.5l2.404.961L10.404 2l-2.218-.887zm3.564 1.426L5.596 5 8 5.961 14.154 3.5l-2.404-.961zm3.25 1.7-6.5 2.6v7.922l6.5-2.6V4.24zM7.5 14.762V6.838L1 4.239v7.923l6.5 2.6zM7.443.184a1.5 1.5 0 0 1 1.114 0l7.129 2.852A.5.5 0 0 1 16 3.5v8.662a1 1 0 0 1-.629.928l-7.185 2.874a.5.5 0 0 1-.372 0L.63 13.09a1 1 0 0 1-.63-.928V3.5a.5.5 0 0 1 .314-.464L7.443.184z"/>
+ </symbol>
+ <symbol id="braces" viewBox="0 0 16 16">
+ <path d="M2.114 8.063V7.9c1.005-.102 1.497-.615 1.497-1.6V4.503c0-1.094.39-1.538 1.354-1.538h.273V2h-.376C3.25 2 2.49 2.759 2.49 4.352v1.524c0 1.094-.376 1.456-1.49 1.456v1.299c1.114 0 1.49.362 1.49 1.456v1.524c0 1.593.759 2.352 2.372 2.352h.376v-.964h-.273c-.964 0-1.354-.444-1.354-1.538V9.663c0-.984-.492-1.497-1.497-1.6zM13.886 7.9v.163c-1.005.103-1.497.616-1.497 1.6v1.798c0 1.094-.39 1.538-1.354 1.538h-.273v.964h.376c1.613 0 2.372-.759 2.372-2.352v-1.524c0-1.094.376-1.456 1.49-1.456V7.332c-1.114 0-1.49-.362-1.49-1.456V4.352C13.51 2.759 12.75 2 11.138 2h-.376v.964h.273c.964 0 1.354.444 1.354 1.538V6.3c0 .984.492 1.497 1.497 1.6z"/>
+ </symbol>
+ <symbol id="braces-asterisk" viewBox="0 0 16 16">
+ <path fill-rule="evenodd" d="M1.114 8.063V7.9c1.005-.102 1.497-.615 1.497-1.6V4.503c0-1.094.39-1.538 1.354-1.538h.273V2h-.376C2.25 2 1.49 2.759 1.49 4.352v1.524c0 1.094-.376 1.456-1.49 1.456v1.299c1.114 0 1.49.362 1.49 1.456v1.524c0 1.593.759 2.352 2.372 2.352h.376v-.964h-.273c-.964 0-1.354-.444-1.354-1.538V9.663c0-.984-.492-1.497-1.497-1.6ZM14.886 7.9v.164c-1.005.103-1.497.616-1.497 1.6v1.798c0 1.094-.39 1.538-1.354 1.538h-.273v.964h.376c1.613 0 2.372-.759 2.372-2.352v-1.524c0-1.094.376-1.456 1.49-1.456v-1.3c-1.114 0-1.49-.362-1.49-1.456V4.352C14.51 2.759 13.75 2 12.138 2h-.376v.964h.273c.964 0 1.354.444 1.354 1.538V6.3c0 .984.492 1.497 1.497 1.6ZM7.5 11.5V9.207l-1.621 1.621-.707-.707L6.792 8.5H4.5v-1h2.293L5.172 5.879l.707-.707L7.5 6.792V4.5h1v2.293l1.621-1.621.707.707L9.208 7.5H11.5v1H9.207l1.621 1.621-.707.707L8.5 9.208V11.5h-1Z"/>
+ </symbol>
+ <symbol id="check2" viewBox="0 0 16 16">
+ <title>Check</title>
+ <path d="M13.854 3.646a.5.5 0 0 1 0 .708l-7 7a.5.5 0 0 1-.708 0l-3.5-3.5a.5.5 0 1 1 .708-.708L6.5 10.293l6.646-6.647a.5.5 0 0 1 .708 0z"/>
+ </symbol>
+ <symbol id="chevron-expand" viewBox="0 0 16 16">
+ <path fill-rule="evenodd" d="M3.646 9.146a.5.5 0 0 1 .708 0L8 12.793l3.646-3.647a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 0-.708zm0-2.292a.5.5 0 0 0 .708 0L8 3.207l3.646 3.647a.5.5 0 0 0 .708-.708l-4-4a.5.5 0 0 0-.708 0l-4 4a.5.5 0 0 0 0 .708z"/>
+ </symbol>
+ <symbol id="clipboard" viewBox="0 0 16 16">
+ <path d="M4 1.5H3a2 2 0 0 0-2 2V14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3.5a2 2 0 0 0-2-2h-1v1h1a1 1 0 0 1 1 1V14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V3.5a1 1 0 0 1 1-1h1v-1z"/>
+ <path d="M9.5 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5h3zm-3-1A1.5 1.5 0 0 0 5 1.5v1A1.5 1.5 0 0 0 6.5 4h3A1.5 1.5 0 0 0 11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3z"/>
+ </symbol>
+ <symbol id="code" viewBox="0 0 16 16">
+ <path d="M5.854 4.854a.5.5 0 1 0-.708-.708l-3.5 3.5a.5.5 0 0 0 0 .708l3.5 3.5a.5.5 0 0 0 .708-.708L2.707 8l3.147-3.146zm4.292 0a.5.5 0 0 1 .708-.708l3.5 3.5a.5.5 0 0 1 0 .708l-3.5 3.5a.5.5 0 0 1-.708-.708L13.293 8l-3.147-3.146z"/>
+ </symbol>
+ <symbol id="file-earmark-richtext" viewBox="0 0 16 16">
+ <path d="M14 4.5V14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h5.5L14 4.5zm-3 0A1.5 1.5 0 0 1 9.5 3V1H4a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4.5h-2z"/>
+ <path d="M4.5 12.5A.5.5 0 0 1 5 12h3a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm0-2A.5.5 0 0 1 5 10h6a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm1.639-3.708 1.33.886 1.854-1.855a.25.25 0 0 1 .289-.047l1.888.974V8.5a.5.5 0 0 1-.5.5H5a.5.5 0 0 1-.5-.5V8s1.54-1.274 1.639-1.208zM6.25 6a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5z"/>
+ </symbol>
+ <symbol id="globe2" viewBox="0 0 16 16">
+ <path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8zm7.5-6.923c-.67.204-1.335.82-1.887 1.855-.143.268-.276.56-.395.872.705.157 1.472.257 2.282.287V1.077zM4.249 3.539c.142-.384.304-.744.481-1.078a6.7 6.7 0 0 1 .597-.933A7.01 7.01 0 0 0 3.051 3.05c.362.184.763.349 1.198.49zM3.509 7.5c.036-1.07.188-2.087.436-3.008a9.124 9.124 0 0 1-1.565-.667A6.964 6.964 0 0 0 1.018 7.5h2.49zm1.4-2.741a12.344 12.344 0 0 0-.4 2.741H7.5V5.091c-.91-.03-1.783-.145-2.591-.332zM8.5 5.09V7.5h2.99a12.342 12.342 0 0 0-.399-2.741c-.808.187-1.681.301-2.591.332zM4.51 8.5c.035.987.176 1.914.399 2.741A13.612 13.612 0 0 1 7.5 10.91V8.5H4.51zm3.99 0v2.409c.91.03 1.783.145 2.591.332.223-.827.364-1.754.4-2.741H8.5zm-3.282 3.696c.12.312.252.604.395.872.552 1.035 1.218 1.65 1.887 1.855V11.91c-.81.03-1.577.13-2.282.287zm.11 2.276a6.696 6.696 0 0 1-.598-.933 8.853 8.853 0 0 1-.481-1.079 8.38 8.38 0 0 0-1.198.49 7.01 7.01 0 0 0 2.276 1.522zm-1.383-2.964A13.36 13.36 0 0 1 3.508 8.5h-2.49a6.963 6.963 0 0 0 1.362 3.675c.47-.258.995-.482 1.565-.667zm6.728 2.964a7.009 7.009 0 0 0 2.275-1.521 8.376 8.376 0 0 0-1.197-.49 8.853 8.853 0 0 1-.481 1.078 6.688 6.688 0 0 1-.597.933zM8.5 11.909v3.014c.67-.204 1.335-.82 1.887-1.855.143-.268.276-.56.395-.872A12.63 12.63 0 0 0 8.5 11.91zm3.555-.401c.57.185 1.095.409 1.565.667A6.963 6.963 0 0 0 14.982 8.5h-2.49a13.36 13.36 0 0 1-.437 3.008zM14.982 7.5a6.963 6.963 0 0 0-1.362-3.675c-.47.258-.995.482-1.565.667.248.92.4 1.938.437 3.008h2.49zM11.27 2.461c.177.334.339.694.482 1.078a8.368 8.368 0 0 0 1.196-.49 7.01 7.01 0 0 0-2.275-1.52c.218.283.418.597.597.932zm-.488 1.343a7.765 7.765 0 0 0-.395-.872C9.835 1.897 9.17 1.282 8.5 1.077V4.09c.81-.03 1.577-.13 2.282-.287z"/>
+ </symbol>
+ <symbol id="grid-fill" viewBox="0 0 16 16">
+ <path d="M1 2.5A1.5 1.5 0 0 1 2.5 1h3A1.5 1.5 0 0 1 7 2.5v3A1.5 1.5 0 0 1 5.5 7h-3A1.5 1.5 0 0 1 1 5.5v-3zm8 0A1.5 1.5 0 0 1 10.5 1h3A1.5 1.5 0 0 1 15 2.5v3A1.5 1.5 0 0 1 13.5 7h-3A1.5 1.5 0 0 1 9 5.5v-3zm-8 8A1.5 1.5 0 0 1 2.5 9h3A1.5 1.5 0 0 1 7 10.5v3A1.5 1.5 0 0 1 5.5 15h-3A1.5 1.5 0 0 1 1 13.5v-3zm8 0A1.5 1.5 0 0 1 10.5 9h3a1.5 1.5 0 0 1 1.5 1.5v3a1.5 1.5 0 0 1-1.5 1.5h-3A1.5 1.5 0 0 1 9 13.5v-3z"/>
+ </symbol>
+ <symbol id="lightning-charge-fill" viewBox="0 0 16 16">
+ <path d="M11.251.068a.5.5 0 0 1 .227.58L9.677 6.5H13a.5.5 0 0 1 .364.843l-8 8.5a.5.5 0 0 1-.842-.49L6.323 9.5H3a.5.5 0 0 1-.364-.843l8-8.5a.5.5 0 0 1 .615-.09z"/>
+ </symbol>
+ <symbol id="list" viewBox="0 0 16 16">
+ <path fill-rule="evenodd" d="M2.5 12a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5z"/>
+ </symbol>
+ <symbol id="magic" viewBox="0 0 16 16">
+ <path d="M9.5 2.672a.5.5 0 1 0 1 0V.843a.5.5 0 0 0-1 0v1.829Zm4.5.035A.5.5 0 0 0 13.293 2L12 3.293a.5.5 0 1 0 .707.707L14 2.707ZM7.293 4A.5.5 0 1 0 8 3.293L6.707 2A.5.5 0 0 0 6 2.707L7.293 4Zm-.621 2.5a.5.5 0 1 0 0-1H4.843a.5.5 0 1 0 0 1h1.829Zm8.485 0a.5.5 0 1 0 0-1h-1.829a.5.5 0 0 0 0 1h1.829ZM13.293 10A.5.5 0 1 0 14 9.293L12.707 8a.5.5 0 1 0-.707.707L13.293 10ZM9.5 11.157a.5.5 0 0 0 1 0V9.328a.5.5 0 0 0-1 0v1.829Zm1.854-5.097a.5.5 0 0 0 0-.706l-.708-.708a.5.5 0 0 0-.707 0L8.646 5.94a.5.5 0 0 0 0 .707l.708.708a.5.5 0 0 0 .707 0l1.293-1.293Zm-3 3a.5.5 0 0 0 0-.706l-.708-.708a.5.5 0 0 0-.707 0L.646 13.94a.5.5 0 0 0 0 .707l.708.708a.5.5 0 0 0 .707 0L8.354 9.06Z"/>
+ </symbol>
+ <symbol id="menu-button-wide-fill" viewBox="0 0 16 16">
+ <path d="M1.5 0A1.5 1.5 0 0 0 0 1.5v2A1.5 1.5 0 0 0 1.5 5h13A1.5 1.5 0 0 0 16 3.5v-2A1.5 1.5 0 0 0 14.5 0h-13zm1 2h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1 0-1zm9.927.427A.25.25 0 0 1 12.604 2h.792a.25.25 0 0 1 .177.427l-.396.396a.25.25 0 0 1-.354 0l-.396-.396zM0 8a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V8zm1 3v2a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2H1zm14-1V8a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v2h14zM2 8.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5zm0 4a.5.5 0 0 1 .5-.5h6a.5.5 0 0 1 0 1h-6a.5.5 0 0 1-.5-.5z"/>
+ </symbol>
+ <symbol id="palette2" viewBox="0 0 16 16">
+ <path d="M0 .5A.5.5 0 0 1 .5 0h5a.5.5 0 0 1 .5.5v5.277l4.147-4.131a.5.5 0 0 1 .707 0l3.535 3.536a.5.5 0 0 1 0 .708L10.261 10H15.5a.5.5 0 0 1 .5.5v5a.5.5 0 0 1-.5.5H3a2.99 2.99 0 0 1-2.121-.879A2.99 2.99 0 0 1 0 13.044m6-.21 7.328-7.3-2.829-2.828L6 7.188v5.647zM4.5 13a1.5 1.5 0 1 0-3 0 1.5 1.5 0 0 0 3 0zM15 15v-4H9.258l-4.015 4H15zM0 .5v12.495V.5z"/>
+ <path d="M0 12.995V13a3.07 3.07 0 0 0 0-.005z"/>
+ </symbol>
+ <symbol id="plugin" viewBox="0 0 16 16">
+ <path fill-rule="evenodd" d="M1 8a7 7 0 1 1 2.898 5.673c-.167-.121-.216-.406-.002-.62l1.8-1.8a3.5 3.5 0 0 0 4.572-.328l1.414-1.415a.5.5 0 0 0 0-.707l-.707-.707 1.559-1.563a.5.5 0 1 0-.708-.706l-1.559 1.562-1.414-1.414 1.56-1.562a.5.5 0 1 0-.707-.706l-1.56 1.56-.707-.706a.5.5 0 0 0-.707 0L5.318 5.975a3.5 3.5 0 0 0-.328 4.571l-1.8 1.8c-.58.58-.62 1.6.121 2.137A8 8 0 1 0 0 8a.5.5 0 0 0 1 0Z"/>
+ </symbol>
+ <symbol id="plus" viewBox="0 0 16 16">
+ <path d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z"/>
+ </symbol>
+ <symbol id="three-dots" viewBox="0 0 16 16">
+ <path d="M3 9.5a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm5 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z"/>
+ </symbol>
+ <symbol id="tools" viewBox="0 0 16 16">
+ <path d="M1 0 0 1l2.2 3.081a1 1 0 0 0 .815.419h.07a1 1 0 0 1 .708.293l2.675 2.675-2.617 2.654A3.003 3.003 0 0 0 0 13a3 3 0 1 0 5.878-.851l2.654-2.617.968.968-.305.914a1 1 0 0 0 .242 1.023l3.356 3.356a1 1 0 0 0 1.414 0l1.586-1.586a1 1 0 0 0 0-1.414l-3.356-3.356a1 1 0 0 0-1.023-.242L10.5 9.5l-.96-.96 2.68-2.643A3.005 3.005 0 0 0 16 3c0-.269-.035-.53-.102-.777l-2.14 2.141L12 4l-.364-1.757L13.777.102a3 3 0 0 0-3.675 3.68L7.462 6.46 4.793 3.793a1 1 0 0 1-.293-.707v-.071a1 1 0 0 0-.419-.814L1 0zm9.646 10.646a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1-.708.708l-3-3a.5.5 0 0 1 0-.708zM3 11l.471.242.529.026.287.445.445.287.026.529L5 13l-.242.471-.026.529-.445.287-.287.445-.529.026L3 15l-.471-.242L2 14.732l-.287-.445L1.268 14l-.026-.529L1 13l.242-.471.026-.529.445-.287.287-.445.529-.026L3 11z"/>
+ </symbol>
+ <symbol id="ui-radios" viewBox="0 0 16 16">
+ <path d="M7 2.5a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-7a.5.5 0 0 1-.5-.5v-1zM0 12a3 3 0 1 1 6 0 3 3 0 0 1-6 0zm7-1.5a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-7a.5.5 0 0 1-.5-.5v-1zm0-5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5zm0 8a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5zM3 1a3 3 0 1 0 0 6 3 3 0 0 0 0-6zm0 4.5a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z"/>
+ </symbol>
+</svg>
diff --git a/site/layouts/partials/scripts.html b/site/layouts/partials/scripts.html
index 2b70521f5d..5e2e52e90b 100644
--- a/site/layouts/partials/scripts.html
+++ b/site/layouts/partials/scripts.html
@@ -25,8 +25,7 @@
// Open in StackBlitz logic
document.querySelectorAll('.btn-edit').forEach(btn => {
btn.addEventListener('click', event => {
- const htmlSnippet = event.target.closest('.bd-edit').previousSibling.innerHTML
-
+ const htmlSnippet = event.target.closest('.bd-code-snippet').querySelector('.bd-example').innerHTML
StackBlitzSDK.openBootstrapSnippet(htmlSnippet)
})
})
diff --git a/site/layouts/shortcodes/example.html b/site/layouts/shortcodes/example.html
index a808c2589a..9dab2f9d1a 100644
--- a/site/layouts/shortcodes/example.html
+++ b/site/layouts/shortcodes/example.html
@@ -15,17 +15,30 @@
{{- $show_markup := .Get "show_markup" | default true -}}
{{- $input := .Inner -}}
-{{- if eq $show_preview true -}}
-<div{{ with $id }} id="{{ . }}"{{ end }} class="bd-example{{ with $class }} {{ . }}{{ end }}">
- {{- $input -}}
-</div>
-{{- end -}}
-
-{{- if eq $show_markup true -}}
- <div class="bd-edit">
- <button type="button" class="btn-edit text-nowrap" title="Try it on StackBlitz">Try it</button>
+<div class="bd-example-snippet bd-code-snippet">
+ {{- if eq $show_preview true -}}
+ <div{{ with $id }} id="{{ . }}"{{ end }} class="bd-example{{ with $class }} {{ . }}{{ end }}">
+ {{- $input -}}
</div>
- {{- $content := replaceRE `<svg class="bd-placeholder-img(?:-lg)?(?: *?bd-placeholder-img-lg)? ?(.*?)".*?<\/svg>\n` `<img src="..." class="$1" alt="...">` $input -}}
- {{- $content = replaceRE ` (class=" *?")` "" $content -}}
- {{- highlight (trim $content "\n") $lang "" -}}
-{{- end -}}
+ {{- end -}}
+
+ {{- if eq $show_markup true -}}
+ {{- if eq $show_preview true -}}
+ <div class="d-flex align-items-center highlight-toolbar bg-light ps-3 pe-2 py-1">
+ <small class="font-monospace text-muted text-uppercase">{{- $lang -}}</small>
+ <div class="d-flex ms-auto">
+ <button type="button" class="btn-edit text-nowrap" title="Try it on StackBlitz">
+ <svg class="bi" width="1em" height="1em" fill="currentColor" role="img" aria-label="Copy"><use xlink:href="#lightning-charge-fill"/></svg>
+ </button>
+ <button type="button" class="btn-clipboard" title="Copy to clipboard">
+ <svg class="bi" width="1em" height="1em" fill="currentColor" role="img" aria-label="Copy"><use xlink:href="#clipboard"/></svg>
+ </button>
+ </div>
+ </div>
+ {{- end -}}
+
+ {{- $content := replaceRE `<svg class="bd-placeholder-img(?:-lg)?(?: *?bd-placeholder-img-lg)? ?(.*?)".*?<\/svg>\n` `<img src="..." class="$1" alt="...">` $input -}}
+ {{- $content = replaceRE ` (class=" *?")` "" $content -}}
+ {{- highlight (trim $content "\n") $lang "" -}}
+ {{- end -}}
+</div>
diff --git a/site/static/docs/5.1/assets/img/examples/navbars-offcanvas.png b/site/static/docs/5.1/assets/img/examples/navbars-offcanvas.png
new file mode 100644
index 0000000000..81b000dbfb
--- /dev/null
+++ b/site/static/docs/5.1/assets/img/examples/navbars-offcanvas.png
Binary files differ
diff --git a/site/static/docs/5.1/assets/img/examples/navbars-offcanvas@2x.png b/site/static/docs/5.1/assets/img/examples/navbars-offcanvas@2x.png
new file mode 100644
index 0000000000..af5313436f
--- /dev/null
+++ b/site/static/docs/5.1/assets/img/examples/navbars-offcanvas@2x.png
Binary files differ