From 979f8c9ff6faf6dd704fca4be5d3d9858ad0503a Mon Sep 17 00:00:00 2001 From: Mark Otto Date: Wed, 12 Aug 2026 15:46:47 -0700 Subject: [PATCH 1/3] docs: center preview content in example previews Wrap example preview markup in a `.bd-example-content` element so the frame can center content on both axes and apply a min-height. Loose inline items (buttons, badges, links) center in a row, while block components keep their own text alignment and get centered horizontally. Retarget the StackBlitz export to the new wrapper so exported markup and author classes stay correct. --- site/src/assets/stackblitz.js | 8 ++- site/src/components/shortcodes/Example.astro | 6 +- site/src/scss/_component-examples.scss | 74 ++++++++++++++------ 3 files changed, 62 insertions(+), 26 deletions(-) diff --git a/site/src/assets/stackblitz.js b/site/src/assets/stackblitz.js index ddb3d32cb80f..ffc8abcc6183 100644 --- a/site/src/assets/stackblitz.js +++ b/site/src/assets/stackblitz.js @@ -23,12 +23,14 @@ export default () => { document.querySelectorAll('.btn-edit').forEach(btn => { btn.addEventListener('click', event => { const codeSnippet = event.target.closest('.bd-code-snippet') - const exampleEl = codeSnippet.querySelector('.bd-example') + // The preview markup and any author-supplied classes live on the inner + // content wrapper. Fall back to `.bd-example` for older markup. + const exampleEl = codeSnippet.querySelector('.bd-example-content') || codeSnippet.querySelector('.bd-example') const htmlSnippet = exampleEl.innerHTML const jsSnippet = codeSnippet.querySelector('.btn-edit').getAttribute('data-sb-js-snippet') - // Get extra classes for this example - const classes = [...exampleEl.classList].join(' ') + // Get extra classes for this example, minus the docs-only wrapper class + const classes = [...exampleEl.classList].filter(cls => cls !== 'bd-example-content').join(' ') openBootstrapSnippet(htmlSnippet, jsSnippet, classes) }) diff --git a/site/src/components/shortcodes/Example.astro b/site/src/components/shortcodes/Example.astro index f74dfe22d91d..276c7ec2a779 100644 --- a/site/src/components/shortcodes/Example.astro +++ b/site/src/components/shortcodes/Example.astro @@ -86,8 +86,10 @@ const simplifiedMarkup = sourceMarkup
{ showPreview && ( -
- +
+
+ +
) } diff --git a/site/src/scss/_component-examples.scss b/site/src/scss/_component-examples.scss index d2d114302465..12e962bcdc89 100644 --- a/site/src/scss/_component-examples.scss +++ b/site/src/scss/_component-examples.scss @@ -51,8 +51,13 @@ } .bd-example { + --bd-example-min-height: 12rem; + position: relative; - display: flow-root; + display: flex; + flex-direction: column; + justify-content: center; // vertically center the content wrapper + min-height: var(--bd-example-min-height); padding: var(--bd-example-padding); font-size: var(--body-font-size); line-height: var(--body-line-height); @@ -66,6 +71,51 @@ margin-top: 2rem; } + // Navbars + .fixed-top, + .sticky-top { + position: static !important; // stylelint-disable-line + margin: calc(-1 * var(--bd-example-padding)) calc(-1 * var(--bd-example-padding)) var(--bd-example-padding); + } + + .fixed-bottom, + .sticky-bottom { + position: static !important; // stylelint-disable-line + margin: var(--bd-example-padding) calc(-1 * var(--bd-example-padding)) calc(-1 * var(--bd-example-padding)); + + } + + // Pagination + .pagination { + margin-bottom: 0; + } + } + + // Preview content wrapper. It keeps normal flow so loose inline items (buttons, + // badges, links) stay on one centered line, while block components keep full + // width. The frame centers this wrapper vertically. + .bd-example-content { + display: flow-root; + width: 100%; + text-align: center; + // Inert in normal flow. When an example sets `d-flex`/`d-grid`/`vstack` on + // the wrapper, this centers the row on the main axis. Utilities still win. + justify-content: center; + + // Keep block-level components left-aligned inside. Only loose inline items + // (buttons, badges, links, icons) pick up the centered text-align above. + // Utilities still win via layer order, so `.text-center` etc. is unaffected. + > * { + text-align: start; + } + + // Center width-constrained block components (cards, wrappers). Full-width + // blocks (alerts, forms) are unaffected. Grid rows keep their negative + // gutters, so exclude `.row` and grid containers. + > *:not(.row):not([class*="grid"]) { + margin-inline: auto; + } + > .tab-content { min-height: 120px; padding: var(--bs-spacer); @@ -75,9 +125,9 @@ > .menu.position-static { max-width: fit-content; + margin-inline: auto; } - // > :last-child, > nav:last-child .breadcrumb { margin-bottom: 0; } @@ -95,30 +145,12 @@ // List groups > .list-group { max-width: 400px; + margin-inline: auto; } > [class*="list-group-horizontal"] { max-width: 100%; } - - // Navbars - .fixed-top, - .sticky-top { - position: static !important; // stylelint-disable-line - margin: calc(-1 * var(--bd-example-padding)) calc(-1 * var(--bd-example-padding)) var(--bd-example-padding); - } - - .fixed-bottom, - .sticky-bottom { - position: static !important; // stylelint-disable-line - margin: var(--bd-example-padding) calc(-1 * var(--bd-example-padding)) calc(-1 * var(--bd-example-padding)); - - } - - // Pagination - .pagination { - margin-bottom: 0; - } } // From fc0f0974c2afc8febb39eb22b29a85d2189b26ae Mon Sep 17 00:00:00 2001 From: Mark Otto Date: Wed, 19 Aug 2026 21:06:56 -0700 Subject: [PATCH 2/3] fix(docs): satisfy stylelint in example preview CSS Put justify-content before text-align and use a single :not(). --- site/src/scss/_component-examples.scss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/site/src/scss/_component-examples.scss b/site/src/scss/_component-examples.scss index 12e962bcdc89..df0249dda43e 100644 --- a/site/src/scss/_component-examples.scss +++ b/site/src/scss/_component-examples.scss @@ -96,11 +96,11 @@ // width. The frame centers this wrapper vertically. .bd-example-content { display: flow-root; - width: 100%; - text-align: center; // Inert in normal flow. When an example sets `d-flex`/`d-grid`/`vstack` on // the wrapper, this centers the row on the main axis. Utilities still win. justify-content: center; + width: 100%; + text-align: center; // Keep block-level components left-aligned inside. Only loose inline items // (buttons, badges, links, icons) pick up the centered text-align above. @@ -112,7 +112,7 @@ // Center width-constrained block components (cards, wrappers). Full-width // blocks (alerts, forms) are unaffected. Grid rows keep their negative // gutters, so exclude `.row` and grid containers. - > *:not(.row):not([class*="grid"]) { + > *:not(.row, [class*="grid"]) { margin-inline: auto; } From 69be1e096627bf31cc1d8d1e2d275429d6fcb7a5 Mon Sep 17 00:00:00 2001 From: Mark Otto Date: Thu, 20 Aug 2026 13:43:33 -0700 Subject: [PATCH 3/3] docs: center flexbox example content on the cross axis Add `align-items: center` to `.bd-example-content` so examples that turn the wrapper into a flexbox (`d-flex`, `vstack`, `hstack`) center their items horizontally, instead of sitting left in the tall min-height frame. Exclude grid wrappers so grid items keep stretching to equal heights. --- site/src/scss/_component-examples.scss | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/site/src/scss/_component-examples.scss b/site/src/scss/_component-examples.scss index df0249dda43e..baf44f88c07e 100644 --- a/site/src/scss/_component-examples.scss +++ b/site/src/scss/_component-examples.scss @@ -102,6 +102,14 @@ width: 100%; text-align: center; + // When an example turns the wrapper into a flexbox (`d-flex`, `vstack`, + // `hstack`), center its items on the cross axis too, so column layouts do + // not sit left in the tall min-height frame. Grid wrappers are excluded so + // grid items keep stretching to equal heights. + &:not([class*="grid"]) { + align-items: center; + } + // Keep block-level components left-aligned inside. Only loose inline items // (buttons, badges, links, icons) pick up the centered text-align above. // Utilities still win via layer order, so `.text-center` etc. is unaffected.