From 3e13bb8705a2f7ab1ebbeb0edffb702c4a6bc6e1 Mon Sep 17 00:00:00 2001 From: Mark Otto Date: Sun, 25 Jul 2021 10:19:02 -0700 Subject: [PATCH 1/3] Replace Sass division with multiplication and custom divide() function Fixes #34353. Co-Authored-By: Slaven Tomac --- scss/_card.scss | 10 +++--- scss/_carousel.scss | 4 +-- scss/_custom-forms.scss | 12 +++---- scss/_forms.scss | 8 ++--- scss/_functions.scss | 44 ++++++++++++++++++++++- scss/_images.scss | 2 +- scss/_jumbotron.scss | 2 +- scss/_modal.scss | 4 +-- scss/_popover.scss | 18 +++++----- scss/_tooltip.scss | 8 ++--- scss/_variables.scss | 14 ++++---- scss/mixins/_forms.scss | 2 +- scss/mixins/_grid-framework.scss | 4 +-- scss/mixins/_grid.scss | 22 ++++++------ scss/utilities/_embed.scss | 2 +- site/assets/scss/_component-examples.scss | 6 ++-- site/assets/scss/_masthead.scss | 2 +- site/assets/scss/_skippy.scss | 4 +-- 18 files changed, 105 insertions(+), 63 deletions(-) diff --git a/scss/_card.scss b/scss/_card.scss index faaa75ef7fc6..a974163f8229 100644 --- a/scss/_card.scss +++ b/scss/_card.scss @@ -58,7 +58,7 @@ } .card-subtitle { - margin-top: -$card-spacer-y / 2; + margin-top: -$card-spacer-y * .5; margin-bottom: 0; } @@ -109,15 +109,15 @@ // .card-header-tabs { - margin-right: -$card-spacer-x / 2; + margin-right: -$card-spacer-x * .5; margin-bottom: -$card-spacer-y; - margin-left: -$card-spacer-x / 2; + margin-left: -$card-spacer-x * .5; border-bottom: 0; } .card-header-pills { - margin-right: -$card-spacer-x / 2; - margin-left: -$card-spacer-x / 2; + margin-right: -$card-spacer-x * .5; + margin-left: -$card-spacer-x * .5; } // Card image diff --git a/scss/_carousel.scss b/scss/_carousel.scss index 28f1e17d147a..25aaf5873fa0 100644 --- a/scss/_carousel.scss +++ b/scss/_carousel.scss @@ -189,9 +189,9 @@ .carousel-caption { position: absolute; - right: (100% - $carousel-caption-width) / 2; + right: (100% - $carousel-caption-width) * .5; bottom: 20px; - left: (100% - $carousel-caption-width) / 2; + left: (100% - $carousel-caption-width) * .5; z-index: 10; padding-top: 20px; padding-bottom: 20px; diff --git a/scss/_custom-forms.scss b/scss/_custom-forms.scss index 06725ff36445..b3db8c48fa91 100644 --- a/scss/_custom-forms.scss +++ b/scss/_custom-forms.scss @@ -26,7 +26,7 @@ left: 0; z-index: -1; // Put the input behind the label so it doesn't overlay text width: $custom-control-indicator-size; - height: ($font-size-base * $line-height-base + $custom-control-indicator-size) / 2; + height: ($font-size-base * $line-height-base + $custom-control-indicator-size) * .5; opacity: 0; &:checked ~ .custom-control-label::before { @@ -83,7 +83,7 @@ // Background-color and (when enabled) gradient &::before { position: absolute; - top: ($font-size-base * $line-height-base - $custom-control-indicator-size) / 2; + top: ($font-size-base * $line-height-base - $custom-control-indicator-size) * .5; left: -($custom-control-gutter + $custom-control-indicator-size); display: block; width: $custom-control-indicator-size; @@ -98,7 +98,7 @@ // Foreground (icon) &::after { position: absolute; - top: ($font-size-base * $line-height-base - $custom-control-indicator-size) / 2; + top: ($font-size-base * $line-height-base - $custom-control-indicator-size) * .5; left: -($custom-control-gutter + $custom-control-indicator-size); display: block; width: $custom-control-indicator-size; @@ -186,7 +186,7 @@ } &::after { - top: add(($font-size-base * $line-height-base - $custom-control-indicator-size) / 2, $custom-control-indicator-border-width * 2); + top: add(($font-size-base * $line-height-base - $custom-control-indicator-size) * .5, $custom-control-indicator-border-width * 2); left: add(-($custom-switch-width + $custom-control-gutter), $custom-control-indicator-border-width * 2); width: $custom-switch-indicator-size; height: $custom-switch-indicator-size; @@ -406,7 +406,7 @@ &::-webkit-slider-thumb { width: $custom-range-thumb-width; height: $custom-range-thumb-height; - margin-top: ($custom-range-track-height - $custom-range-thumb-height) / 2; // Webkit specific + margin-top: ($custom-range-track-height - $custom-range-thumb-height) * .5; // Webkit specific @include gradient-bg($custom-range-thumb-bg); border: $custom-range-thumb-border; @include border-radius($custom-range-thumb-border-radius); @@ -481,7 +481,7 @@ cursor: $custom-range-track-cursor; background-color: transparent; border-color: transparent; - border-width: $custom-range-thumb-height / 2; + border-width: $custom-range-thumb-height * .5; @include box-shadow($custom-range-track-box-shadow); } diff --git a/scss/_forms.scss b/scss/_forms.scss index a2494ceafd7d..cde466327b08 100644 --- a/scss/_forms.scss +++ b/scss/_forms.scss @@ -199,13 +199,13 @@ textarea.form-control { .form-row { display: flex; flex-wrap: wrap; - margin-right: -$form-grid-gutter-width / 2; - margin-left: -$form-grid-gutter-width / 2; + margin-right: -$form-grid-gutter-width * .5; + margin-left: -$form-grid-gutter-width * .5; > .col, > [class*="col-"] { - padding-right: $form-grid-gutter-width / 2; - padding-left: $form-grid-gutter-width / 2; + padding-right: $form-grid-gutter-width * .5; + padding-left: $form-grid-gutter-width * .5; } } diff --git a/scss/_functions.scss b/scss/_functions.scss index 8abc31164e98..f940fb430acc 100644 --- a/scss/_functions.scss +++ b/scss/_functions.scss @@ -75,7 +75,7 @@ $g: green($color); $b: blue($color); - $yiq: (($r * 299) + ($g * 587) + ($b * 114)) / 1000; + $yiq: (($r * 299) + ($g * 587) + ($b * 114)) * .001; @if ($yiq >= $yiq-contrasted-threshold) { @return $dark; @@ -158,3 +158,45 @@ @return if($return-calc == true, calc(#{$value1} - #{$value2}), $value1 + unquote(" - ") + $value2); } + +@function divide($dividend, $divisor, $precision: 10) { + $sign: if($dividend > 0 and $divisor > 0 or $dividend < 0 and $divisor < 0, 1, -1); + $dividend: abs($dividend); + $divisor: abs($divisor); + @if $dividend == 0 { + @return 0; + } + @if $divisor == 0 { + @error "Cannot divide by 0"; + } + $remainder: $dividend; + $result: 0; + $factor: 10; + @while ($remainder > 0 and $precision >= 0) { + $quotient: 0; + @while ($remainder >= $divisor) { + $remainder: $remainder - $divisor; + $quotient: $quotient + 1; + } + $result: $result * 10 + $quotient; + $factor: $factor * .1; + $remainder: $remainder * 10; + $precision: $precision - 1; + @if ($precision < 0 and $remainder >= $divisor * 5) { + $result: $result + 1; + } + } + $result: $result * $factor * $sign; + $dividend-unit: unit($dividend); + $divisor-unit: unit($divisor); + $unit-map: ( + "px": 1px, + "rem": 1rem, + "em": 1em, + "%": 1% + ); + @if ($dividend-unit != $divisor-unit and map-has-key($unit-map, $dividend-unit)) { + $result: $result * map-get($unit-map, $dividend-unit); + } + @return $result; +} diff --git a/scss/_images.scss b/scss/_images.scss index b11b45a37bb0..3d6a1014c431 100644 --- a/scss/_images.scss +++ b/scss/_images.scss @@ -32,7 +32,7 @@ } .figure-img { - margin-bottom: $spacer / 2; + margin-bottom: $spacer * .5; line-height: 1; } diff --git a/scss/_jumbotron.scss b/scss/_jumbotron.scss index bcd7dcad996d..2c617edb5925 100644 --- a/scss/_jumbotron.scss +++ b/scss/_jumbotron.scss @@ -1,5 +1,5 @@ .jumbotron { - padding: $jumbotron-padding ($jumbotron-padding / 2); + padding: $jumbotron-padding ($jumbotron-padding * .5); margin-bottom: $jumbotron-padding; color: $jumbotron-color; background-color: $jumbotron-bg; diff --git a/scss/_modal.scss b/scss/_modal.scss index e43c70fbb4bb..4d01788d7090 100644 --- a/scss/_modal.scss +++ b/scss/_modal.scss @@ -175,7 +175,7 @@ flex-wrap: wrap; align-items: center; // vertically center justify-content: flex-end; // Right align buttons with flex property because text-align doesn't work on flex items - padding: $modal-inner-padding - $modal-footer-margin-between / 2; + padding: $modal-inner-padding - $modal-footer-margin-between * .5; border-top: $modal-footer-border-width solid $modal-footer-border-color; @include border-bottom-radius($modal-content-inner-border-radius); @@ -183,7 +183,7 @@ // This solution is far from ideal because of the universal selector usage, // but is needed to fix https://github.com/twbs/bootstrap/issues/24800 > * { - margin: $modal-footer-margin-between / 2; + margin: $modal-footer-margin-between * .5; } } diff --git a/scss/_popover.scss b/scss/_popover.scss index 0ad76af3eeb6..c7106a809d71 100644 --- a/scss/_popover.scss +++ b/scss/_popover.scss @@ -43,13 +43,13 @@ &::before { bottom: 0; - border-width: $popover-arrow-height ($popover-arrow-width / 2) 0; + border-width: $popover-arrow-height ($popover-arrow-width * .5) 0; border-top-color: $popover-arrow-outer-color; } &::after { bottom: $popover-border-width; - border-width: $popover-arrow-height ($popover-arrow-width / 2) 0; + border-width: $popover-arrow-height ($popover-arrow-width * .5) 0; border-top-color: $popover-arrow-color; } } @@ -66,13 +66,13 @@ &::before { left: 0; - border-width: ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2) 0; + border-width: ($popover-arrow-width * .5) $popover-arrow-height ($popover-arrow-width * .5) 0; border-right-color: $popover-arrow-outer-color; } &::after { left: $popover-border-width; - border-width: ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2) 0; + border-width: ($popover-arrow-width * .5) $popover-arrow-height ($popover-arrow-width * .5) 0; border-right-color: $popover-arrow-color; } } @@ -86,13 +86,13 @@ &::before { top: 0; - border-width: 0 ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2); + border-width: 0 ($popover-arrow-width * .5) $popover-arrow-height ($popover-arrow-width * .5); border-bottom-color: $popover-arrow-outer-color; } &::after { top: $popover-border-width; - border-width: 0 ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2); + border-width: 0 ($popover-arrow-width * .5) $popover-arrow-height ($popover-arrow-width * .5); border-bottom-color: $popover-arrow-color; } } @@ -104,7 +104,7 @@ left: 50%; display: block; width: $popover-arrow-width; - margin-left: -$popover-arrow-width / 2; + margin-left: -$popover-arrow-width * .5; content: ""; border-bottom: $popover-border-width solid $popover-header-bg; } @@ -121,13 +121,13 @@ &::before { right: 0; - border-width: ($popover-arrow-width / 2) 0 ($popover-arrow-width / 2) $popover-arrow-height; + border-width: ($popover-arrow-width * .5) 0 ($popover-arrow-width * .5) $popover-arrow-height; border-left-color: $popover-arrow-outer-color; } &::after { right: $popover-border-width; - border-width: ($popover-arrow-width / 2) 0 ($popover-arrow-width / 2) $popover-arrow-height; + border-width: ($popover-arrow-width * .5) 0 ($popover-arrow-width * .5) $popover-arrow-height; border-left-color: $popover-arrow-color; } } diff --git a/scss/_tooltip.scss b/scss/_tooltip.scss index 6b3aa62dd619..6771b4eb4f58 100644 --- a/scss/_tooltip.scss +++ b/scss/_tooltip.scss @@ -37,7 +37,7 @@ &::before { top: 0; - border-width: $tooltip-arrow-height ($tooltip-arrow-width / 2) 0; + border-width: $tooltip-arrow-height ($tooltip-arrow-width * .5) 0; border-top-color: $tooltip-arrow-color; } } @@ -53,7 +53,7 @@ &::before { right: 0; - border-width: ($tooltip-arrow-width / 2) $tooltip-arrow-height ($tooltip-arrow-width / 2) 0; + border-width: ($tooltip-arrow-width * .5) $tooltip-arrow-height ($tooltip-arrow-width * .5) 0; border-right-color: $tooltip-arrow-color; } } @@ -67,7 +67,7 @@ &::before { bottom: 0; - border-width: 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height; + border-width: 0 ($tooltip-arrow-width * .5) $tooltip-arrow-height; border-bottom-color: $tooltip-arrow-color; } } @@ -83,7 +83,7 @@ &::before { left: 0; - border-width: ($tooltip-arrow-width / 2) 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height; + border-width: ($tooltip-arrow-width * .5) 0 ($tooltip-arrow-width * .5) $tooltip-arrow-height; border-left-color: $tooltip-arrow-color; } } diff --git a/scss/_variables.scss b/scss/_variables.scss index 705b5212151b..7d8fb3b3bf03 100644 --- a/scss/_variables.scss +++ b/scss/_variables.scss @@ -299,7 +299,7 @@ $h4-font-size: $font-size-base * 1.5 !default; $h5-font-size: $font-size-base * 1.25 !default; $h6-font-size: $font-size-base !default; -$headings-margin-bottom: $spacer / 2 !default; +$headings-margin-bottom: $spacer * .5 !default; $headings-font-family: null !default; $headings-font-weight: 500 !default; $headings-line-height: 1.2 !default; @@ -495,7 +495,7 @@ $input-height-border: $input-border-width * 2 !default; $input-height-inner: add($input-line-height * 1em, $input-padding-y * 2) !default; $input-height-inner-half: add($input-line-height * .5em, $input-padding-y) !default; -$input-height-inner-quarter: add($input-line-height * .25em, $input-padding-y / 2) !default; +$input-height-inner-quarter: add($input-line-height * .25em, $input-padding-y * .5) !default; $input-height: add($input-line-height * 1em, add($input-padding-y * 2, $input-height-border, false)) !default; $input-height-sm: add($input-line-height-sm * 1em, add($input-padding-y-sm * 2, $input-height-border, false)) !default; @@ -565,7 +565,7 @@ $custom-radio-indicator-border-radius: 50% !default; $custom-radio-indicator-icon-checked: url("data:image/svg+xml,") !default; $custom-switch-width: $custom-control-indicator-size * 1.75 !default; -$custom-switch-indicator-border-radius: $custom-control-indicator-size / 2 !default; +$custom-switch-indicator-border-radius: $custom-control-indicator-size * .5 !default; $custom-switch-indicator-size: subtract($custom-control-indicator-size, $custom-control-indicator-border-width * 4) !default; $custom-select-padding-y: $input-padding-y !default; @@ -710,12 +710,12 @@ $nav-pills-link-active-color: $component-active-color !default; $nav-pills-link-active-bg: $component-active-bg !default; $nav-divider-color: $gray-200 !default; -$nav-divider-margin-y: $spacer / 2 !default; +$nav-divider-margin-y: $spacer * .5 !default; // Navbar -$navbar-padding-y: $spacer / 2 !default; +$navbar-padding-y: $spacer * .5 !default; $navbar-padding-x: $spacer !default; $navbar-nav-link-padding-x: .5rem !default; @@ -724,7 +724,7 @@ $navbar-brand-font-size: $font-size-lg !default; // Compute the navbar-brand padding-y so the navbar-brand will have the same height as navbar-text and nav-link $nav-link-height: $font-size-base * $line-height-base + $nav-link-padding-y * 2 !default; $navbar-brand-height: $navbar-brand-font-size * $line-height-base !default; -$navbar-brand-padding-y: ($nav-link-height - $navbar-brand-height) / 2 !default; +$navbar-brand-padding-y: ($nav-link-height - $navbar-brand-height) * .5 !default; $navbar-toggler-padding-y: .25rem !default; $navbar-toggler-padding-x: .75rem !default; @@ -845,7 +845,7 @@ $card-bg: $white !default; $card-img-overlay-padding: 1.25rem !default; -$card-group-margin: $grid-gutter-width / 2 !default; +$card-group-margin: $grid-gutter-width * .5 !default; $card-deck-margin: $card-group-margin !default; $card-columns-count: 3 !default; diff --git a/scss/mixins/_forms.scss b/scss/mixins/_forms.scss index 234c6b431ae4..b8847cc80de2 100644 --- a/scss/mixins/_forms.scss +++ b/scss/mixins/_forms.scss @@ -69,7 +69,7 @@ // Align tooltip to form elements .form-row > .col > &, .form-row > [class*="col-"] > & { - left: $form-grid-gutter-width / 2; + left: $form-grid-gutter-width * .5; } } diff --git a/scss/mixins/_grid-framework.scss b/scss/mixins/_grid-framework.scss index 6fc8e856122c..ef3291753042 100644 --- a/scss/mixins/_grid-framework.scss +++ b/scss/mixins/_grid-framework.scss @@ -8,8 +8,8 @@ %grid-column { position: relative; width: 100%; - padding-right: $gutter / 2; - padding-left: $gutter / 2; + padding-right: $gutter * .5; + padding-left: $gutter * .5; } @each $breakpoint in map-keys($breakpoints) { diff --git a/scss/mixins/_grid.scss b/scss/mixins/_grid.scss index 19babc09fbd2..0eb09910d1c1 100644 --- a/scss/mixins/_grid.scss +++ b/scss/mixins/_grid.scss @@ -4,8 +4,8 @@ @mixin make-container($gutter: $grid-gutter-width) { width: 100%; - padding-right: $gutter / 2; - padding-left: $gutter / 2; + padding-right: $gutter * .5; + padding-left: $gutter * .5; margin-right: auto; margin-left: auto; } @@ -13,8 +13,8 @@ @mixin make-row($gutter: $grid-gutter-width) { display: flex; flex-wrap: wrap; - margin-right: -$gutter / 2; - margin-left: -$gutter / 2; + margin-right: -$gutter * .5; + margin-left: -$gutter * .5; } // For each breakpoint, define the maximum width of the container in a media query @@ -33,16 +33,16 @@ // always setting `width: 100%;`. This works because we use `flex` values // later on to override this initial width. width: 100%; - padding-right: $gutter / 2; - padding-left: $gutter / 2; + padding-right: $gutter * .5; + padding-left: $gutter * .5; } @mixin make-col($size, $columns: $grid-columns) { - flex: 0 0 percentage($size / $columns); + flex: 0 0 percentage(divide($size, $columns)); // Add a `max-width` to ensure content within each column does not blow out // the width of the column. Applies to IE10+ and Firefox. Chrome and Safari // do not appear to require this. - max-width: percentage($size / $columns); + max-width: percentage(divide($size, $columns)); } @mixin make-col-auto() { @@ -52,7 +52,7 @@ } @mixin make-col-offset($size, $columns: $grid-columns) { - $num: $size / $columns; + $num: divide($size, $columns); margin-left: if($num == 0, 0, percentage($num)); } @@ -63,7 +63,7 @@ // style grid. @mixin row-cols($count) { > * { - flex: 0 0 100% / $count; - max-width: 100% / $count; + flex: 0 0 divide(100%, $count); + max-width: divide(100%, $count); } } diff --git a/scss/utilities/_embed.scss b/scss/utilities/_embed.scss index 4497ac0400fb..e37465e408cc 100644 --- a/scss/utilities/_embed.scss +++ b/scss/utilities/_embed.scss @@ -33,7 +33,7 @@ .embed-responsive-#{$embed-responsive-aspect-ratio-x}by#{$embed-responsive-aspect-ratio-y} { &::before { - padding-top: percentage($embed-responsive-aspect-ratio-y / $embed-responsive-aspect-ratio-x); + padding-top: percentage(divide($embed-responsive-aspect-ratio-y, $embed-responsive-aspect-ratio-x)); } } } diff --git a/site/assets/scss/_component-examples.scss b/site/assets/scss/_component-examples.scss index 89c52208f4bc..68856059b0d1 100644 --- a/site/assets/scss/_component-examples.scss +++ b/site/assets/scss/_component-examples.scss @@ -88,7 +88,7 @@ .bd-example { position: relative; padding: 1rem; - margin: 1rem (-$grid-gutter-width / 2) 0; + margin: 1rem (-$grid-gutter-width * .5) 0; border: solid $gray-100; border-width: .2rem 0 0; @include clearfix(); @@ -350,8 +350,8 @@ } .bd-content .highlight { - margin-right: (-$grid-gutter-width / 2); - margin-left: (-$grid-gutter-width / 2); + margin-right: (-$grid-gutter-width * .5); + margin-left: (-$grid-gutter-width * .5); @include media-breakpoint-up(sm) { margin-right: 0; diff --git a/site/assets/scss/_masthead.scss b/site/assets/scss/_masthead.scss index 6a13562e33e2..c16aa0138c35 100644 --- a/site/assets/scss/_masthead.scss +++ b/site/assets/scss/_masthead.scss @@ -2,7 +2,7 @@ .bd-masthead { position: relative; - padding: 3rem ($grid-gutter-width / 2); + padding: 3rem ($grid-gutter-width * .5); background: linear-gradient(to right bottom, lighten($bd-purple-light, 16%) 50%, #fff 50%); h1 { diff --git a/site/assets/scss/_skippy.scss b/site/assets/scss/_skippy.scss index 894db70db4e7..125f44c84142 100644 --- a/site/assets/scss/_skippy.scss +++ b/site/assets/scss/_skippy.scss @@ -11,8 +11,8 @@ position: static !important; width: auto !important; height: auto !important; - padding: $spacer / 2 !important; - margin: $spacer / 4 !important; + padding: $spacer * .5 !important; + margin: $spacer * .25 !important; overflow: visible !important; clip: auto !important; white-space: normal !important; From 776538e1713feef5926987f8e644ceb32396594a Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Tue, 7 Sep 2021 15:27:06 +0300 Subject: [PATCH 2/3] Update RFS to v8.1.0 --- scss/vendor/_rfs.scss | 228 +++++++++++++++++++++++------------------- 1 file changed, 126 insertions(+), 102 deletions(-) diff --git a/scss/vendor/_rfs.scss b/scss/vendor/_rfs.scss index 497e07eda913..e453f441ee5c 100644 --- a/scss/vendor/_rfs.scss +++ b/scss/vendor/_rfs.scss @@ -2,9 +2,9 @@ // SCSS RFS mixin // -// Automated font-resizing +// Automated responsive font sizes // -// See https://github.com/twbs/rfs +// Licensed under MIT (https://github.com/twbs/rfs/blob/v8.x/LICENSE) // Configuration @@ -12,11 +12,19 @@ $rfs-base-font-size: 1.25rem !default; $rfs-font-size-unit: rem !default; +@if $rfs-font-size-unit != rem and $rfs-font-size-unit != px { + @error "`#{$rfs-font-size-unit}` is not a valid unit for $rfs-font-size-unit. Use `px` or `rem`."; +} + // Breakpoint at where font-size starts decreasing if screen width is smaller $rfs-breakpoint: 1200px !default; $rfs-breakpoint-unit: px !default; -// Resize font-size based on screen height and width +@if $rfs-breakpoint-unit != px and $rfs-breakpoint-unit != em and $rfs-breakpoint-unit != rem { + @error "`#{$rfs-breakpoint-unit}` is not a valid unit for $rfs-breakpoint-unit. Use `px`, `em` or `rem`."; +} + +// Resize font size based on screen height and width $rfs-two-dimensional: false !default; // Factor of decrease @@ -41,12 +49,54 @@ $enable-responsive-font-sizes: true !default; // Cache $rfs-base-font-size unit $rfs-base-font-size-unit: unit($rfs-base-font-size); +@function divide($dividend, $divisor, $precision: 10) { + $sign: if($dividend > 0 and $divisor > 0 or $dividend < 0 and $divisor < 0, 1, -1); + $dividend: abs($dividend); + $divisor: abs($divisor); + @if $dividend == 0 { + @return 0; + } + @if $divisor == 0 { + @error "Cannot divide by 0"; + } + $remainder: $dividend; + $result: 0; + $factor: 10; + @while ($remainder > 0 and $precision >= 0) { + $quotient: 0; + @while ($remainder >= $divisor) { + $remainder: $remainder - $divisor; + $quotient: $quotient + 1; + } + $result: $result * 10 + $quotient; + $factor: $factor * .1; + $remainder: $remainder * 10; + $precision: $precision - 1; + @if ($precision < 0 and $remainder >= $divisor * 5) { + $result: $result + 1; + } + } + $result: $result * $factor * $sign; + $dividend-unit: unit($dividend); + $divisor-unit: unit($divisor); + $unit-map: ( + "px": 1px, + "rem": 1rem, + "em": 1em, + "%": 1% + ); + @if ($dividend-unit != $divisor-unit and map-has-key($unit-map, $dividend-unit)) { + $result: $result * map-get($unit-map, $dividend-unit); + } + @return $result; +} + // Remove px-unit from $rfs-base-font-size for calculations @if $rfs-base-font-size-unit == "px" { - $rfs-base-font-size: $rfs-base-font-size / ($rfs-base-font-size * 0 + 1); + $rfs-base-font-size: divide($rfs-base-font-size, $rfs-base-font-size * 0 + 1); } @else if $rfs-base-font-size-unit == "rem" { - $rfs-base-font-size: $rfs-base-font-size / ($rfs-base-font-size * 0 + 1 / $rfs-rem-value); + $rfs-base-font-size: divide($rfs-base-font-size, divide($rfs-base-font-size * 0 + 1, $rfs-rem-value)); } // Cache $rfs-breakpoint unit to prevent multiple calls @@ -54,13 +104,55 @@ $rfs-breakpoint-unit-cache: unit($rfs-breakpoint); // Remove unit from $rfs-breakpoint for calculations @if $rfs-breakpoint-unit-cache == "px" { - $rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1); + $rfs-breakpoint: divide($rfs-breakpoint, $rfs-breakpoint * 0 + 1); } @else if $rfs-breakpoint-unit-cache == "rem" or $rfs-breakpoint-unit-cache == "em" { - $rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1 / $rfs-rem-value); + $rfs-breakpoint: divide($rfs-breakpoint, divide($rfs-breakpoint * 0 + 1, $rfs-rem-value)); +} + +// Internal mixin that adds disable classes to the selector if needed. +@mixin _rfs-disable-class { + @if $rfs-class == "disable" { + // Adding an extra class increases specificity, which prevents the media query to override the font size + &, + .disable-responsive-font-size &, + &.disable-responsive-font-size { + @content; + } + } + @else { + @content; + } +} + +// Internal mixin that adds enable classes to the selector if needed. +@mixin _rfs-enable-class { + @if $rfs-class == "enable" { + .enable-responsive-font-size &, + &.enable-responsive-font-size { + @content; + } + } + @else { + @content; + } } -// Responsive font-size mixin +// Internal mixin used to determine which media query needs to be used +@mixin _rfs-media-query($mq-value) { + @if $rfs-two-dimensional { + @media (max-width: #{$mq-value}), (max-height: #{$mq-value}) { + @content; + } + } + @else { + @media (max-width: #{$mq-value}) { + @content; + } + } +} + +// Responsive font size mixin @mixin rfs($fs, $important: false) { // Cache $fs unit $fs-unit: if(type-of($fs) == "number", unit($fs), false); @@ -73,128 +165,60 @@ $rfs-breakpoint-unit-cache: unit($rfs-breakpoint); font-size: #{$fs}#{$rfs-suffix}; } @else { - // Variables for storing static and fluid rescaling - $rfs-static: null; - $rfs-fluid: null; - - // Remove px-unit from $fs for calculations + // Remove unit from $fs for calculations @if $fs-unit == "px" { - $fs: $fs / ($fs * 0 + 1); + $fs: divide($fs, $fs * 0 + 1); } @else if $fs-unit == "rem" { - $fs: $fs / ($fs * 0 + 1 / $rfs-rem-value); + $fs: divide($fs, divide($fs * 0 + 1, $rfs-rem-value)); } - // Set default font-size - @if $rfs-font-size-unit == rem { - $rfs-static: #{$fs / $rfs-rem-value}rem#{$rfs-suffix}; - } - @else if $rfs-font-size-unit == px { - $rfs-static: #{$fs}px#{$rfs-suffix}; + // Set default font size + $rfs-static: if($rfs-font-size-unit == rem, #{divide($fs, $rfs-rem-value)}rem, #{$fs}px); + + // Only add the media query if the font size is bigger than the minimum font size + @if $fs <= $rfs-base-font-size or not $enable-responsive-font-sizes { + font-size: #{$rfs-static}#{$rfs-suffix}; } @else { - @error "`#{$rfs-font-size-unit}` is not a valid unit for $rfs-font-size-unit. Use `px` or `rem`."; - } - - // Only add media query if font-size is bigger as the minimum font-size - // If $rfs-factor == 1, no rescaling will take place - @if $fs > $rfs-base-font-size and $enable-responsive-font-sizes { - $min-width: null; - $variable-unit: null; + // Calculate the minimum font size for $fs + $fs-min: $rfs-base-font-size + divide($fs - $rfs-base-font-size, $rfs-factor); - // Calculate minimum font-size for given font-size - $fs-min: $rfs-base-font-size + ($fs - $rfs-base-font-size) / $rfs-factor; - - // Calculate difference between given font-size and minimum font-size for given font-size + // Calculate difference between $fs and the minimum font size $fs-diff: $fs - $fs-min; // Base font-size formatting - // No need to check if the unit is valid, because we did that before - $min-width: if($rfs-font-size-unit == rem, #{$fs-min / $rfs-rem-value}rem, #{$fs-min}px); + $min-width: if($rfs-font-size-unit == rem, #{divide($fs-min, $rfs-rem-value)}rem, #{$fs-min}px); - // If two-dimensional, use smallest of screen width and height + // Use `vmin` if two-dimensional is enabled $variable-unit: if($rfs-two-dimensional, vmin, vw); // Calculate the variable width between 0 and $rfs-breakpoint - $variable-width: #{$fs-diff * 100 / $rfs-breakpoint}#{$variable-unit}; + $variable-width: #{divide($fs-diff * 100, $rfs-breakpoint)}#{$variable-unit}; - // Set the calculated font-size. + // Set the calculated font-size $rfs-fluid: calc(#{$min-width} + #{$variable-width}) #{$rfs-suffix}; - } - // Rendering - @if $rfs-fluid == null { - // Only render static font-size if no fluid font-size is available - font-size: $rfs-static; - } - @else { - $mq-value: null; + // Breakpoint formatting + $mq-value: if($rfs-breakpoint-unit == px, #{$rfs-breakpoint}px, #{divide($rfs-breakpoint, $rfs-rem-value)}#{$rfs-breakpoint-unit}); - // RFS breakpoint formatting - @if $rfs-breakpoint-unit == em or $rfs-breakpoint-unit == rem { - $mq-value: #{$rfs-breakpoint / $rfs-rem-value}#{$rfs-breakpoint-unit}; - } - @else if $rfs-breakpoint-unit == px { - $mq-value: #{$rfs-breakpoint}px; - } - @else { - @error "`#{$rfs-breakpoint-unit}` is not a valid unit for $rfs-breakpoint-unit. Use `px`, `em` or `rem`."; + @include _rfs-disable-class { + font-size: #{$rfs-static}#{$rfs-suffix}; } - @if $rfs-class == "disable" { - // Adding an extra class increases specificity, - // which prevents the media query to override the font size - &, - .disable-responsive-font-size &, - &.disable-responsive-font-size { - font-size: $rfs-static; + @include _rfs-media-query($mq-value) { + @include _rfs-enable-class { + font-size: $rfs-fluid; } - } - @else { - font-size: $rfs-static; - } - @if $rfs-two-dimensional { - @media (max-width: #{$mq-value}), (max-height: #{$mq-value}) { - @if $rfs-class == "enable" { - .enable-responsive-font-size &, - &.enable-responsive-font-size { - font-size: $rfs-fluid; - } - } - @else { - font-size: $rfs-fluid; - } - - @if $rfs-safari-iframe-resize-bug-fix { - // stylelint-disable-next-line length-zero-no-unit - min-width: 0vw; - } - } - } - @else { - @media (max-width: #{$mq-value}) { - @if $rfs-class == "enable" { - .enable-responsive-font-size &, - &.enable-responsive-font-size { - font-size: $rfs-fluid; - } - } - @else { - font-size: $rfs-fluid; - } - - @if $rfs-safari-iframe-resize-bug-fix { - // stylelint-disable-next-line length-zero-no-unit - min-width: 0vw; - } - } + // Include safari iframe resize fix if needed + min-width: if($rfs-safari-iframe-resize-bug-fix, (0 * 1vw), null); } } } } -// The font-size & responsive-font-size mixin uses RFS to rescale font sizes +// The font-size & responsive-font-size mixins use RFS to rescale the font size @mixin font-size($fs, $important: false) { @include rfs($fs, $important); } From d92a24374ce31d3620681c2667aa0c7e4e044462 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Tue, 7 Sep 2021 16:21:30 +0300 Subject: [PATCH 3/3] Move RFS version in config.yml and update it. --- config.yml | 1 + site/content/docs/4.6/content/typography.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/config.yml b/config.yml index f072f329f497..c9e8c7351e51 100644 --- a/config.yml +++ b/config.yml @@ -50,6 +50,7 @@ params: current_version: "4.6.0" current_ruby_version: "4.6.0" docs_version: "4.6" + rfs_version: "v8.1.0" github_org: "https://github.com/twbs" repo: "https://github.com/twbs/bootstrap" twitter: "getbootstrap" diff --git a/site/content/docs/4.6/content/typography.md b/site/content/docs/4.6/content/typography.md index 9ed7e9a6b9a4..2fd6e0362957 100644 --- a/site/content/docs/4.6/content/typography.md +++ b/site/content/docs/4.6/content/typography.md @@ -283,4 +283,4 @@ Align terms and descriptions horizontally by using our grid system's predefined As of v4.3.0, Bootstrap ships with the option to enable responsive font sizes, allowing text to scale more naturally across device and viewport sizes. RFS can be enabled by changing the `$enable-responsive-font-sizes` Sass variable to `true` and recompiling Bootstrap. -To support RFS, we use a Sass mixin to replace our normal `font-size` properties. Responsive font sizes will be compiled into `calc()` functions with a mix of `rem` and viewport units to enable the responsive scaling behavior. More about RFS and its configuration can be found on its [GitHub repository](https://github.com/twbs/rfs/tree/v8.0.4). +To support RFS, we use a Sass mixin to replace our normal `font-size` properties. Responsive font sizes will be compiled into `calc()` functions with a mix of `rem` and viewport units to enable the responsive scaling behavior. More about RFS and its configuration can be found on its [GitHub repository](https://github.com/twbs/rfs/tree/{{< param "rfs_version" >}}).