styles: Use range context queries to eliminate *_max variables.

On a high-DPI display or with a non-default zoom level, the browser
viewport may have a width strictly between md_max = 767px and md_min =
768px.  Use only the *_min bounds for consistency.

This requires queries with strict inequalities to express upper
bounds (width < md_min).  Fortunately, that functionality is provided
by range context queries.  Unfortunately, those are not supported in
all browsers.  Fortunately, we can compile them away using
postcss-media-minmax.  Unfortunately, postcss-media-minmax currently
subtracts 1px for strict inequalities anyway to work around a Safari
rounding bug.  Fortunately, 0.02px should be sufficient for that, so I
submitted a PR:

https://github.com/postcss/postcss-media-minmax/pull/28

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg 2021-02-03 17:49:05 -08:00 committed by Tim Abbott
parent d679aa015d
commit 64b78ad992
27 changed files with 119 additions and 122 deletions

View File

@ -53,6 +53,7 @@
"postcss-calc": "^8.0.0",
"postcss-extend-rule": "^3.0.0",
"postcss-loader": "^4.0.2",
"postcss-media-minmax": "https://github.com/andersk/postcss-media-minmax.git#01239f17f4a9872ace1dd133cee526a7de4ac9f5",
"postcss-nested": "^5.0.0",
"postcss-simple-vars": "^6.0.0",
"regenerator-runtime": "^0.13.3",

View File

@ -11,6 +11,7 @@ module.exports = {
variables: media_breakpoints,
},
"postcss-calc": {},
"postcss-media-minmax": {},
autoprefixer: {},
},
};

View File

@ -22,14 +22,5 @@ module.exports = {
ml_min: ml + "px",
mm_min: mm + "px",
ms_min: ms + "px",
xs_max: xs - 1 + "px",
sm_max: sm - 1 + "px",
md_max: md - 1 + "px",
lg_max: lg - 1 + "px",
xl_max: xl - 1 + "px",
ml_max: ml - 1 + "px",
mm_max: mm - 1 + "px",
ms_max: ms - 1 + "px",
},
};

View File

