]> git.ipfire.org Git - thirdparty/bootstrap.git/commitdiff
Update color and background-color utilities
authorMark Otto <markdotto@gmail.com>
Mon, 24 May 2021 18:56:19 +0000 (11:56 -0700)
committerMark Otto <otto@github.com>
Wed, 4 Aug 2021 00:06:06 +0000 (17:06 -0700)
- Adds new functions to generate additional Sass maps
- Adds new root variables for rgb() versions of our theme colors, plus a few extras
- Adds ability to change the alpha transparency of text color and background color utilities with new utilities, inline styles, or local CSS var
- Updates documentation for color and background-color utilities pages
- Deprecates .text-black-50 and .text-white-50 since those (and additional transparency levels) can be generated on the fly

Change approach slightly to prevent cascade

scss/_functions.scss
scss/_root.scss
scss/_utilities.scss
scss/_variables.scss
scss/mixins/_utilities.scss
site/content/docs/5.0/utilities/background.md
site/content/docs/5.0/utilities/colors.md

index 1f3263175e99e13df9689b8e7546382147271eb3..e00395505fed0d9f5df9df3bd6a063fa9ece6dad 100644 (file)
   }
 }
 
+// Colors
+@function to-rgb($value) {
+  @return red($value), green($value), blue($value);
+}
+
+@function rgba-css-var($identifier, $target) {
+  @return rgba(var(--#{$variable-prefix}#{$identifier}-rgb), var(--#{$variable-prefix}#{$target}-opacity));
+}
+
+// stylelint-disable scss/dollar-variable-pattern
+@function map-loop($map, $func, $args...) {
+  $_map: ();
+
+  @each $key, $value in $map {
+    // allow to pass the $key and $value of the map as an function argument
+    $_args: ();
+    @each $arg in $args {
+      $_args: append($_args, if($arg == "$key", $key, if($arg == "$value", $value, $arg)));
+    }
+
+    $_map: map-merge($_map, ($key: call(get-function($func), $_args...)));
+  }
+
+  @return $_map;
+}
+// stylelint-enable scss/dollar-variable-pattern
+
+@function varify($list) {
+  $result: null;
+  @each $entry in $list {
+    $result: append($result, var(--#{$variable-prefix}#{$entry}), space);
+  }
+  @return $result;
+}
+
 // Internal Bootstrap function to turn maps into its negative variant.
 // It prefixes the keys with `n` and makes the value negative.
 @function negativify-map($map) {
index 768d6343f8c4119ce87c195fcb8ebbd0a0af0598..95c77390112a104a77d4745afa0207d444bec124 100644 (file)
@@ -8,6 +8,14 @@
     --#{$variable-prefix}#{$color}: #{$value};
   }
 
+  @each $color, $value in $theme-colors-rgb {
+    --#{$variable-prefix}#{$color}-rgb: #{$value};
+  }
+
+  --#{$variable-prefix}white-rgb: #{to-rgb($white)};
+  --#{$variable-prefix}black-rgb: #{to-rgb($black)};
+  --#{$variable-prefix}body-rgb: #{to-rgb($body-color)};
+
   // Use `inspect` for lists so that quoted items keep the quotes.
   // See https://github.com/sass/sass/issues/2383#issuecomment-336349172
   --#{$variable-prefix}font-sans-serif: #{inspect($font-family-sans-serif)};
index 74f8a3a01ca973c365f2ae6e63f9bfb416826321..960d6f1adf04a0ad8d4b8b04143c5f3f6fe4c91c 100644 (file)
@@ -514,32 +514,55 @@ $utilities: map-merge(
     "color": (
       property: color,
       class: text,
+      local-vars: (
+        "text-opacity": 1
+      ),
       values: map-merge(
-        $theme-colors,
+        $utilities-text-colors,
         (
-          "white": $white,
-          "body": $body-color,
           "muted": $text-muted,
-          "black-50": rgba($black, .5),
-          "white-50": rgba($white, .5),
+          "black-50": rgba($black, .5), // deprecated
+          "white-50": rgba($white, .5), // deprecated
           "reset": inherit,
         )
       )
     ),
+    "text-opacity": (
+      css-var: true,
+      class: text-opacity,
+      values: (
+        25: .25,
+        50: .5,
+        75: .75,
+        100: 1
+      )
+    ),
     // scss-docs-end utils-color
     // scss-docs-start utils-bg-color
     "background-color": (
       property: background-color,
       class: bg,
+      local-vars: (
+        "bg-opacity": 1
+      ),
       values: map-merge(
-        $theme-colors,
+        $utilities-bg-colors,
         (
-          "body": $body-bg,
-          "white": $white,
           "transparent": transparent
         )
       )
     ),
+    "bg-opacity": (
+      css-var: true,
+      class: bg-opacity,
+      values: (
+        10: .1,
+        25: .25,
+        50: .5,
+        75: .75,
+        100: 1
+      )
+    ),
     // scss-docs-end utils-bg-color
     "gradient": (
       property: background-image,
index 9e921c07efca2d83179fa6786667f6699e03796f..3750fa2c2320e6cf3c0bb268dee330fb4de0b8c1 100644 (file)
@@ -90,6 +90,10 @@ $theme-colors: (
 ) !default;
 // scss-docs-end theme-colors-map
 
+// scss-docs-start theme-colors-rgb
+$theme-colors-rgb: map-loop($theme-colors, to-rgb, "$value") !default;
+// scss-docs-end theme-colors-rgb
+
 // The contrast ratio to reach against white, to determine if color changes from "light" to "dark". Acceptable values for WCAG 2.0 are 3, 4.5 and 7.
 // See https://www.w3.org/TR/WCAG20/#visual-audio-contrast-contrast
 $min-contrast-ratio:   4.5 !default;
@@ -401,6 +405,28 @@ $body-bg:                   $white !default;
 $body-color:                $gray-900 !default;
 $body-text-align:           null !default;
 
+// Utilities maps
+//
+// Extends the default `$theme-colors` maps to help create our utilities.
+
+// scss-docs-start utilities-colors
+$utilities-colors: map-merge(
+  $theme-colors-rgb,
+  (
+    "black": to-rgb($black),
+    "white": to-rgb($white),
+    "body":  to-rgb($body-color)
+  )
+) !default;
+// scss-docs-end utilities-colors
+
+// scss-docs-start utilities-text-colors
+$utilities-text-colors: map-loop($utilities-colors, rgba-css-var, "$key", "text") !default;
+// scss-docs-end utilities-text-colors
+
+// scss-docs-start utilities-bg-colors
+$utilities-bg-colors: map-loop($utilities-colors, rgba-css-var, "$key", "bg") !default;
+// scss-docs-end utilities-bg-colors
 
 // Links
 //
index 4d2370a0bf3c9244bca1b2b482a6b9f25572eea6..e871b4233671123ba99fad213556598fddadf66a 100644 (file)
       }
     }
 
+    $is-css-var: map-get($utility, css-var);
+    $is-local-vars: map-get($utility, local-vars);
     $is-rtl: map-get($utility, rtl);
 
     @if $value != null {
       @if $is-rtl == false {
         /* rtl:begin:remove */
       }
-      .#{$property-class + $infix + $property-class-modifier} {
-        @each $property in $properties {
-          #{$property}: $value if($enable-important-utilities, !important, null);
+
+      @if $is-css-var {
+        .#{$property-class + $infix + $property-class-modifier} {
+          --#{$variable-prefix}#{$property-class}: #{$value};
         }
-      }
 
-      @each $pseudo in $state {
-        .#{$property-class + $infix + $property-class-modifier}-#{$pseudo}:#{$pseudo} {
+        @each $pseudo in $state {
+          .#{$property-class + $infix + $property-class-modifier}-#{$pseudo}:#{$pseudo} {
+            --#{$variable-prefix}#{$property-class}: #{$value};
+          }
+        }
+      } @else {
+        .#{$property-class + $infix + $property-class-modifier} {
           @each $property in $properties {
+            @if $is-local-vars {
+              @each $local-var, $value in $is-local-vars {
+                --#{$variable-prefix}#{$local-var}: #{$value};
+              }
+            }
             #{$property}: $value if($enable-important-utilities, !important, null);
           }
         }
+
+        @each $pseudo in $state {
+          .#{$property-class + $infix + $property-class-modifier}-#{$pseudo}:#{$pseudo} {
+            @each $property in $properties {
+              #{$property}: $value if($enable-important-utilities, !important, null);
+            }
+          }
+        }
       }
+
       @if $is-rtl == false {
         /* rtl:end:remove */
       }
index 7b1b481401f4aaf6d7af7d4787d511a7ef64c30c..d5edbdf3b39180cccbeba3e789f2e5fee0884b4d 100644 (file)
@@ -35,6 +35,44 @@ Do you need a gradient in your custom CSS? Just add `background-image: var(--bs-
 {{< /colors.inline >}}
 {{< /markdown >}}
 
+## Opacity
+
+<small class="d-inline-flex px-2 py-1 font-monospace text-muted border rounded-3">Added in v5.1.0</small>
+
+As of v5.1.0, `background-color` utilities are generated with Sass using CSS variables. This allows for real-time color changes without compilation and dynamic alpha transparency changes.
+
+### How it works
+
+Consider our default `.bg-success` utility.
+
+```css
+.bg-success {
+  --bs-bg-opacity: 1;
+  background-color: rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important;
+}
+```
+
+We use an RGB version of our `--bs-succes` (with the value of `25, 135, 84`) CSS variable and attached a second CSS variable, `--bs-bg-opacity`, for the alpha transparency (with no default value, but a fallback of `1`). That means anytime you use `.bg-success` now, your computed `color` value is `rgba(25, 135, 84, 1)`.
+
+### Example
+
+To change that opacity, override `--bs-bg-opacity` via custom styles or inline styles.
+
+{{< example >}}
+<div class="bg-success p-2 text-white">This is default success background</div>
+<div class="bg-success p-2" style="--bs-bg-opacity: .5;">This is 50% opacity success background</div>
+{{< /example >}}
+
+Or, choose from any of the `.bg-opacity` utilities:
+
+{{< example >}}
+<div class="bg-success p-2 text-white">This is default success background</div>
+<div class="bg-success p-2 text-white bg-opacity-75">This is 75% opacity success background</div>
+<div class="bg-success p-2 text-dark bg-opacity-50">This is 50% opacity success background</div>
+<div class="bg-success p-2 text-dark bg-opacity-25">This is 25% opacity success background</div>
+<div class="bg-success p-2 text-dark bg-opacity-10">This is 10% opacity success background</div>
+{{< /example >}}
+
 ## Sass
 
 In addition to the following Sass functionality, consider reading about our included [CSS custom properties]({{< docsref "/customize/css-variables" >}}) (aka CSS variables) for colors and more.
@@ -63,6 +101,14 @@ Grayscale colors are also available as a Sass map. **This map is not used to gen
 
 {{< scss-docs name="gray-colors-map" file="scss/_variables.scss" >}}
 
+RGB colors are generated from a separate Sass map:
+
+{{< scss-docs name="theme-colors-rgb" file="scss/_variables.scss" >}}
+
+And background color opacities build on that with their own map that's consumed by the utilities API:
+
+{{< scss-docs name="utilities-bg-colors" file="scss/_variables.scss" >}}
+
 ### Mixins
 
 **No mixins are used to generate our background utilities**, but we do have some additional mixins for other situations where you'd like to create your own gradients.
index 266f671f6df63bb3ee234ccbb3f71016b16982b8..9502c4877700f7ecddb3ef0d748bb2c0932ed21d 100644 (file)
@@ -23,10 +23,51 @@ Colorize text with color utilities. If you want to colorize links, you can use t
 <p class="text-white-50 bg-dark">.text-white-50</p>
 {{< /example >}}
 
+{{< callout warning >}}
+**Deprecation:** With the addition of `.text-opacity-*` utilities and CSS variables for text utilities, `.text-black-50` and `.text-white-50` are deprecated as of v5.1.0. They'll be removed in v6.0.0.
+{{< /callout >}}
+
 {{< callout info >}}
 {{< partial "callout-warning-color-assistive-technologies.md" >}}
 {{< /callout >}}
 
+## Opacity
+
+<small class="d-inline-flex px-2 py-1 font-monospace text-muted border rounded-3">Added in v5.1.0</small>
+
+As of v5.1.0, text color utilities are generated with Sass using CSS variables. This allows for real-time color changes without compilation and dynamic alpha transparency changes.
+
+### How it works
+
+Consider our default `.text-primary` utility.
+
+```css
+.text-primary {
+  --bs-text-opacity: 1;
+  color: rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important;
+}
+```
+
+We use an RGB version of our `--bs-primary` (with the value of `13, 110, 253`) CSS variable and attached a second CSS variable, `--bs-text-opacity`, for the alpha transparency (with no default value, but a fallback of `1`). That means anytime you use `.text-primary` now, your computed `color` value is `rgba(13, 110, 253, 1)`.
+
+### Example
+
+To change that opacity, override `--bs-text-opacity` via custom styles or inline styles.
+
+{{< example >}}
+<div class="text-primary">This is default primary text</div>
+<div class="text-primary" style="--bs-text-opacity: .5;">This is 50% opacity primary text</div>
+{{< /example >}}
+
+Or, choose from any of the `.text-opacity` utilities:
+
+{{< example >}}
+<div class="text-primary">This is default primary text</div>
+<div class="text-primary text-opacity-75">This is 75% opacity primary text</div>
+<div class="text-primary text-opacity-50">This is 50% opacity primary text</div>
+<div class="text-primary text-opacity-25">This is 25% opacity primary text</div>
+{{< /example >}}
+
 ## Specificity
 
 Sometimes contextual classes cannot be applied due to the specificity of another selector. In some cases, a sufficient workaround is to wrap your element's content in a `<div>` or more semantic element with the desired class.
@@ -57,6 +98,14 @@ Grayscale colors are also available as a Sass map. **This map is not used to gen
 
 {{< scss-docs name="gray-colors-map" file="scss/_variables.scss" >}}
 
+RGB colors are generated from a separate Sass map:
+
+{{< scss-docs name="theme-colors-rgb" file="scss/_variables.scss" >}}
+
+And color opacities build on that with their own map that's consumed by the utilities API:
+
+{{< scss-docs name="utilities-text-colors" file="scss/_variables.scss" >}}
+
 ### Utilities API
 
 Color utilities are declared in our utilities API in `scss/_utilities.scss`. [Learn how to use the utilities API.]({{< docsref "/utilities/api#using-the-api" >}})