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>
This commit is contained in:
Mark Otto 2022-04-17 22:17:50 -07:00 committed by GitHub
parent 26ea6f1649
commit 195440f2fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
51 changed files with 1581 additions and 634 deletions

View File

@ -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",

View File

@ -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)
/**

View File

@ -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', () => {

View File

@ -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;
}
}
}
}

View File

@ -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);
// stylelint-disable function-disallowed-list
&.showing,
&.show:not(.hiding) {
transform: none;
%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;
}
}
&.showing,
&.hiding,
&.show {
visibility: visible;
@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%);
}
&.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%);
}

View File

@ -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;
}

View File

@ -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 })
})
})()

View File

@ -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 })
})
})()

View File

@ -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',

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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;
}
.highlight {
background-color: rgba($black, .05);
}
}
// Variations
.bd-callout-info {
border-left-color: $bd-info;
}
.bd-callout-warning {
border-left-color: $bd-warning;
}
.bd-callout-danger {
border-left-color: $bd-danger;
@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);
}
}

View File

@ -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;
}
}

View File

@ -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-content .highlight {
margin-right: $bd-gutter-x * -1;
margin-left: $bd-gutter-x * -1;
.bd-example-snippet {
.highlight {
@include border-top-radius(0);
border: 1px solid $border-color;
}
.highlight-toolbar {
border: solid $border-color;
border-width: 0 1px;
}
}
@include media-breakpoint-up(sm) {
.bd-content .highlight {
margin-right: $bd-gutter-x * -.5;
margin-left: $bd-gutter-x * -.5;
@include media-breakpoint-up(md) {
margin-right: 0;
margin-left: 0;
}

View File

@ -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;
}
> 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;
}
}

View File

@ -1,16 +1,14 @@
.bd-layout {
padding-right: $bd-gutter-x;
padding-left: $bd-gutter-x;
.bd-gutter {
--bs-gutter-x: #{$bd-gutter-x};
}
@include media-breakpoint-up(md) {
display: grid;
grid-template-areas: "sidebar main";
grid-template-columns: 1fr 3fr;
gap: $grid-gutter-width;
}
.bd-layout {
@include media-breakpoint-up(lg) {
display: grid;
grid-template-areas: "sidebar main";
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:

View File

@ -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) {
color: $gray-700;
}
.btn {
padding: .8rem 2rem;
font-weight: 600;
}
.lead {
@include font-size(1.5rem);
@include font-size(1rem);
font-weight: 400;
color: $gray-700;
}
.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);
}
}
}
@include media-breakpoint-up(md) {
.mw-md-75 { max-width: 75%; }
.masthead-followup {
.lead {
@include font-size(1rem);
}
.highlight {
@include border-radius(.5rem);
}
@include media-breakpoint-up(md) {
.lead {
@include font-size(1.25rem);
}
}
}
.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);
}

View File

@ -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,
&:focus {
color: $white;
}
&:hover {
transform: rotate(-5deg) scale(1.1);
}
}
&.active {
font-weight: 600;
color: $white;
}
.navbar-toggler,
.nav-link {
padding-right: $spacer * .25;
padding-left: $spacer * .25;
color: rgba($white, .85);
&: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;
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
.bd-links-nav {
@include media-breakpoint-down(lg) {
font-size: .875rem;
}
a {
padding: .1875rem .5rem;
margin-top: .125rem;
margin-left: 1.25rem;
color: rgba($black, .65);
text-decoration: if($link-decoration == none, null, none);
@include media-breakpoint-between(xs, lg) {
column-count: 2;
column-gap: 1.5rem;
&:hover,
&:focus {
color: rgba($black, .85);
text-decoration: if($link-hover-decoration == underline, none, null);
background-color: rgba($bd-violet, .1);
}
}
.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;
&: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);
.bd-links-span-all {
column-span: all;
}
// 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%;
}
&[aria-expanded="true"] {
color: rgba($black, .85);
&::before {
transform: rotate(90deg);
}
}
}
.active {
font-weight: 600;
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);
&: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 {
font-weight: 600;
}
}

View File

@ -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; }
}
}

View File

@ -101,7 +101,7 @@
.language-bash,
.language-sh {
&::before {
color: #009;
color: #777;
content: "$ ";
user-select: none;
}

View File

@ -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
}
}

View File

@ -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)};
}

View File

@ -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";

View File

@ -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 dont 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

View File

@ -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 >}}

View File

@ -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>

View File

@ -0,0 +1,7 @@
body {
padding-bottom: 20px;
}
.navbar {
margin-bottom: 20px;
}

View File

@ -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). |

View File

@ -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

View File

@ -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

47
site/data/plugins.yml Normal file
View File

@ -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/

View File

@ -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

View File

@ -5,6 +5,7 @@
</head>
{{ block "body_override" . }}<body>{{ end }}
{{ partial "skippy" . }}
{{ partial "icons" . }}
{{ partial "docs-navbar" . }}

View File

@ -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 }}

View File

@ -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>. Theyre built as their own extended frameworks, rich with new components and plugins, documentation, and powerful build tools.
</p>

View File

@ -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 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.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.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{{ 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" 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.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.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.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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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">

View File

@ -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">

View File

@ -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 Bootstraps source Sass and JavaScript files via npm, Composer, or Meteor.
</p>
<p>Package managed installs dont 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 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>
<div class="col-md-7 ps-md-5">
<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 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 Bootstraps source Sass and JavaScript files via npm, RubyGems, Composer, or Meteor. Package managed installs dont 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" "" }}
</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-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 Bootstraps compiled CSS or JS, you can use <a href="https://www.jsdelivr.com/">jsDelivr</a>.
</p>
<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 Bootstraps 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 Bootstraps 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 theyll work in any project. Theyre 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"

View File

@ -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 worlds 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>

View File

@ -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>

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -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)
})
})

View File

@ -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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB