Enable RFS for font resizing

- Enable RFS
- Add documentation
- Disable doc font size overrides
This commit is contained in:
Martijn Cuppens 2019-10-27 11:01:30 +01:00 committed by XhmikosR
parent 4787347c85
commit cd077cd599
10 changed files with 305 additions and 118 deletions

View File

@ -222,7 +222,7 @@ $enable-transitions: true !default;
$enable-prefers-reduced-motion-media-query: true !default;
$enable-grid-classes: true !default;
$enable-pointer-cursor-for-buttons: true !default;
$enable-responsive-font-sizes: false !default;
$enable-rfs: true !default;
$enable-validation-icons: true !default;
$enable-deprecation-messages: true !default;

299
scss/vendor/_rfs.scss vendored
View File

@ -2,21 +2,21 @@
// SCSS RFS mixin
//
// Automated responsive font sizes
// Automated responsive values for font sizes, paddings, margins and much more
//
// Licensed under MIT (https://github.com/twbs/rfs/blob/master/LICENSE)
// Configuration
// Base font size
$rfs-base-font-size: 1.25rem !default;
$rfs-font-size-unit: rem !default;
// Base value
$rfs-base-value: 1.25rem !default;
$rfs-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`.";
@if $rfs-unit != rem and $rfs-unit != px {
@error "`#{$rfs-unit}` is not a valid unit for $rfs-unit. Use `px` or `rem`.";
}
// Breakpoint at where font-size starts decreasing if screen width is smaller
// Breakpoint at where values start decreasing if screen width is smaller
$rfs-breakpoint: 1200px !default;
$rfs-breakpoint-unit: px !default;
@ -24,16 +24,19 @@ $rfs-breakpoint-unit: px !default;
@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
// Resize values based on screen height and width
$rfs-two-dimensional: false !default;
// Factor of decrease
$rfs-factor: 10 !default;
@if type-of($rfs-factor) != "number" or $rfs-factor <= 1 {
@if type-of($rfs-factor) != number or $rfs-factor <= 1 {
@error "`#{$rfs-factor}` is not a valid $rfs-factor, it must be greater than 1.";
}
// Mode. Possibilities: "min-media-query", "max-media-query"
$rfs-mode: min-media-query !default;
// Generate enable or disable classes. Possibilities: false, "enable" or "disable"
$rfs-class: false !default;
@ -43,38 +46,63 @@ $rfs-rem-value: 16 !default;
// Safari iframe resize bug: https://github.com/twbs/rfs/issues/14
$rfs-safari-iframe-resize-bug-fix: false !default;
// Disable RFS by setting $enable-responsive-font-sizes to false
$enable-responsive-font-sizes: true !default;
// Disable RFS by setting $enable-rfs to false
$enable-rfs: true !default;
// Cache $rfs-base-font-size unit
$rfs-base-font-size-unit: unit($rfs-base-font-size);
// Cache $rfs-base-value unit
$rfs-base-value-unit: unit($rfs-base-value);
// 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);
// Remove px-unit from $rfs-base-value for calculations
@if $rfs-base-value-unit == px {
$rfs-base-value: $rfs-base-value / ($rfs-base-value * 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);
@else if $rfs-base-value-unit == rem {
$rfs-base-value: $rfs-base-value / ($rfs-base-value * 0 + 1 / $rfs-rem-value);
}
// Cache $rfs-breakpoint unit to prevent multiple calls
$rfs-breakpoint-unit-cache: unit($rfs-breakpoint);
// Remove unit from $rfs-breakpoint for calculations
@if $rfs-breakpoint-unit-cache == "px" {
@if $rfs-breakpoint-unit-cache == px {
$rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1);
}
@else if $rfs-breakpoint-unit-cache == "rem" or $rfs-breakpoint-unit-cache == "em" {
@else if $rfs-breakpoint-unit-cache == rem or $rfs-breakpoint-unit-cache == "em" {
$rfs-breakpoint: $rfs-breakpoint / ($rfs-breakpoint * 0 + 1 / $rfs-rem-value);
}
// Calculate the media query value
$rfs-mq-value: if($rfs-breakpoint-unit == px, #{$rfs-breakpoint}px, #{$rfs-breakpoint / $rfs-rem-value}#{$rfs-breakpoint-unit});
$rfs-mq-property-width: if($rfs-mode == max-media-query, max-width, min-width);
$rfs-mq-property-height: if($rfs-mode == max-media-query, max-height, min-height);
// Internal mixin used to determine which media query needs to be used
@mixin _rfs-media-query {
@if $rfs-two-dimensional {
@media (#{$rfs-mq-property-width}: #{$rfs-mq-value}), (#{$rfs-mq-property-height}: #{$rfs-mq-value}) {
@content;
}
}
@else {
@media (#{$rfs-mq-property-width}: #{$rfs-mq-value}) {
@content;
}
}
}
// 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
@mixin _rfs-rule {
@if $rfs-class == disable and $rfs-mode == max-media-query {
// Adding an extra class increases specificity, which prevents the media query to override the property
&,
.disable-responsive-font-size &,
&.disable-responsive-font-size {
.disable-rfs &,
&.disable-rfs {
@content;
}
}
@else if $rfs-class == enable and $rfs-mode == min-media-query {
.enable-rfs &,
&.enable-rfs {
@content;
}
}
@ -84,103 +112,194 @@ $rfs-breakpoint-unit-cache: unit($rfs-breakpoint);
}
// 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;
}
}
@mixin _rfs-media-query-rule {
// 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}) {
@if $rfs-class == enable {
@if $rfs-mode == min-media-query {
@content;
}
@include _rfs-media-query {
.enable-rfs &,
&.enable-rfs {
@content;
}
}
}
@else {
@media (max-width: #{$mq-value}) {
@if $rfs-class == disable and $rfs-mode == min-media-query {
.disable-rfs &,
&.disable-rfs {
@content;
}
}
@include _rfs-media-query {
@content;
}
}
}
// Responsive font size mixin
@mixin rfs($fs, $important: false) {
// Cache $fs unit
$fs-unit: if(type-of($fs) == "number", unit($fs), false);
// Helper function to get the formatted non-responsive value
@function rfs-value($values) {
// Convert to list
$values: if(type-of($values) != list, ($values,), $values);
// Add !important suffix if needed
$rfs-suffix: if($important, " !important", "");
$val: '';
// If $fs isn't a number (like inherit) or $fs has a unit (not px or rem, like 1.5em) or $ is 0, just print the value
@if not $fs-unit or $fs-unit != "" and $fs-unit != "px" and $fs-unit != "rem" or $fs == 0 {
font-size: #{$fs}#{$rfs-suffix};
}
@else {
// Remove unit from $fs for calculations
@if $fs-unit == "px" {
$fs: $fs / ($fs * 0 + 1);
}
@else if $fs-unit == "rem" {
$fs: $fs / ($fs * 0 + 1 / $rfs-rem-value);
}
// Set default font size
$rfs-static: if($rfs-font-size-unit == rem, #{$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};
// Loop over each value and calculate value
@each $value in $values {
@if $value == 0 {
$val: $val + ' 0';
}
@else {
// Calculate the minimum font size for $fs
$fs-min: $rfs-base-font-size + ($fs - $rfs-base-font-size) / $rfs-factor;
// Cache $value unit
$unit: if(type-of($value) == "number", unit($value), false);
// Calculate difference between $fs and the minimum font size
$fs-diff: $fs - $fs-min;
@if $unit == px {
// Convert to rem if needed
$val: $val + ' ' + if($rfs-unit == rem, #{$value / ($value * 0 + $rfs-rem-value)}rem, $value);
}
@else if $unit == rem {
// Convert to px if needed
$val: $val + ' ' + if($rfs-unit == px, #{$value / ($value * 0 + 1) * $rfs-rem-value}px, $value);
}
@else {
// If $value isn't a number (like inherit) or $value has a unit (not px or rem, like 1.5em) or $ is 0, just print the value
$val: $val + ' ' + $value;
}
}
}
// Base font-size formatting
$min-width: if($rfs-font-size-unit == rem, #{$fs-min / $rfs-rem-value}rem, #{$fs-min}px);
// Remove first space
@return unquote(str-slice($val, 2));
}
// Use `vmin` if two-dimensional is enabled
$variable-unit: if($rfs-two-dimensional, vmin, vw);
// Helper function to get the responsive value calculated by RFS
@function rfs-fluid-value($values) {
// Convert to list
$values: if(type-of($values) != list, ($values,), $values);
// Calculate the variable width between 0 and $rfs-breakpoint
$variable-width: #{$fs-diff * 100 / $rfs-breakpoint}#{$variable-unit};
$val: '';
// Set the calculated font-size
$rfs-fluid: calc(#{$min-width} + #{$variable-width}) #{$rfs-suffix};
// Loop over each value and calculate value
@each $value in $values {
@if $value == 0 {
$val: $val + ' 0';
}
// Breakpoint formatting
$mq-value: if($rfs-breakpoint-unit == px, #{$rfs-breakpoint}px, #{$rfs-breakpoint / $rfs-rem-value}#{$rfs-breakpoint-unit});
@else {
// Cache $value unit
$unit: if(type-of($value) == "number", unit($value), false);
@include _rfs-disable-class {
font-size: #{$rfs-static}#{$rfs-suffix};
// If $value isn't a number (like inherit) or $value has a unit (not px or rem, like 1.5em) or $ is 0, just print the value
@if not $unit or $unit != px and $unit != rem {
$val: $val + ' ' + $value;
}
@include _rfs-media-query($mq-value) {
@include _rfs-enable-class {
font-size: $rfs-fluid;
@else {
// Remove unit from $value for calculations
$value: $value / ($value * 0 + if($unit == px, 1, 1 / $rfs-rem-value));
// Only add the media query if the value is greater than the minimum value
@if abs($value) <= $rfs-base-value or not $enable-rfs {
$val: $val + ' ' + if($rfs-unit == rem, #{$value / $rfs-rem-value}rem, #{$value}px);
}
@else {
// Calculate the minimum value
$value-min: $rfs-base-value + (abs($value) - $rfs-base-value) / $rfs-factor;
// Calculate difference between $value and the minimum value
$value-diff: abs($value) - $value-min;
// Base value formatting
$min-width: if($rfs-unit == rem, #{$value-min / $rfs-rem-value}rem, #{$value-min}px);
// Use negative value if needed
$min-width: if($value < 0, -$min-width, $min-width);
// 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: #{$value-diff * 100 / $rfs-breakpoint}#{$variable-unit};
// Return the calculated value
$val: $val + ' calc(' + $min-width + if($value < 0, ' - ', ' + ') + $variable-width + ')';
}
}
}
}
// Remove first space
@return unquote(str-slice($val, 2));
}
// RFS mixin
@mixin rfs($values, $property: font-size) {
@if $values != null {
$val: rfs-value($values);
$fluidVal: rfs-fluid-value($values);
// Do not print the media query if responsive & non-responsive values are the same
@if $val == $fluidVal {
#{$property}: $val;
}
@else {
@include _rfs-rule {
#{$property}: if($rfs-mode == max-media-query, $val, $fluidVal);
// Include safari iframe resize fix if needed
min-width: if($rfs-safari-iframe-resize-bug-fix, (0 * 1vw), null);
}
@include _rfs-media-query-rule {
#{$property}: if($rfs-mode == max-media-query, $fluidVal, $val);
}
}
}
}
// The font-size & responsive-font-size mixins use RFS to rescale the font size
@mixin font-size($fs, $important: false) {
@include rfs($fs, $important);
// Shorthand helper mixins
@mixin font-size($value) {
@include rfs($value);
}
@mixin responsive-font-size($fs, $important: false) {
@include rfs($fs, $important);
@mixin padding($value) {
@include rfs($value, padding);
}
@mixin padding-top($value) {
@include rfs($value, padding-top);
}
@mixin padding-right($value) {
@include rfs($value, padding-right);
}
@mixin padding-bottom($value) {
@include rfs($value, padding-bottom);
}
@mixin padding-left($value) {
@include rfs($value, padding-left);
}
@mixin margin($value) {
@include rfs($value, margin);
}
@mixin margin-top($value) {
@include rfs($value, margin-top);
}
@mixin margin-right($value) {
@include rfs($value, margin-right);
}
@mixin margin-bottom($value) {
@include rfs($value, margin-bottom);
}
@mixin margin-left($value) {
@include rfs($value, margin-left);
}

View File

@ -47,7 +47,7 @@
.algolia-docsearch-suggestion--category-header {
padding: .125rem 1rem !important;
margin-top: 0 !important;
@include font-size(.875rem, true);
@include font-size(.875rem !important);
font-weight: 600 !important;
color: $bd-purple-bright !important;
border-bottom: 0 !important;
@ -107,7 +107,7 @@
.algolia-docsearch-suggestion--title {
display: block;
margin-bottom: 0 !important;
@include font-size(.875rem, true);
@include font-size(.875rem !important);
font-weight: 400 !important;
}
@ -115,7 +115,7 @@
flex: 0 0 100%;
max-width: 100%;
padding: .2rem 0;
@include font-size(.8125rem, true);
@include font-size(.8125rem !important);
font-weight: 400;
line-height: 1.25 !important;
color: $gray-600;
@ -126,7 +126,7 @@
width: auto !important;
height: auto !important;
padding: .75rem 1rem 0;
@include font-size(.75rem, true);
@include font-size(.75rem !important);
line-height: 1 !important;
color: $gray-600 !important;
border-top: 1px solid rgba(0, 0, 0, .1);

View File

@ -58,18 +58,6 @@
//
.bd-content {
> h2 {
@include font-size($h2-font-size);
}
> h3 {
@include font-size($h3-font-size);
}
> h4 {
@include font-size($h4-font-size);
}
> h2:not(:first-child) {
margin-top: 3rem;
}

View File

@ -11,8 +11,3 @@ $bd-warning: #f0ad4e;
$bd-danger: #d9534f;
$dropdown-active-icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'><path fill='#292b2c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/></svg>");
$sidebar-collapse-icon: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path fill='none' stroke='rgba(0,0,0,.5)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 14l6-6-6-6'/></svg>");
// Enable responsive font sizes for font sizes defined in the docs
// The weird if test is made as a workaround to prevent a false fusv error.
//
$enable-responsive-font-sizes: if($enable-responsive-font-sizes, true, true);

View File

@ -102,7 +102,7 @@ Use the included utility classes to recreate the small secondary heading text fr
## Display headings
Traditional heading elements are designed to work best in the meat of your page content. When you need a heading to stand out, consider using a **display heading**—a larger, slightly more opinionated heading style. Keep in mind these headings are not responsive by default, but it's possible to enable [responsive font sizes](#responsive-font-sizes).
Traditional heading elements are designed to work best in the meat of your page content. When you need a heading to stand out, consider using a **display heading**—a larger, slightly more opinionated heading style.
<div class="bd-example">
<div class="display-1 pb-3 mb-3 border-bottom">Display 1</div>
@ -272,6 +272,4 @@ Align terms and descriptions horizontally by using our grid system's predefined
## Responsive font sizes
Bootstrap v4.3 ships with the option to enable responsive font sizes, allowing text to scale more naturally across device and viewport sizes. <abbr title="Responsive font sizes">RFS</abbr> can be enabled by changing the `$enable-responsive-font-sizes` Sass variable to `true` and recompiling Bootstrap.
To support <abbr title="Responsive font sizes">RFS</abbr>, 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 <abbr title="Responsive font sizes">RFS</abbr> and its configuration can be found on its [GitHub repository](https://github.com/twbs/rfs).
In Bootstrap `v5`, we've enabled responsive font sizes by default, allowing text to scale more naturally across device and viewport sizes. Have a look at the [RFS]({{< docsref "/getting-started/rfs" >}}) page to find out how this works.

View File

@ -0,0 +1,86 @@
---
layout: docs
title: RFS
description: Bootstrap's resizing engine.
group: getting-started
toc: true
---
## What is RFS?
Bootstrap's side project [RFS](https://github.com/twbs/rfs) is a unit resizing engine which was initially developed to resize font sizes (hence its abbreviation for Responsive Font Sizes). Nowadays RFS is capable of rescaling basically every value for any css property with units, like `margin`, `padding`, `border-radius` or even `box-shadow`.
The mechanism automatically calculates the appropriate values based on the dimensions of the browser viewport. It will be compiled into `calc()` functions with a mix of `rem` and viewport units to enable the responsive scaling behavior.
## Using RFS
The mixins are included in Bootstrap and are available once you include Bootstraps' `scss`. RFS can also be installed [standalone](https://github.com/twbs/rfs#installation) if needed.
### Using the mixins
The `rfs()` mixin has shorthands for `font-size`, `margin`, `margin-top`, `margin-right`, `margin-bottom`, `margin-left`, `padding`, `padding-top`, `padding-right`, `padding-bottom` and `padding-left` which can be used like this:
```scss
.title {
@include font-size(4rem);
}
```
which outputs the following CSS:
```css
.title {
font-size: calc(1.525rem + 3.3vw);
}
@media (max-width: 1200px) {
.title {
font-size: 4rem;
}
}
```
Any other property can be passed to the `rfs()` mixin like this:
```scss
.selector {
@include rfs(4rem, border-radius);
}
```
`!important` can also just be added to whatever value you want:
```scss
.selector {
@include padding(2.5rem !important);
}
```
### Using the functions
- `rfs-value()` converts a value into a `rem` value if a `px` value is passed, in other cases it returns the same result.
- `rfs-fluid-value()` returns the fluid version of a value if the property needs rescaling.
In this example we use one of Bootstrap's built-in [responsive breakpoint mixins]({{< docsref "/layout/overview#responsive-breakpoints" >}}) to only apply styling below the `lg` breakpoint.
```scss
.selector {
@include media-breakpoint-down(lg) {
padding: rfs-fluid-value(2rem);
font-size: rfs-fluid-value(1.125rem);
}
}
```
```css
@media (max-width: 991.98px) {
.selector {
padding: calc(1.325rem + 0.9vw);
font-size: 1.125rem; /* 1.125rem is small enough, so RFS won't rescale this */
}
}
```
## Extended documentation
RFS is a separate project under the Bootstrap organisation. More about RFS and its configuration can be found on its [GitHub repository](https://github.com/twbs/rfs).

View File

@ -270,7 +270,7 @@ You can find and customize these variables for key global options in Bootstrap's
| `$enable-grid-classes` | `true` (default) or `false` | Enables the generation of CSS classes for the grid system (e.g., `.container`, `.row`, `.col-md-1`, etc.). |
| `$enable-caret` | `true` (default) or `false` | Enables pseudo element caret on `.dropdown-toggle`. |
| `$enable-pointer-cursor-for-buttons` | `true` (default) or `false` | Add "hand" cursor to non-disabled button elements. |
| `$enable-responsive-font-sizes` | `true` or `false` (default) | Enables [responsive font sizes]({{< docsref "/content/typography#responsive-font-sizes" >}}). |
| `$enable-rfs` | `true` or `false` (default) | Globally enables [RFS]({{< docsref "/getting-started/rfs" >}}). |
| `$enable-validation-icons` | `true` (default) or `false` | Enables `background-image` icons within textual inputs and some custom forms for validation states. |
| `$enable-deprecation-messages` | `true` or `false` (default) | Set to `true` to show warnings when using any of the deprecated mixins and functions that are planned to be removed in `v5`. |

View File

@ -59,7 +59,7 @@ Changes to any layout tools and our grid system.
Changes to Reboot, typography, tables, and more.
- **Todo:** Make RFS enabled by default
- [RFS](https://github.com/twbs/rfs) enabled for automated font size rescaling. [See #29152](https://github.com/twbs/bootstrap/pull/29152)
- Reset default horizontal `padding-left` on `<ul>` and `<ol>` elements from browser default `40px` to `2rem`.
- Simplified table styles (no more 2px border on `thead > th` elements) and tightened cell padding.
- Dropped `.pre-scrollable` class. [See #29135](https://github.com/twbs/bootstrap/pull/29135)

View File

@ -10,6 +10,7 @@
# - title: Best practices # TODO: Write this content
- title: Webpack
- title: Accessibility
- title: RFS
- title: Layout
pages: