From 90b7cc661ecb1640fe01d513a00fcaaddd6c0c48 Mon Sep 17 00:00:00 2001 From: Mark Otto Date: Thu, 18 Sep 2025 19:55:53 -0700 Subject: [PATCH] v6: Add reference tables to utilities docs, add community links to some pages (MDN, CSS Tricks) (#41749) * wip * improve * Add more utility refs * Remove important flag from the utilities * update * Start on helpers * fixes * fix links --- .cspell.json | 1 + scss/_config.scss | 2 +- scss/_root.scss | 4 +- site/data/sidebar.yml | 3 +- site/src/components/ReferenceTable.astro | 108 ++++++++++++ site/src/components/icons/CssTricksIcon.astro | 19 +++ site/src/components/icons/MdnIcon.astro | 17 ++ site/src/content/config.ts | 18 ++ site/src/content/docs/components/card.mdx | 2 +- site/src/content/docs/content/images.mdx | 2 +- site/src/content/docs/content/tables.mdx | 2 +- site/src/content/docs/helpers/position.mdx | 9 + site/src/content/docs/layout/css-grid.mdx | 3 + site/src/content/docs/layout/grid.mdx | 3 + site/src/content/docs/migration.mdx | 4 +- site/src/content/docs/utilities/api.mdx | 122 +++++++------- .../content/docs/utilities/aspect-ratio.mdx | 17 ++ .../src/content/docs/utilities/background.mdx | 3 +- .../content/docs/utilities/border-radius.mdx | 88 ++++++++++ .../utilities/{borders.mdx => border.mdx} | 139 ++++++++++++---- site/src/content/docs/utilities/colors.mdx | 2 +- site/src/content/docs/utilities/display.mdx | 37 +++++ site/src/content/docs/utilities/flex.mdx | 4 + site/src/content/docs/utilities/float.mdx | 10 ++ .../content/docs/utilities/interactions.mdx | 16 ++ .../src/content/docs/utilities/object-fit.mdx | 16 ++ site/src/content/docs/utilities/opacity.mdx | 16 ++ site/src/content/docs/utilities/overflow.mdx | 37 +++++ site/src/content/docs/utilities/position.mdx | 61 +++++++ site/src/content/docs/utilities/shadows.mdx | 13 ++ site/src/content/docs/utilities/sizing.mdx | 79 +++++++++ site/src/content/docs/utilities/spacing.mdx | 112 ++++++++++++- site/src/content/docs/utilities/text.mdx | 98 +++++++++++ .../content/docs/utilities/vertical-align.mdx | 19 +++ .../src/content/docs/utilities/visibility.mdx | 11 +- site/src/content/docs/utilities/z-index.mdx | 16 ++ site/src/layouts/DocsLayout.astro | 157 +++++++++++++++--- site/src/scss/_content.scss | 37 ++++- 38 files changed, 1160 insertions(+), 147 deletions(-) create mode 100644 site/src/components/ReferenceTable.astro create mode 100644 site/src/components/icons/CssTricksIcon.astro create mode 100644 site/src/components/icons/MdnIcon.astro create mode 100644 site/src/content/docs/utilities/border-radius.mdx rename site/src/content/docs/utilities/{borders.mdx => border.mdx} (61%) diff --git a/.cspell.json b/.cspell.json index d2434c30a6..191c9bc05c 100644 --- a/.cspell.json +++ b/.cspell.json @@ -29,6 +29,7 @@ "Crossfade", "crossfading", "cssgrid", + "csstricks", "Csvg", "Datalists", "Deque", diff --git a/scss/_config.scss b/scss/_config.scss index 7215edea2c..34c1abb54c 100644 --- a/scss/_config.scss +++ b/scss/_config.scss @@ -19,7 +19,7 @@ $enable-rfs: true !default; $enable-validation-icons: true !default; $enable-negative-margins: false !default; $enable-deprecation-messages: true !default; -$enable-important-utilities: true !default; +$enable-important-utilities: false !default; $enable-dark-mode: true !default; $color-mode-type: data !default; // `data` or `media-query` diff --git a/scss/_root.scss b/scss/_root.scss index 31523403b2..9a7ee1f91d 100644 --- a/scss/_root.scss +++ b/scss/_root.scss @@ -158,14 +158,16 @@ --#{$prefix}border-style: #{$border-style}; --#{$prefix}border-color: #{$border-color}; --#{$prefix}border-color-translucent: #{$border-color-translucent}; + // scss-docs-end root-border-var + // scss-docs-start root-border-radius-var --#{$prefix}border-radius: #{$border-radius}; --#{$prefix}border-radius-sm: #{$border-radius-sm}; --#{$prefix}border-radius-lg: #{$border-radius-lg}; --#{$prefix}border-radius-xl: #{$border-radius-xl}; --#{$prefix}border-radius-xxl: #{$border-radius-xxl}; --#{$prefix}border-radius-pill: #{$border-radius-pill}; - // scss-docs-end root-border-var + // scss-docs-end root-border-radius-var --#{$prefix}box-shadow: #{$box-shadow}; --#{$prefix}box-shadow-sm: #{$box-shadow-sm}; diff --git a/site/data/sidebar.yml b/site/data/sidebar.yml index b5fd2d2818..fcaffa4941 100644 --- a/site/data/sidebar.yml +++ b/site/data/sidebar.yml @@ -119,7 +119,8 @@ - title: API - title: Aspect ratio - title: Background - - title: Borders + - title: Border + - title: Border radius - title: Colors - title: Display - title: Flex diff --git a/site/src/components/ReferenceTable.astro b/site/src/components/ReferenceTable.astro new file mode 100644 index 0000000000..cff8ca55ad --- /dev/null +++ b/site/src/components/ReferenceTable.astro @@ -0,0 +1,108 @@ +--- +interface ReferenceItem { + class: string; + styles: string | string[] | Record; + [key: string]: any; // Allow additional properties +} + +interface Props { + className?: string; + columns?: Array<{ label: string; key: string }>; + data?: Array; + reference?: Array; // Direct prop for reference data +} + +const { + className = "table reference-table", + columns, + data, + reference +} = Astro.props; + +// Use explicit reference prop or data prop +const referenceData = reference || data || []; + +// If no explicit columns provided, infer from the first data item +const inferredColumns = columns || (() => { + if (referenceData.length === 0) { + return [ + { label: 'Class', key: 'class' }, + { label: 'Styles', key: 'styles' } + ]; + } + + const firstItem = referenceData[0]; + return Object.keys(firstItem).map(key => ({ + label: key.charAt(0).toUpperCase() + key.slice(1), // Capitalize first letter + key: key + })); +})(); + +// Transform frontmatter format to table format +const tableData = referenceData.map((item: ReferenceItem) => { + const transformedItem: Record = {}; + + inferredColumns.forEach(column => { + const key = column.key; + let value = item[key]; + + if (key === 'class' && typeof value === 'string' && !value.startsWith('.')) { + value = `.${value}`; + } + + if (key === 'styles') { + if (typeof value === 'string') { + transformedItem[key] = value; + } else if (typeof value === 'object' && !Array.isArray(value)) { + // Handle object syntax: { prop: value, prop2: value2 } + transformedItem[key] = Object.entries(value) + .map(([prop, val]) => `${prop}: ${val};`) + .join('
'); + } else if (Array.isArray(value)) { + transformedItem[key] = value.map((style: any) => { + if (typeof style === 'string') { + return style.includes(':') ? style + (style.endsWith(';') ? '' : ';') : style; + } + if (typeof style === 'object') { + return Object.entries(style).map(([prop, val]) => `${prop}: ${val};`).join(' '); + } + return style; + }).join('
'); + } else { + transformedItem[key] = value || ''; + } + } else { + transformedItem[key] = value; + } + }); + + return transformedItem; +}); +--- + +
+ + + + {inferredColumns.map(column => ( + + ))} + + + + {tableData.map((row: any) => ( + + {inferredColumns.map(column => ( + + ))} + + ))} + +
{column.label}
+ {column.key === 'styles' ? ( + + ) : ( + row[column.key] + )} +
+
diff --git a/site/src/components/icons/CssTricksIcon.astro b/site/src/components/icons/CssTricksIcon.astro new file mode 100644 index 0000000000..4df46d4c02 --- /dev/null +++ b/site/src/components/icons/CssTricksIcon.astro @@ -0,0 +1,19 @@ +--- +import type { SvgIconProps } from '@libs/icon' + +type Props = SvgIconProps + +const { class: className, height, width } = Astro.props +--- + + + CSS-Tricks + + diff --git a/site/src/components/icons/MdnIcon.astro b/site/src/components/icons/MdnIcon.astro new file mode 100644 index 0000000000..941363dca7 --- /dev/null +++ b/site/src/components/icons/MdnIcon.astro @@ -0,0 +1,17 @@ +--- +import type { SvgIconProps } from '@libs/icon' +type Props = SvgIconProps +const { class: className, height, width } = Astro.props +--- + + + MDN + + diff --git a/site/src/content/config.ts b/site/src/content/config.ts index 387a0052eb..8a55637adc 100644 --- a/site/src/content/config.ts +++ b/site/src/content/config.ts @@ -8,6 +8,15 @@ const docsSchema = z.object({ }) .optional(), aliases: z.string().or(z.string().array()).optional(), + csstricks: z + .union([ + z.string(), + z.object({ + url: z.string(), + label: z.string().optional() + }) + ]) + .optional(), description: z.string(), direction: z.literal('rtl').optional(), extra_js: z @@ -17,6 +26,15 @@ const docsSchema = z.object({ }) .array() .optional(), + mdn: z.string().optional(), + reference: z + .object({ + class: z.string(), + description: z.string().optional(), + styles: z.union([z.string(), z.string().array(), z.record(z.string())]).optional() + }) + .array() + .optional(), sections: z .object({ description: z.string(), diff --git a/site/src/content/docs/components/card.mdx b/site/src/content/docs/components/card.mdx index 99b14d6194..c1af4c11b3 100644 --- a/site/src/content/docs/components/card.mdx +++ b/site/src/content/docs/components/card.mdx @@ -393,7 +393,7 @@ Set a `background-color` with contrasting foreground `color` with [our `.text-bg ### Border -Use [border utilities]([[docsref:/utilities/borders]]) to change just the `border-color` of a card. Note that you can put `.text-{color}` classes on the parent `.card` or a subset of the card’s contents as shown below. +Use [border utilities]([[docsref:/utilities/border]]) to change just the `border-color` of a card. Note that you can put `.text-{color}` classes on the parent `.card` or a subset of the card’s contents as shown below. `
Header
diff --git a/site/src/content/docs/content/images.mdx b/site/src/content/docs/content/images.mdx index a697d21fa7..10b4595182 100644 --- a/site/src/content/docs/content/images.mdx +++ b/site/src/content/docs/content/images.mdx @@ -12,7 +12,7 @@ Images in Bootstrap are made responsive with `.img-fluid`. This applies `max-wid ## Image thumbnails -In addition to our [border-radius utilities]([[docsref:/utilities/borders]]), you can use `.img-thumbnail` to give an image a rounded 1px border appearance. +In addition to our [border-radius utilities]([[docsref:/utilities/border]]), you can use `.img-thumbnail` to give an image a rounded 1px border appearance. `} /> diff --git a/site/src/content/docs/content/tables.mdx b/site/src/content/docs/content/tables.mdx index 39e8d8a9a5..311a7b915d 100644 --- a/site/src/content/docs/content/tables.mdx +++ b/site/src/content/docs/content/tables.mdx @@ -237,7 +237,7 @@ Add `.table-bordered` for borders on all sides of the table and cells. -[Border color utilities]([[docsref:/utilities/borders#border-color]]) can be added to change colors: +[Border color utilities]([[docsref:/utilities/border#border-color]]) can be added to change colors:
diff --git a/site/src/content/docs/helpers/position.mdx b/site/src/content/docs/helpers/position.mdx index 4ccbf7777f..942968ff84 100644 --- a/site/src/content/docs/helpers/position.mdx +++ b/site/src/content/docs/helpers/position.mdx @@ -2,6 +2,15 @@ title: Position description: Use these helpers for quickly configuring the position of an element. toc: true +reference: + - class: 'fixed-top' + description: 'Fix an element to the top of the viewport.' + - class: 'fixed-bottom' + description: 'Fix an element to the bottom of the viewport.' + - class: '.sticky{-$infix}-top' + description: 'Responsively sticky an element to the top of the viewport.' + - class: '.sticky{-$infix}-bottom' + description: 'Responsively sticky an element to the bottom of the viewport.' --- ## Fixed top diff --git a/site/src/content/docs/layout/css-grid.mdx b/site/src/content/docs/layout/css-grid.mdx index a302ad8ea1..55d5bbfaeb 100644 --- a/site/src/content/docs/layout/css-grid.mdx +++ b/site/src/content/docs/layout/css-grid.mdx @@ -2,6 +2,9 @@ title: CSS Grid description: Learn how to enable, use, and customize our alternate layout system built on CSS Grid with examples and code snippets. toc: true +csstricks: + url: https://css-tricks.com/snippets/css/complete-guide-grid/ + label: CSS Grid Guide --- Bootstrap’s default grid system represents the culmination of over a decade of CSS layout techniques, tried and tested by millions of people. But, it was also created without many of the modern CSS features and techniques we’re seeing in browsers like the new CSS Grid. diff --git a/site/src/content/docs/layout/grid.mdx b/site/src/content/docs/layout/grid.mdx index c540ad9c63..015963a68a 100644 --- a/site/src/content/docs/layout/grid.mdx +++ b/site/src/content/docs/layout/grid.mdx @@ -2,6 +2,9 @@ title: Grid system description: Use our powerful mobile-first flexbox grid to build layouts of all shapes and sizes thanks to a twelve column system, six default responsive tiers, Sass variables and mixins, and dozens of predefined classes. toc: true +csstricks: + url: https://css-tricks.com/snippets/css/a-guide-to-flexbox/ + label: Flexbox Guide --- ## Example diff --git a/site/src/content/docs/migration.mdx b/site/src/content/docs/migration.mdx index d526bcc97e..ed8d6fb99e 100644 --- a/site/src/content/docs/migration.mdx +++ b/site/src/content/docs/migration.mdx @@ -307,7 +307,7 @@ Your custom Bootstrap CSS builds should now look something like this with a sepa ### New utilities - Expanded [`font-weight` utilities]([[docsref:/utilities/text#font-weight-and-italics]]) to include `.fw-semibold` for semibold fonts. -- Expanded [`border-radius` utilities]([[docsref:/utilities/borders#sizes]]) to include two new sizes, `.rounded-4` and `.rounded-5`, for more options. +- Expanded [`border-radius` utilities]([[docsref:/utilities/border-radius#sizes]]) to include two new sizes, `.rounded-4` and `.rounded-5`, for more options. ### Additional changes @@ -685,7 +685,7 @@ Want more information? [Read the v5.1.0 blog post.](https://blog.getbootstrap.co - Added new `.translate-middle-x` & `.translate-middle-y` utilities to horizontally or vertically center absolute/fixed positioned elements. -- Added new [`border-width` utilities]([[docsref:/utilities/borders#border-width]]). +- Added new [`border-width` utilities]([[docsref:/utilities/border#border-width]]). - Breaking Renamed `.text-monospace` to `.font-monospace`. diff --git a/site/src/content/docs/utilities/api.mdx b/site/src/content/docs/utilities/api.mdx index 58c833777a..a3a3631170 100644 --- a/site/src/content/docs/utilities/api.mdx +++ b/site/src/content/docs/utilities/api.mdx @@ -70,9 +70,9 @@ $utilities: ( Output: ```css -.text-decoration-none { text-decoration: none !important; } -.text-decoration-underline { text-decoration: underline !important; } -.text-decoration-line-through { text-decoration: line-through !important; } +.text-decoration-none { text-decoration: none; } +.text-decoration-underline { text-decoration: underline; } +.text-decoration-line-through { text-decoration: line-through; } ``` ### Values @@ -126,11 +126,11 @@ $utilities: ( Output: ```css -.o-0 { opacity: 0 !important; } -.o-25 { opacity: .25 !important; } -.o-50 { opacity: .5 !important; } -.o-75 { opacity: .75 !important; } -.o-100 { opacity: 1 !important; } +.o-0 { opacity: 0; } +.o-25 { opacity: .25; } +.o-50 { opacity: .5; } +.o-75 { opacity: .75; } +.o-100 { opacity: 1; } ``` If `class: null`, generates classes for each of the `values` keys: @@ -151,8 +151,8 @@ $utilities: ( Output: ```css -.visible { visibility: visible !important; } -.invisible { visibility: hidden !important; } +.visible { visibility: visible; } +.invisible { visibility: hidden; } ``` ### CSS variable utilities @@ -213,7 +213,7 @@ Output: ```css .bg-primary { --bs-bg-opacity: 1; - background-color: rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important; + background-color: rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)); } ``` @@ -243,11 +243,11 @@ $utilities: ( Output: ```css -.opacity-0-hover:hover { opacity: 0 !important; } -.opacity-25-hover:hover { opacity: .25 !important; } -.opacity-50-hover:hover { opacity: .5 !important; } -.opacity-75-hover:hover { opacity: .75 !important; } -.opacity-100-hover:hover { opacity: 1 !important; } +.opacity-0-hover:hover { opacity: 0; } +.opacity-25-hover:hover { opacity: .25; } +.opacity-50-hover:hover { opacity: .5; } +.opacity-75-hover:hover { opacity: .75; } +.opacity-100-hover:hover { opacity: 1; } ``` ### Responsive @@ -273,50 +273,50 @@ $utilities: ( Output: ```css -.opacity-0 { opacity: 0 !important; } -.opacity-25 { opacity: .25 !important; } -.opacity-50 { opacity: .5 !important; } -.opacity-75 { opacity: .75 !important; } -.opacity-100 { opacity: 1 !important; } +.opacity-0 { opacity: 0; } +.opacity-25 { opacity: .25; } +.opacity-50 { opacity: .5; } +.opacity-75 { opacity: .75; } +.opacity-100 { opacity: 1; } @media (min-width: 576px) { - .opacity-sm-0 { opacity: 0 !important; } - .opacity-sm-25 { opacity: .25 !important; } - .opacity-sm-50 { opacity: .5 !important; } - .opacity-sm-75 { opacity: .75 !important; } - .opacity-sm-100 { opacity: 1 !important; } + .opacity-sm-0 { opacity: 0; } + .opacity-sm-25 { opacity: .25; } + .opacity-sm-50 { opacity: .5; } + .opacity-sm-75 { opacity: .75; } + .opacity-sm-100 { opacity: 1; } } @media (min-width: 768px) { - .opacity-md-0 { opacity: 0 !important; } - .opacity-md-25 { opacity: .25 !important; } - .opacity-md-50 { opacity: .5 !important; } - .opacity-md-75 { opacity: .75 !important; } - .opacity-md-100 { opacity: 1 !important; } + .opacity-md-0 { opacity: 0; } + .opacity-md-25 { opacity: .25; } + .opacity-md-50 { opacity: .5; } + .opacity-md-75 { opacity: .75; } + .opacity-md-100 { opacity: 1; } } @media (min-width: 992px) { - .opacity-lg-0 { opacity: 0 !important; } - .opacity-lg-25 { opacity: .25 !important; } - .opacity-lg-50 { opacity: .5 !important; } - .opacity-lg-75 { opacity: .75 !important; } - .opacity-lg-100 { opacity: 1 !important; } + .opacity-lg-0 { opacity: 0; } + .opacity-lg-25 { opacity: .25; } + .opacity-lg-50 { opacity: .5; } + .opacity-lg-75 { opacity: .75; } + .opacity-lg-100 { opacity: 1; } } @media (min-width: 1200px) { - .opacity-xl-0 { opacity: 0 !important; } - .opacity-xl-25 { opacity: .25 !important; } - .opacity-xl-50 { opacity: .5 !important; } - .opacity-xl-75 { opacity: .75 !important; } - .opacity-xl-100 { opacity: 1 !important; } + .opacity-xl-0 { opacity: 0; } + .opacity-xl-25 { opacity: .25; } + .opacity-xl-50 { opacity: .5; } + .opacity-xl-75 { opacity: .75; } + .opacity-xl-100 { opacity: 1; } } @media (min-width: 1400px) { - .opacity-xxl-0 { opacity: 0 !important; } - .opacity-xxl-25 { opacity: .25 !important; } - .opacity-xxl-50 { opacity: .5 !important; } - .opacity-xxl-75 { opacity: .75 !important; } - .opacity-xxl-100 { opacity: 1 !important; } + .opacity-xxl-0 { opacity: 0; } + .opacity-xxl-25 { opacity: .25; } + .opacity-xxl-50 { opacity: .5; } + .opacity-xxl-75 { opacity: .75; } + .opacity-xxl-100 { opacity: 1; } } ``` @@ -343,24 +343,28 @@ $utilities: ( Output: ```css -.opacity-0 { opacity: 0 !important; } -.opacity-25 { opacity: .25 !important; } -.opacity-50 { opacity: .5 !important; } -.opacity-75 { opacity: .75 !important; } -.opacity-100 { opacity: 1 !important; } +.opacity-0 { opacity: 0; } +.opacity-25 { opacity: .25; } +.opacity-50 { opacity: .5; } +.opacity-75 { opacity: .75; } +.opacity-100 { opacity: 1; } @media print { - .opacity-print-0 { opacity: 0 !important; } - .opacity-print-25 { opacity: .25 !important; } - .opacity-print-50 { opacity: .5 !important; } - .opacity-print-75 { opacity: .75 !important; } - .opacity-print-100 { opacity: 1 !important; } + .opacity-print-0 { opacity: 0; } + .opacity-print-25 { opacity: .25; } + .opacity-print-50 { opacity: .5; } + .opacity-print-75 { opacity: .75; } + .opacity-print-100 { opacity: 1; } } ``` ## Importance -All utilities generated by the API include `!important` to ensure they override components and modifier classes as intended. You can toggle this setting globally with the `$enable-important-utilities` variable (defaults to `true`). +Utilities generated by the API no longer include `!important` by default in v6. This is because we now use CSS layers to ensure utilities override components and modifier classes as intended. You can toggle this setting globally with the `$enable-important-utilities` variable (defaults to `false`). + +```scss +$enable-important-utilities: true; +``` ## Using the API @@ -612,8 +616,8 @@ Output: ```css /* rtl:begin:remove */ .text-break { - word-wrap: break-word !important; - word-break: break-word !important; + word-wrap: break-word; + word-break: break-word; } /* rtl:end:remove */ ``` diff --git a/site/src/content/docs/utilities/aspect-ratio.mdx b/site/src/content/docs/utilities/aspect-ratio.mdx index cec9e5de61..e31ccb46a8 100644 --- a/site/src/content/docs/utilities/aspect-ratio.mdx +++ b/site/src/content/docs/utilities/aspect-ratio.mdx @@ -2,6 +2,23 @@ title: Aspect ratio description: Make elements maintain specific aspect ratios. Perfect for handling videos, slideshow embeds, and more based on the width of the parent. toc: true +mdn: https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio +reference: + - class: ratio-auto + styles: + --bs-ratio: 'auto' + - class: ratio-1x1 + styles: + --bs-ratio: '1 / 1' + - class: ratio-4x3 + styles: + --bs-ratio: '4 / 3' + - class: ratio-16x9 + styles: + --bs-ratio: '16 / 9' + - class: ratio-21x9 + styles: + --bs-ratio: '21 / 9' --- Use the ratio utility to manage the aspect ratios of content like `