1
0
mirror of https://github.com/twbs/bootstrap.git synced 2025-09-25 12:59:05 +02:00

Remove !important from utilities, make it opt-in per utility (#41755)

* Remove !important from utilities, make it opt-in per utility

* package-lock

* Fix test
This commit is contained in:
Mark Otto
2025-09-21 22:12:17 -07:00
committed by GitHub
parent 21491d1f2f
commit e5a1ee3d3a
10 changed files with 105 additions and 33 deletions

21
package-lock.json generated
View File

@@ -7174,6 +7174,16 @@
"npm": "1.2.8000 || >= 1.4.16" "npm": "1.2.8000 || >= 1.4.16"
} }
}, },
"node_modules/detect-libc": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.0.tgz",
"integrity": "sha512-vEtk+OcP7VBRtQZ1EJ3bdgzSfBjgnEalLTp5zjJrS+2Z1w2KZly4SBdac/WDU3hhsNAZ9E8SC96ME4Ey8MZ7cg==",
"dev": true,
"optional": true,
"engines": {
"node": ">=8"
}
},
"node_modules/deterministic-object-hash": { "node_modules/deterministic-object-hash": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/deterministic-object-hash/-/deterministic-object-hash-2.0.2.tgz", "resolved": "https://registry.npmjs.org/deterministic-object-hash/-/deterministic-object-hash-2.0.2.tgz",
@@ -17109,17 +17119,6 @@
"@img/sharp-win32-x64": "0.34.4" "@img/sharp-win32-x64": "0.34.4"
} }
}, },
"node_modules/sharp/node_modules/detect-libc": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz",
"integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==",
"dev": true,
"license": "Apache-2.0",
"optional": true,
"engines": {
"node": ">=8"
}
},
"node_modules/sharp/node_modules/semver": { "node_modules/sharp/node_modules/semver": {
"version": "7.7.2", "version": "7.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",

View File

@@ -19,7 +19,6 @@ $enable-rfs: true !default;
$enable-validation-icons: true !default; $enable-validation-icons: true !default;
$enable-negative-margins: false !default; $enable-negative-margins: false !default;
$enable-deprecation-messages: true !default; $enable-deprecation-messages: true !default;
$enable-important-utilities: false !default;
$enable-dark-mode: true !default; $enable-dark-mode: true !default;
$color-mode-type: data !default; // `data` or `media-query` $color-mode-type: data !default; // `data` or `media-query`

View File

@@ -95,6 +95,7 @@ $utilities: map.merge(
print: true, print: true,
property: display, property: display,
class: d, class: d,
important: true,
values: inline inline-block block grid inline-grid table table-row table-cell flex inline-flex flow-root none values: inline inline-block block grid inline-grid table table-row table-cell flex inline-flex flow-root none
), ),
// scss-docs-end utils-display // scss-docs-end utils-display
@@ -121,6 +122,7 @@ $utilities: map.merge(
// scss-docs-start utils-position // scss-docs-start utils-position
"position": ( "position": (
property: position, property: position,
important: true,
values: static relative absolute fixed sticky values: static relative absolute fixed sticky
), ),
"top": ( "top": (
@@ -859,6 +861,7 @@ $utilities: map.merge(
"visibility": ( "visibility": (
property: visibility, property: visibility,
class: null, class: null,
important: true,
values: ( values: (
visible: visible, visible: visible,
invisible: hidden, invisible: hidden,

View File

@@ -94,7 +94,6 @@ $escaped-characters: (
// $enable-validation-icons: true !default; // $enable-validation-icons: true !default;
// $enable-negative-margins: false !default; // $enable-negative-margins: false !default;
// $enable-deprecation-messages: true !default; // $enable-deprecation-messages: true !default;
// $enable-important-utilities: true !default;
// $enable-dark-mode: true !default; // $enable-dark-mode: true !default;
// $color-mode-type: data !default; // `data` or `media-query` // $color-mode-type: data !default; // `data` or `media-query`

View File

@@ -6,8 +6,8 @@
// All-caps `RGBA()` function used because of this Sass bug: https://github.com/sass/node-sass/issues/2251 // All-caps `RGBA()` function used because of this Sass bug: https://github.com/sass/node-sass/issues/2251
@each $color, $value in $theme-colors { @each $color, $value in $theme-colors {
.text-bg-#{$color} { .text-bg-#{$color} {
color: color-contrast($value) if($enable-important-utilities, !important, null); color: color-contrast($value);
background-color: RGBA(var(--#{$prefix}#{$color}-rgb), var(--#{$prefix}bg-opacity, 1)) if($enable-important-utilities, !important, null); background-color: RGBA(var(--#{$prefix}#{$color}-rgb), var(--#{$prefix}bg-opacity, 1));
} }
} }
} }

View File

@@ -58,6 +58,7 @@
$is-css-var: map.get($utility, css-var); $is-css-var: map.get($utility, css-var);
$is-local-vars: map.get($utility, local-vars); $is-local-vars: map.get($utility, local-vars);
$is-rtl: map.get($utility, rtl); $is-rtl: map.get($utility, rtl);
$is-important: map.get($utility, important);
@if $value != null { @if $value != null {
@if $is-rtl == false { @if $is-rtl == false {
@@ -82,7 +83,7 @@
--#{$prefix}#{$local-var}: #{$variable}; --#{$prefix}#{$local-var}: #{$variable};
} }
} }
#{$property}: $value if($enable-important-utilities, !important, null); #{$property}: $value if($is-important, !important, null);
} }
} }
@@ -94,7 +95,7 @@
--#{$prefix}#{$local-var}: #{$variable}; --#{$prefix}#{$local-var}: #{$variable};
} }
} }
#{$property}: $value if($enable-important-utilities, !important, null); #{$property}: $value if($is-important, !important, null);
} }
} }
} }

