From dcb761350c72d77a4288493efc5b9a043feb9a26 Mon Sep 17 00:00:00 2001 From: "Patrick H. Lauke" Date: Mon, 20 Nov 2017 05:13:37 -0500 Subject: [PATCH] Add support for fractional viewport widths (zoom/high-dpi displays) (#24299) * Change breakpoint max- calculation to fractional values * Update docs to reflect fractional max-width breakpoint values * Add fractional max-width to offcanvas example * Add documentation and SCSS comment for fractional viewport support --- .../callout-info-mediaqueries-breakpoints.md | 3 +++ docs/4.0/content/tables.md | 4 ++++ docs/4.0/examples/offcanvas/offcanvas.css | 2 +- docs/4.0/layout/overview.md | 21 +++++++++++-------- scss/mixins/_breakpoints.scss | 6 ++++-- 5 files changed, 24 insertions(+), 12 deletions(-) create mode 100644 _includes/callout-info-mediaqueries-breakpoints.md diff --git a/_includes/callout-info-mediaqueries-breakpoints.md b/_includes/callout-info-mediaqueries-breakpoints.md new file mode 100644 index 0000000000..ddf2b37450 --- /dev/null +++ b/_includes/callout-info-mediaqueries-breakpoints.md @@ -0,0 +1,3 @@ +{% callout info %} +Note that since browsers do not currently support [range context queries](https://www.w3.org/TR/mediaqueries-4/#range-context), we work around the limitations of [`min-` and `max-` prefixes](https://www.w3.org/TR/mediaqueries-4/#mq-min-max) and viewports with fractional widths (which can occur under certain conditions on high-dpi devices, for instance) by using values with higher precision for these comparisons. +{% endcallout %} \ No newline at end of file diff --git a/docs/4.0/content/tables.md b/docs/4.0/content/tables.md index 791de590db..0aefc9ad1f 100644 --- a/docs/4.0/content/tables.md +++ b/docs/4.0/content/tables.md @@ -579,6 +579,10 @@ Regular table background variants are not available with the dark table, however {% capture callout-include %}{% include callout-warning-color-assistive-technologies.md %}{% endcapture %} {{ callout-include | markdownify }} +Create responsive tables by adding `.table-responsive{-sm|-md|-lg|-xl}` to any `.table` to make them scroll horizontally at each `max-width` breakpoint of 575.99px, 767.99px, 991.99px, and 1119.99px, respectively. + +{% capture callout-include %}{% include callout-info-mediaqueries-breakpoints.md %}{% endcapture %} +{{ callout-include | markdownify }} ## Captions diff --git a/docs/4.0/examples/offcanvas/offcanvas.css b/docs/4.0/examples/offcanvas/offcanvas.css index 1c9ca3b447..c23004ad49 100644 --- a/docs/4.0/examples/offcanvas/offcanvas.css +++ b/docs/4.0/examples/offcanvas/offcanvas.css @@ -17,7 +17,7 @@ footer { * Off Canvas * -------------------------------------------------- */ -@media screen and (max-width: 767px) { +@media screen and (max-width: 767.99px) { .row-offcanvas { position: relative; transition: all .25s ease-out; diff --git a/docs/4.0/layout/overview.md b/docs/4.0/layout/overview.md index 4952da5b78..9ac82d7bdf 100644 --- a/docs/4.0/layout/overview.md +++ b/docs/4.0/layout/overview.md @@ -88,21 +88,24 @@ We occasionally use media queries that go in the other direction (the given scre {% highlight scss %} // Extra small devices (portrait phones, less than 576px) -@media (max-width: 575px) { ... } +@media (max-width: 575.99px) { ... } // Small devices (landscape phones, less than 768px) -@media (max-width: 767px) { ... } +@media (max-width: 767.99px) { ... } // Medium devices (tablets, less than 992px) -@media (max-width: 991px) { ... } +@media (max-width: 991.99px) { ... } // Large devices (desktops, less than 1200px) -@media (max-width: 1199px) { ... } +@media (max-width: 1199.99px) { ... } // Extra large devices (large desktops) // No media query since the extra-large breakpoint has no upper bound on its width {% endhighlight %} +{% capture callout-include %}{% include callout-info-mediaqueries-breakpoints.md %}{% endcapture %} +{{ callout-include | markdownify }} + Once again, these media queries are also available via Sass mixins: {% highlight scss %} @@ -116,16 +119,16 @@ There are also media queries and mixins for targeting a single segment of screen {% highlight scss %} // Extra small devices (portrait phones, less than 576px) -@media (max-width: 575px) { ... } +@media (max-width: 575.99px) { ... } // Small devices (landscape phones, 576px and up) -@media (min-width: 576px) and (max-width: 767px) { ... } +@media (min-width: 576px) and (max-width: 767.99px) { ... } // Medium devices (tablets, 768px and up) -@media (min-width: 768px) and (max-width: 991px) { ... } +@media (min-width: 768px) and (max-width: 991.99px) { ... } // Large devices (desktops, 992px and up) -@media (min-width: 992px) and (max-width: 1199px) { ... } +@media (min-width: 992px) and (max-width: 1199.99px) { ... } // Extra large devices (large desktops, 1200px and up) @media (min-width: 1200px) { ... } @@ -146,7 +149,7 @@ Similarly, media queries may span multiple breakpoint widths: {% highlight scss %} // Example // Apply styles starting from medium devices and up to extra large devices -@media (min-width: 768px) and (max-width: 1199px) { ... } +@media (min-width: 768px) and (max-width: 1199.99px) { ... } {% endhighlight %} The Sass mixin for targeting the same screen size range would be: diff --git a/scss/mixins/_breakpoints.scss b/scss/mixins/_breakpoints.scss index a9866bd907..7c95c688f5 100644 --- a/scss/mixins/_breakpoints.scss +++ b/scss/mixins/_breakpoints.scss @@ -29,13 +29,15 @@ } // Maximum breakpoint width. Null for the largest (last) breakpoint. -// The maximum value is calculated as the minimum of the next one less 0.1. +// The maximum value is calculated as the minimum of the next one less 0.01px +// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths. +// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max // // >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)) // 767px @function breakpoint-max($name, $breakpoints: $grid-breakpoints) { $next: breakpoint-next($name, $breakpoints); - @return if($next, breakpoint-min($next, $breakpoints) - 1px, null); + @return if($next, breakpoint-min($next, $breakpoints) - .01px, null); } // Returns a blank string if smallest breakpoint, otherwise returns the name with a dash infront.