@ -307,7 +307,7 @@ exports.is_narrow = function () {
// This basically returns true when we hide the right sidebar for
// the left_side_userlist skinny mode. It would be nice to have a less brittle
// test for this.
return window.innerWidth <= media_breakpoints.xl_max;
return window.innerWidth < media_breakpoints.xl_min;
};
exports.system_initiated_animate_scroll = function (scroll_amount) {

View File

@ -240,7 +240,7 @@ $alert-error-red: hsl(0, 80%, 40%);
}
/* @media queries */
@media (max-width: $lg_max) {
@media (width < $lg_min) {
.alert-box {
width: 80%;
left: 10%;

View File

@ -268,7 +268,7 @@
.stream_sorter_toggle {
margin-left: auto;
@media (max-width: $lg_max) {
@media (width < $lg_min) {
margin-left: unset;
}
}
@ -390,7 +390,7 @@
}
}
@media (max-width: $md_max) {
@media (width < $md_min) {
/* Override Bootstrap's responsive grid to display input at full width */
.input-append .stream-list-filter {
/* Input width = 100% - 10px margin x2 - 6px padding x2 - 1px border x2. */

View File

@ -16,7 +16,7 @@
line-height: 1em;
}
@media (min-width: $sm_min) {
@media (width >= $sm_min) {
display: none;
}
}
@ -33,7 +33,7 @@
display: none;
}
@media (max-width: $sm_max) {
@media (width < $sm_min) {
.compose_stream_button,
.compose_private_button {
display: none;
@ -497,20 +497,20 @@ a#undo_markdown_preview {
}
/* This max-width must be synced with message_viewport.is_narrow */
@media (max-width: $xl_max) {
@media (width < $xl_min) {
.compose-content {
margin-right: 7px;
}
}
@media (max-width: $md_max) {
@media (width < $md_min) {
.compose-content {
margin-right: 7px;
margin-left: 7px;
}
}
@media (max-width: $mm_max) {
@media (width < $mm_min) {
#stream_message_recipient_topic.recipient_box {
width: calc(100% - 175px);
min-width: 95px;

View File

@ -11,7 +11,7 @@
display: flex;
flex-direction: column;
@media (max-width: $md_max) {
@media (width < $md_min) {
height: 95%;
max-width: none;
width: 90%;
@ -111,7 +111,7 @@
right: -80px;
font-size: 0.9em;
@media (max-width: $sm_max) {
@media (width < $sm_min) {
right: 0;
}

View File

@ -122,7 +122,7 @@
margin-bottom: 10px !important;
}
@media only screen and (max-width: $md_max) {
@media only screen and (width < $md_min) {
.informational-overlays {
.overlay-content {
width: calc(100% - 20px);

View File

@ -253,7 +253,7 @@
}
}
@media only screen and (min-width: $ms_min) and (max-width: $md_max) {
@media only screen and ($ms_min <= width < $md_min) {
#lightbox_overlay {
.image-actions {
float: left;

View File

@ -353,7 +353,7 @@ ul {
}
}
@media (max-width: $md_max) {
@media (width < $md_min) {
.message-info-popover,
.user-info-popover {
display: flex !important;
@ -402,7 +402,7 @@ ul {
pointer-events: all;
}
@media (max-width: $sm_max) {
@media (width < $sm_min) {
.popover-inner {
width: 70%;
}

View File

@ -26,7 +26,7 @@ body {
margin-top: 12px;
}
@media (max-width: 500px) {
@media (width <= 500px) {
.header {
height: 40px;
line-height: 10px;

View File

@ -35,16 +35,16 @@ $category-text: hsl(219, 23%, 33%);
border: none;
}
@media (max-width: 768px) {
@media (width <= 768px) {
width: auto;
}
@media (max-width: 686px) {
@media (width <= 686px) {
width: calc(100% - 50px);
margin: 0 auto;
}
@media (max-width: 450px) {
@media (width <= 450px) {
width: 100%;
}
}
@ -60,12 +60,12 @@ $category-text: hsl(219, 23%, 33%);
pointer-events: all;
}
@media (max-width: 500px) {
@media (width <= 500px) {
height: auto;
}
}
@media (max-width: 450px) {
@media (width <= 450px) {
padding: 40px 0;
}
}
@ -141,12 +141,12 @@ $category-text: hsl(219, 23%, 33%);
border: 1px solid $border-green;
}
@media (max-width: 768px) {
@media (width <= 768px) {
width: 375px;
margin: 0 auto;
}
@media (max-width: 550px) {
@media (width <= 550px) {
width: calc(100% - 80px);
}
}
@ -159,11 +159,11 @@ $category-text: hsl(219, 23%, 33%);
color: $border-green;
}
@media (max-width: 768px) {
@media (width <= 768px) {
width: 445px;
}
@media (max-width: 550px) {
@media (width <= 550px) {
width: 100%;
}
}
@ -212,7 +212,7 @@ $category-text: hsl(219, 23%, 33%);
}
}
@media (max-width: 906px) {
@media (width <= 906px) {
display: none;
}
}
@ -226,7 +226,7 @@ $category-text: hsl(219, 23%, 33%);
font-weight: 600;
}
@media (max-width: 906px) {
@media (width <= 906px) {
display: block;
width: 670px;
@ -282,27 +282,27 @@ $category-text: hsl(219, 23%, 33%);
}
}
@media (max-width: 830px) {
@media (width <= 830px) {
width: 666px;
}
@media (max-width: 786px) {
@media (width <= 786px) {
width: 509px;
}
@media (max-width: 768px) {
@media (width <= 768px) {
width: 666px;
}
@media (max-width: 686px) {
@media (width <= 686px) {
width: 509px;
}
@media (max-width: 578px) {
@media (width <= 578px) {
width: 351px;
}
@media (max-width: 357px) {
@media (width <= 357px) {
width: 299px;
}
}
@ -311,7 +311,7 @@ $category-text: hsl(219, 23%, 33%);
overflow: hidden;
text-align: left;
@media (max-width: 906px) {
@media (width <= 906px) {
text-align: center;
}
}
@ -380,7 +380,7 @@ $category-text: hsl(219, 23%, 33%);
}
}
@media (max-width: 830px) {
@media (width <= 830px) {
width: 134px;
height: 180px;
@ -406,11 +406,11 @@ $category-text: hsl(219, 23%, 33%);
}
}
@media (max-width: 375px) {
@media (width <= 375px) {
width: 120px;
}
@media (max-width: 357px) {
@media (width <= 357px) {
width: 108px;
height: 160px;
@ -452,7 +452,7 @@ $category-text: hsl(219, 23%, 33%);
display: none;
}
@media (max-width: 768px) {
@media (width <= 768px) {
border: none;
display: flex !important;
@ -510,21 +510,21 @@ $category-text: hsl(219, 23%, 33%);
display: inline-block;
margin-left: 5px;
@media (min-width: 768px) {
@media (width >= 768px) {
margin-top: 15px;
}
@media (max-width: 768px) {
@media (width <= 768px) {
display: none;
}
}
@media (max-width: 768px) {
@media (width <= 768px) {
font-size: 22px;
}
}
@media (max-width: 768px) {
@media (width <= 768px) {
flex-direction: row;
justify-content: space-between;
align-items: center;
@ -533,7 +533,7 @@ $category-text: hsl(219, 23%, 33%);
border-bottom: 1px solid $light-blue-border;
}
@media (max-width: 768px) {
@media (width <= 768px) {
.name {
display: block;
}
@ -549,20 +549,20 @@ $category-text: hsl(219, 23%, 33%);
margin: 20px 0;
}
@media (min-width: 768px) {
@media (width >= 768px) {
width: calc(100% - 200px);
}
@media (max-width: 768px) {
@media (width <= 768px) {
margin-left: 0;
}
}
@media (max-width: 768px) {
@media (width <= 768px) {
flex-direction: column;
}
@media (max-width: 450px) {
@media (width <= 450px) {
padding: 0 25px;
}
}

View File

@ -2854,7 +2854,7 @@ nav {
}
/* -- media queries -- */
@media (max-width: 1426px) {
@media (width <= 1426px) {
.portico-landing.hello .integrations .integration-icons .hide-1 {
display: none;
}
@ -2868,7 +2868,7 @@ nav {
}
}
@media (max-width: 1390px) {
@media (width <= 1390px) {
.portico-landing.plans
.pricing-container
.block:not(:first-child)
@ -2877,7 +2877,7 @@ nav {
}
}
@media (max-width: 1376px) {
@media (width <= 1376px) {
.portico-landing.plans .price-box {
margin: 20px;
}
@ -2917,14 +2917,14 @@ nav {
}
}
@media (min-width: 1296px), (max-width: 985px) and (min-width: 687px) {
@media (width >= 1296px), (687px <= width <= 985px) {
/* while there are nine, show only two rows of four. */
.portico-landing .testimonials .company-box > div:last-of-type {
display: none;
}
}
@media (max-width: 1295px) {
@media (width <= 1295px) {
.portico-landing.hello .apps .right-side {
display: none;
}
@ -2952,7 +2952,7 @@ nav {
}
}
@media (max-width: 1100px) {
@media (width <= 1100px) {
.tour .carousel-inner img {
&.zulip-topic,
&.slack-overwhelming,
@ -2992,7 +2992,7 @@ nav {
}
}
@media (max-width: 1024px) {
@media (width <= 1024px) {
.portico-landing.hello .gradients .gradient {
height: 1400px;
}
@ -3060,7 +3060,7 @@ nav {
}
}
@media (max-width: 985px) {
@media (width <= 985px) {
.features .feature-box .text-content {
width: 100%;
height: auto;
@ -3161,7 +3161,7 @@ nav {
}
}
@media (max-width: 906px) {
@media (width <= 906px) {
.portico-landing.why-page .hero p br {
display: none;
}
@ -3188,7 +3188,7 @@ nav {
}
}
@media (max-width: 830px) {
@media (width <= 830px) {
.portico-landing.features-app {
section {
.headliner {
@ -3247,7 +3247,7 @@ nav {
}
}
@media (max-width: 768px) {
@media (width <= 768px) {
nav {
padding-left: 50px;
padding-right: 50px;
@ -3362,7 +3362,7 @@ nav {
}
}
@media (max-width: 686px) {
@media (width <= 686px) {
.portico-landing {
padding-top: 120px;
}
@ -3599,7 +3599,7 @@ nav {
}
}
@media (max-width: 640px) {
@media (width <= 640px) {
.portico-landing.hello .integrations .integration-icons .group {
margin: 10px 16px 0 16px;
}
@ -3617,7 +3617,7 @@ nav {
}
}
@media (max-width: 550px) {
@media (width <= 550px) {
.portico-landing.features-app {
section {
&.hero {
@ -3694,7 +3694,7 @@ nav {
}
}
@media (max-width: 450px) {
@media (width <= 450px) {
.portico-landing.plans .price-box {
display: inline-flex;
flex-direction: column;
@ -3790,7 +3790,7 @@ nav {
}
}
@media (max-width: 375px) {
@media (width <= 375px) {
.portico-landing.hello .integrations .integration-icons .group {
width: 130px;
height: 215px;
@ -3817,7 +3817,7 @@ nav {
}
}
@media (max-width: 360px) {
@media (width <= 360px) {
.portico-landing.features-app {
section {
.keyboard-shortcuts {
@ -3832,7 +3832,7 @@ nav {
}
/* For iPhone 5/SE device */
@media (max-width: 320px) {
@media (width <= 320px) {
.portico-landing.features-app {
section {
.keyboard-shortcuts {
@ -3846,7 +3846,7 @@ nav {
}
}
@media (max-width: 313px) {
@media (width <= 313px) {
.portico-landing .testimonials .quote-container {
width: 93%;
padding-left: 7%;

View File

@ -142,7 +142,7 @@
margin: 0 0 2px;
}
@media (max-width: 500px) {
@media (width <= 500px) {
margin-left: 0;
}
}
@ -173,7 +173,7 @@
vertical-align: middle;
}
@media (max-width: 500px) {
@media (width <= 500px) {
padding: 10px;
}
}

View File

@ -1352,7 +1352,7 @@ input.new-organization-button {
margin-bottom: 25px !important;
}
@media (max-width: 800px) {
@media (width <= 800px) {
.app.help {
.markdown {
width: 100vw;
@ -1426,7 +1426,7 @@ input.new-organization-button {
}
}
@media (max-width: 815px) {
@media (width <= 815px) {
.footer {
width: 450px;
margin-left: auto;
@ -1438,7 +1438,7 @@ input.new-organization-button {
}
}
@media (max-width: 767px) {
@media (width <= 767px) {
body {
padding: 0 !important;
}
@ -1489,7 +1489,7 @@ input.new-organization-button {
}
}
@media (max-width: 558px) {
@media (width <= 558px) {
.team {
.bdfl {
.profile-name,
@ -1500,7 +1500,7 @@ input.new-organization-button {
}
}
@media (max-width: 500px) {
@media (width <= 500px) {
.app.help {
.sidebar {
top: 39px;
@ -1555,7 +1555,7 @@ input.new-organization-button {
}
}
@media (max-width: 475px) {
@media (width <= 475px) {
.footer {
width: auto;
@ -1566,7 +1566,7 @@ input.new-organization-button {
}
}
@media (max-width: 400px) {
@media (width <= 400px) {
.footer {
section {
width: calc(100% - 40px);

View File

@ -1036,25 +1036,25 @@ button#register_auth_button_gitlab {
/* -- media queries -- */
@media (max-width: 950px) {
@media (width <= 950px) {
.split-view .left-side {
width: 400px;
}
}
@media (max-width: 850px) {
@media (width <= 850px) {
.split-view .left-side {
width: 350px;
}
}
@media (max-width: 815px) {
@media (width <= 815px) {
.flex {
min-height: calc(100vh - 530px);
}
}
@media (max-width: 795px) {
@media (width <= 795px) {
.register-account #registration {
padding: 10px;
}
@ -1116,7 +1116,7 @@ button#register_auth_button_gitlab {
}
}
@media (max-width: 500px) {
@media (width <= 500px) {
.new-style .get-started {
font-size: 1.6em;
}
@ -1160,7 +1160,7 @@ button#register_auth_button_gitlab {
}
}
@media (max-width: 400px) {
@media (width <= 400px) {
.flex {
min-height: calc(100vh - 560px);
}

View File

@ -225,7 +225,7 @@ p {
}
}
@media (min-width: 1680px) {
@media (width >= 1680px) {
.center-charts {
width: calc(
816px * 2

View File

@ -11,7 +11,7 @@
display: flex;
flex-direction: column;
@media (max-width: $md_max) {
@media (width < $md_min) {
height: 95%;
max-width: none;
width: 90%;
@ -279,7 +279,7 @@
white-space: nowrap;
}
@media (max-width: $md_max) {
@media (width < $md_min) {
/* Hide participants and last message time
on smaller screens. This ensures user always
has a nice UI experience. */

View File

@ -464,7 +464,7 @@
right: 12px;
}
@media (max-width: $sm_max) {
@media (width < $sm_min) {
.rendered_markdown .message_embed {
height: auto;

View File

@ -196,7 +196,7 @@
}
/* This max-width must be synced with message_viewport.is_narrow */
@media (max-width: $xl_max) {
@media (width < $xl_min) {
#sidebar-keyboard-shortcuts {
/* This is supposed to fix this appearing improperly in narrow
windows. It's likely the wrong solution; a proper fix likely
@ -210,14 +210,14 @@
}
}
@media (max-width: $md_max) {
@media (width < $md_min) {
#user_search_section .user-list-filter {
/* input should be 100% - 6px padding x2 - 1px border x2. */
width: calc(100% - 12px - 2px);
}
}
@media (max-width: $sm_max) {
@media (width < $sm_min) {
#userlist-toggle {
height: 30px;
line-height: 30px;

View File

@ -1761,7 +1761,7 @@ body:not(.night-mode) #settings_page .custom_user_field .datepicker {
margin: 20px;
}
@media (max-width: $lg_max) {
@media (width < $lg_min) {
.user-avatar-section,
.realm-icon-section {
float: none;
@ -1784,7 +1784,7 @@ body:not(.night-mode) #settings_page .custom_user_field .datepicker {
/* This value needs to match with the same in subscriptions.css, as
we have some shared styles declared there */
@media (max-width: $md_max) {
@media (width < $md_min) {
#settings_overlay_container {
/* this variable allows JavaScript to detect this media query */
--single-column: yes;
@ -1829,7 +1829,7 @@ body:not(.night-mode) #settings_page .custom_user_field .datepicker {
}
}
@media (max-width: $sm_max) {
@media (width < $sm_min) {
#pw_strength {
margin: auto;
}
@ -1862,7 +1862,7 @@ body:not(.night-mode) #settings_page .custom_user_field .datepicker {
}
}
@media (max-width: $ml_max) {
@media (width < $ml_min) {
#api_key_buttons,
#download_zuliprc {
flex-direction: column;
@ -1870,7 +1870,7 @@ body:not(.night-mode) #settings_page .custom_user_field .datepicker {
}
}
@media only screen and (max-width: $lg_max) {
@media only screen and (width < $lg_min) {
/* Show bot-information-box at full width on small
screen sizes. Not having this media query breaks the
information box */

View File

@ -1087,7 +1087,7 @@ ul.grey-box {
}
}
@media (max-width: $lg_max) {
@media (width < $lg_min) {
.subscriptions-container {
max-width: 95%;
}
@ -1103,7 +1103,7 @@ ul.grey-box {
}
}
@media (max-width: $lg_max) {
@media (width < $lg_min) {
.subscriptions-container .left .search-container {
flex-wrap: wrap;
justify-content: space-evenly;
@ -1119,7 +1119,7 @@ ul.grey-box {
Longer-term we should extract this logic two-column-overlay class
to read more naturally. */
@media (max-width: $md_max) {
@media (width < $md_min) {
.subscriptions-container {
position: relative;
overflow: hidden;
@ -1180,7 +1180,7 @@ ul.grey-box {
}
}
@media (max-width: $sm_max) {
@media (width < $sm_min) {
#subscription_overlay .subscription_settings .button-group {
display: block;
float: unset;

View File

@ -11,13 +11,13 @@
}
/* This max-width must be synced with message_viewport.is_narrow */
@media (max-width: $xl_max) {
@media (width < $xl_min) {
#typing_notifications {
margin-right: 7px;
}
}
@media (max-width: $md_max) {
@media (width < $md_min) {
#typing_notifications {
margin-right: 7px;
margin-left: 7px;

View File

@ -8,14 +8,14 @@
overflow: hidden;
background-color: hsl(0, 0%, 100%);
@media (max-width: $ml_max) {
@media (width < $ml_min) {
width: 100%;
}
}
input.user_status {
width: 336px;
@media (max-width: $ml_max) {
@media (width < $ml_min) {
width: 94%;
}
}

View File

@ -1584,7 +1584,7 @@ div.focused_table {
padding: 12px 6px;
overflow: hidden;
text-overflow: ellipsis;
@media (max-width: $sm_max) {
@media (width < $sm_min) {
padding: 7px 3.5px; /* based on having ~41.66% decrease */
}
i {
@ -1639,14 +1639,14 @@ div.focused_table {
height: 50%;
color: hsl(0, 0%, 88%);
font-size: 20px;
@media (max-width: $sm_max) {
@media (width < $sm_min) {
top: 10%;
}
}
&::before {
left: -3px;
@media (max-width: $sm_max) {
@media (width < $sm_min) {
/* this ensures the before "|" doesn't overlap
with the stream name text on small narrows */
left: 0;
@ -1671,7 +1671,7 @@ div.focused_table {
padding: 12px 0;
padding-left: 10px;
@media (max-width: $sm_max) {
@media (width < $sm_min) {
padding: 7px 0;
padding-left: 10px;
}
@ -1689,7 +1689,7 @@ div.focused_table {
font-size: 20px;
padding: 10px 15px 0 0;
@media (max-width: $sm_max) {
@media (width < $sm_min) {
padding: 5px 15px 0 0;
}
}
@ -1827,13 +1827,13 @@ div.focused_table {
padding: 0;
}
@media (min-width: $sm_min) {
@media (width >= $sm_min) {
.pill {
padding: 2px 0 2px 0 !important;
font-size: 14px;
}
}
@media (max-width: $sm_max) {
@media (width < $sm_min) {
#search_arrows .pill {
line-height: 20px;
@ -2600,7 +2600,7 @@ select.inline_select_topic_edit {
}
/* This max-width must be synced with message_viewport.is_narrow */
@media (max-width: $xl_max) {
@media (width < $xl_min) {
.app-main,
.header-main {
min-width: 750px;
@ -2680,7 +2680,7 @@ select.inline_select_topic_edit {
}
}
@media (max-width: $md_max) {
@media (width < $md_min) {
body {
padding: 0;
}
@ -2778,7 +2778,7 @@ select.inline_select_topic_edit {
}
}
@media (max-width: $sm_max) {
@media (width < $sm_min) {
.column-right.expanded .right-sidebar,
.column-left.expanded .left-sidebar {
margin-top: 31px;
@ -2883,7 +2883,7 @@ select.inline_select_topic_edit {
}
}
@media (max-width: $mm_max) {
@media (width < $mm_min) {
html {
overflow-x: hidden;
}
@ -2896,7 +2896,7 @@ select.inline_select_topic_edit {
}
}
@media (max-width: $md_max) {
@media (width < $md_min) {
#feedback_container {
width: calc(90% - 30px);
left: 5%;

View File

@ -9528,6 +9528,10 @@ postcss-loader@^4.0.2:
schema-utils "^3.0.0"
semver "^7.3.4"
"postcss-media-minmax@https://github.com/andersk/postcss-media-minmax.git#01239f17f4a9872ace1dd133cee526a7de4ac9f5":
version "5.0.0"
resolved "https://github.com/andersk/postcss-media-minmax.git#01239f17f4a9872ace1dd133cee526a7de4ac9f5"
postcss-media-query-parser@^0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz#27b39c6f4d94f81b1a73b8f76351c609e5cef244"