View File

@@ -6,7 +6,6 @@
$true-terminal-output: false; $true-terminal-output: false;
$prefix: bs-; $prefix: bs-;
$enable-important-utilities: false;
// Important: Do not import rfs to check that the mixin just calls the appropriate functions from it // Important: Do not import rfs to check that the mixin just calls the appropriate functions from it
// @import "../../mixins/utilities"; // @import "../../mixins/utilities";
@@ -41,13 +40,12 @@ $enable-important-utilities: false;
} }
} }
@include describe("global $enable-important-utilities: true") { @include describe("per-utility important: true") {
@include it("sets !important") { @include it("sets !important") {
$enable-important-utilities: true !global;
@include test-generate-utility( @include test-generate-utility(
( (
property: "padding", property: "padding",
important: true,
values: (small: .5rem, large: 2rem) values: (small: .5rem, large: 2rem)
) )
) { ) {
@@ -59,8 +57,6 @@ $enable-important-utilities: false;
padding: 2rem !important; padding: 2rem !important;
} }
} }
$enable-important-utilities: false !global;
} }
} }

View File

@@ -1,8 +1,7 @@
@import "../../functions"; @use "../../functions";
@import "../../variables"; @use "../../variables";
@import "../../variables-dark"; @use "../../maps";
@import "../../maps"; @use "../../mixins";
@import "../../mixins";
$utilities: (); $utilities: ();
@@ -11,16 +10,19 @@ $utilities: ();
$utilities: ( $utilities: (
margin: ( margin: (
property: margin, property: margin,
important: true,
values: auto values: auto
), ),
padding: ( padding: (
property: padding, property: padding,
responsive: true, responsive: true,
important: true,
values: 1rem values: 1rem
), ),
font-size: ( font-size: (
property: font-size, property: font-size,
values: (large: 1.25rem), values: (large: 1.25rem),
important: true,
print: true print: true
) )
) !global; ) !global;
@@ -33,7 +35,7 @@ $utilities: ();
@include assert() { @include assert() {
@include output() { @include output() {
@import "../../utilities/api"; @use "../../utilities/api";
} }
@include expect() { @include expect() {
@@ -72,4 +74,53 @@ $utilities: ();
} }
} }
@include it("generates utilities without !important when important: false or not set") {
$utilities: (
opacity: (
property: opacity,
values: (
0: 0,
50: .5,
100: 1
)
),
text-align: (
property: text-align,
important: false,
values: (
start: left,
center: center
)
)
) !global;
@include assert() {
@include output() {
@import "../../utilities/api";
}
@include expect() {
.opacity-0 {
opacity: 0;
}
.opacity-50 {
opacity: .5;
}
.opacity-100 {
opacity: 1;
}
.text-align-start {
text-align: left;
}
.text-align-center {
text-align: center;
}
}
}
}
} }

View File

@@ -26,6 +26,5 @@ You can find and customize these variables for key global options in Bootstrap
| `$enable-validation-icons` | `true` (default) or `false` | Enables `background-image` icons within textual inputs and some custom forms for validation states. | | `$enable-validation-icons` | `true` (default) or `false` | Enables `background-image` icons within textual inputs and some custom forms for validation states. |
| `$enable-negative-margins` | `true` or `false` (default) | Enables the generation of [negative margin utilities]([[docsref:/utilities/spacing#negative-margin]]). | | `$enable-negative-margins` | `true` or `false` (default) | Enables the generation of [negative margin utilities]([[docsref:/utilities/spacing#negative-margin]]). |
| `$enable-deprecation-messages` | `true` (default) or `false` | Set to `false` to hide warnings when using any of the deprecated mixins and functions that are planned to be removed in `v6`. | | `$enable-deprecation-messages` | `true` (default) or `false` | Set to `false` to hide warnings when using any of the deprecated mixins and functions that are planned to be removed in `v6`. |
| `$enable-important-utilities` | `true` (default) or `false` | Enables the `!important` suffix in utility classes. |
| `$enable-smooth-scroll` | `true` (default) or `false` | Applies `scroll-behavior: smooth` globally, except for users asking for reduced motion through [`prefers-reduced-motion` media query]([[docsref:/getting-started/accessibility#reduced-motion]]) | | `$enable-smooth-scroll` | `true` (default) or `false` | Applies `scroll-behavior: smooth` globally, except for users asking for reduced motion through [`prefers-reduced-motion` media query]([[docsref:/getting-started/accessibility#reduced-motion]]) |
</BsTable> </BsTable>

View File

@@ -13,13 +13,14 @@ The `$utilities` map contains all our utilities and is later merged with your cu
| Option | Type | Default&nbsp;value | Description | | 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). | | [`property`](#property) | **Required** | | Name of the property, this can be a string or an array of strings (e.g., horizontal paddings or margins). |
| [`values`](#values) | **Required** | | List of values, or a map if you dont want the class name to be the same as the value. If `null` is used as map key, `class` is not prepended to the class name. | | [`values`](#values) | **Required** | | List of values, or a map if you don't want the class name to be the same as the value. If `null` is used as map key, `class` is not prepended to the class name. |
| [`class`](#class) | Optional | null | Name of the generated class. If not provided and `property` is an array of strings, `class` will default to the first element of the `property` array. If not provided and `property` is a string, the `values` keys are used for the `class` names. | | [`class`](#class) | Optional | null | Name of the generated class. If not provided and `property` is an array of strings, `class` will default to the first element of the `property` array. If not provided and `property` is a string, the `values` keys are used for the `class` names. |
| [`css-var`](#css-variable-utilities) | Optional | `false` | Boolean to generate CSS variables instead of CSS rules. | | [`css-var`](#css-variable-utilities) | Optional | `false` | Boolean to generate CSS variables instead of CSS rules. |
| [`css-variable-name`](#css-variable-utilities) | Optional | null | Custom un-prefixed name for the CSS variable inside the ruleset. | | [`css-variable-name`](#css-variable-utilities) | Optional | null | Custom un-prefixed name for the CSS variable inside the ruleset. |
| [`local-vars`](#local-css-variables) | Optional | null | Map of local CSS variables to generate in addition to the CSS rules. | | [`local-vars`](#local-css-variables) | Optional | null | Map of local CSS variables to generate in addition to the CSS rules. |
| [`state`](#states) | Optional | null | List of pseudo-class variants (e.g., `:hover` or `:focus`) to generate. | | [`state`](#states) | Optional | null | List of pseudo-class variants (e.g., `:hover` or `:focus`) to generate. |
| [`responsive`](#responsive) | Optional | `false` | Boolean indicating if responsive classes should be generated. | | [`responsive`](#responsive) | Optional | `false` | Boolean indicating if responsive classes should be generated. |
| [`important`](#importance) | Optional | `false` | Boolean indicating if `!important` should be added to the utility's CSS rules. |
| `rfs` | Optional | `false` | Boolean to enable [fluid rescaling with RFS]([[docsref:/getting-started/rfs]]). | | `rfs` | Optional | `false` | Boolean to enable [fluid rescaling with RFS]([[docsref:/getting-started/rfs]]). |
| [`print`](#print) | Optional | `false` | Boolean indicating if print classes need to be generated. | | [`print`](#print) | Optional | `false` | Boolean indicating if print classes need to be generated. |
| `rtl` | Optional | `true` | Boolean indicating if utility should be kept in RTL. | | `rtl` | Optional | `true` | Boolean indicating if utility should be kept in RTL. |
@@ -360,12 +361,36 @@ Output:
## Importance ## Importance
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`). 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 enable `!important` on a per-utility basis by setting the `important` option to `true`.
```scss ```scss
$enable-important-utilities: true; $utilities: (
"opacity": (
property: opacity,
important: true,
values: (
0: 0,
25: .25,
50: .5,
75: .75,
100: 1,
)
)
);
``` ```
This will generate utilities with `!important`:
```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; }
```
Some utilities like `display`, `position`, and `visibility` have `important: true` set by default as they commonly need to override component styles.
## Using the API ## Using the API
Now that youre familiar with how the utilities API works, learn how to add your own custom classes and modify our default utilities. Now that youre familiar with how the utilities API works, learn how to add your own custom classes and modify our default utilities.