diff --git a/.stylelintignore b/.stylelintignore new file mode 100644 index 0000000000..4faf0d8932 --- /dev/null +++ b/.stylelintignore @@ -0,0 +1,3 @@ +node_modules +venv +build diff --git a/.stylelintrc.js b/.stylelintrc.js new file mode 100644 index 0000000000..cb62a31c5d --- /dev/null +++ b/.stylelintrc.js @@ -0,0 +1,7 @@ +module.exports = { + extends: '@wagtail/stylelint-config-wagtail', + rules: { + // Would be valuable for strict BEM components but is too hard to enforce with legacy code. + 'no-descending-specificity': null, + }, +}; diff --git a/.stylelintrc.yaml b/.stylelintrc.yaml deleted file mode 100644 index b984081371..0000000000 --- a/.stylelintrc.yaml +++ /dev/null @@ -1,6 +0,0 @@ -ignoreFiles: - - node_modules - - build/**/* - - venv/**/* -extends: - - '@wagtail/stylelint-config-wagtail' diff --git a/client/scss/components/_button.scss b/client/scss/components/_button.scss index 97bbef0e7a..5fc2a27793 100644 --- a/client/scss/components/_button.scss +++ b/client/scss/components/_button.scss @@ -1,3 +1,4 @@ +@use "sass:color"; // Core button style // Note that these styles include methods to render buttons the same x-browser, described here: // http: //cbjdigital.com/blog/2010/08/bulletproof_css_input_button_heights @@ -214,6 +215,7 @@ } } + // stylelint-disable-next-line no-duplicate-selectors &:hover { background-color: $color-button-hover; color: $color-white; @@ -302,12 +304,6 @@ border: 0; } - &.button--icon { - .icon { - @include svg-icon(1.5em); - } - } - &.button-strokeonhover { border: 1px solid transparent; @@ -597,7 +593,7 @@ button { background-color: $color-white; padding: 1em 10em 1em 1.5em; // 10em padding leaves room for controls margin-bottom: 1em; - border: 1px solid lighten($color-grey-4, 3%); // really trying to avoid creating more greys, but this one is better than grey 4 or 5 + border: 1px solid color.adjust($color-grey-4, $lightness: 3%); // really trying to avoid creating more greys, but this one is better than grey 4 or 5 } &.moving { diff --git a/client/scss/components/_chooser.scss b/client/scss/components/_chooser.scss index 8d8645ff08..6059144d80 100644 --- a/client/scss/components/_chooser.scss +++ b/client/scss/components/_chooser.scss @@ -36,7 +36,7 @@ overridden here? hmm. // TODO: [icon-font] remove when the Wagtail icon font is removed &:before { vertical-align: middle; - font-family: wagtail; + font-family: $font-wagtail-icons; content: ''; // position: relative display: inline-block; diff --git a/client/scss/components/_dropdown.legacy.scss b/client/scss/components/_dropdown.legacy.scss index 428be6b5ff..59c0cb0deb 100644 --- a/client/scss/components/_dropdown.legacy.scss +++ b/client/scss/components/_dropdown.legacy.scss @@ -329,6 +329,7 @@ } // Transitions +// stylelint-disable-next-line no-duplicate-selectors .dropdown ul { @include transition(opacity 0.2s linear); } diff --git a/client/scss/components/_footer.scss b/client/scss/components/_footer.scss index 30d445ab02..d1ad6a91f1 100644 --- a/client/scss/components/_footer.scss +++ b/client/scss/components/_footer.scss @@ -1,3 +1,5 @@ +@use "sass:math"; + .footer { $border-curvature: 3px; @include transition(bottom 0.5s ease 1s); @@ -82,7 +84,7 @@ .meta { float: right; text-align: right; - padding: 7px $grid-gutter-width / 2; + padding: 7px math.div($grid-gutter-width, 2); font-size: 0.85em; p { diff --git a/client/scss/components/_forms.scss b/client/scss/components/_forms.scss index 527a190660..a4573e31d7 100644 --- a/client/scss/components/_forms.scss +++ b/client/scss/components/_forms.scss @@ -1,3 +1,6 @@ +@use "sass:map"; +@use "sass:math"; +// stylelint-disable scss/comment-no-empty // These are the generic stylings for forms of any type. // If you're styling something specific to the page editing interface, // it probably ought to go in layouts/page-editor.scss @@ -92,8 +95,8 @@ select::-ms-expand { top: 1px; bottom: 0; width: 1.5em; - font-family: wagtail; - content: map-get($icons, 'arrow-down'); + font-family: $font-wagtail-icons; + content: map.get($icons, 'arrow-down'); border: 1px solid $color-input-border; border-width: 0 0 0 1px; text-align: center; @@ -134,9 +137,9 @@ select::-ms-expand { } &::before { - font-family: wagtail; + font-family: $font-wagtail-icons; vertical-align: -10%; - content: map-get($icons, 'cross'); + content: map.get($icons, 'cross'); } } @@ -191,7 +194,7 @@ label.required:after { &:before, &:after { - font-family: wagtail; + font-family: $font-wagtail-icons; position: absolute; top: 0.5em; line-height: 100%; @@ -246,19 +249,19 @@ label.required:after { .date_field, .date_time_field { .input:before { - content: map-get($icons, 'date'); + content: map.get($icons, 'date'); } } .time_field { .input:before { - content: map-get($icons, 'time'); + content: map.get($icons, 'time'); } } .url_field { .input:before { - content: map-get($icons, 'link'); + content: map.get($icons, 'link'); } } @@ -345,7 +348,7 @@ li.inline .field { // solve gutter issues of inline fields ul.inline li:first-child, li.inline:first-child { - margin-left: -$grid-gutter-width / 2; + margin-left: math.div(-$grid-gutter-width, 2); } // search-bars @@ -380,6 +383,7 @@ li.inline:first-child { } // Transitions +// stylelint-disable-next-line no-duplicate-selectors .help { @include transition(opacity 0.2s ease); } diff --git a/client/scss/components/_header.scss b/client/scss/components/_header.scss index c5b4efcf53..5977ab5ed9 100644 --- a/client/scss/components/_header.scss +++ b/client/scss/components/_header.scss @@ -1,3 +1,5 @@ +@use "sass:math"; + header { padding-top: 1em; padding-bottom: 1em; @@ -67,7 +69,7 @@ header { .breadcrumb { margin-left: -$desktop-nice-padding; margin-right: -$desktop-nice-padding; - padding-left: $desktop-nice-padding / 2; + padding-left: math.div($desktop-nice-padding, 2); } } } @@ -77,7 +79,7 @@ header { .breadcrumb { margin-bottom: 1rem; - padding-left: $desktop-nice-padding / 2; // rather than padding-left: revert; + padding-left: math.div($desktop-nice-padding, 2); // rather than padding-left: revert; } } diff --git a/client/scss/components/_help-block.scss b/client/scss/components/_help-block.scss index 704bf789b4..7ec972efd2 100644 --- a/client/scss/components/_help-block.scss +++ b/client/scss/components/_help-block.scss @@ -1,3 +1,5 @@ +@use "sass:color"; +@use "sass:map"; // Help text formatters .help-block { padding: 1em; @@ -26,17 +28,17 @@ position: relative; &:before { - font-family: wagtail; + font-family: $font-wagtail-icons; position: absolute; left: 1em; top: 0.7em; - content: map-get($icons, 'help'); + content: map.get($icons, 'help'); font-size: 1.4em; } } .help-info { - background-color: lighten($color-blue, 30%); + background-color: color.adjust($color-blue, $lightness: 30%); &:before { color: $color-blue; @@ -44,20 +46,20 @@ } .help-warning { - background-color: lighten($color-orange, 30%); + background-color: color.adjust($color-orange, $lightness: 30%); &:before { color: $color-orange; - content: map-get($icons, 'warning'); + content: map.get($icons, 'warning'); } } .help-critical { - background-color: lighten($color-red, 40%); + background-color: color.adjust($color-red, $lightness: 40%); &:before { color: $color-red; - content: map-get($icons, 'warning'); + content: map.get($icons, 'warning'); } } diff --git a/client/scss/components/_icons.scss b/client/scss/components/_icons.scss index baa31d64d2..b03a6a87fa 100644 --- a/client/scss/components/_icons.scss +++ b/client/scss/components/_icons.scss @@ -1,3 +1,4 @@ +@use "sass:string"; // The wagtail font isn't available in WOFF2, so a @font-face is set here without a mixin. @font-face { font-family: 'wagtail'; @@ -29,12 +30,14 @@ @include icon(); // from _mixins.scss } +// stylelint-disable-next-line no-duplicate-selectors .icon:after, .hallotoolbar [class^='icon-']:after, .hallotoolbar [class^='icon-']:after { text-align: right; } +// stylelint-disable-next-line no-duplicate-selectors .hallotoolbar [class^='icon-'], .hallotoolbar [class*=' icon-']:before, .hallotoolbar [class*=' icon-']:before, @@ -50,13 +53,13 @@ @each $icon, $content in $icons { .icon-#{$icon}:before { - content: quote(#{$content}); + content: string.quote(#{$content}); } } @each $icon, $content in $icons-after { .icon-#{$icon}:after { - content: quote(#{$content}); + content: string.quote(#{$content}); } } @@ -155,6 +158,7 @@ svg.icon-spinner { // TODO: leave only class when iconfont styles are removed } } +// stylelint-disable-next-line no-duplicate-selectors .icon { &.initial { @include svg-icon(1em); diff --git a/client/scss/components/_indicator.scss b/client/scss/components/_indicator.scss index 1e95606eee..d1b4ecfa1d 100644 --- a/client/scss/components/_indicator.scss +++ b/client/scss/components/_indicator.scss @@ -1,3 +1,4 @@ +@use "sass:math"; // ============================================================================= // Indicator light // ============================================================================= @@ -42,7 +43,7 @@ $c-indicator-margin: 0.25rem; &:before { content: ''; - width: $c-indicator-size / 2; + width: math.div($c-indicator-size, 2); height: $c-indicator-size; position: absolute; top: 0; diff --git a/client/scss/components/_listing.scss b/client/scss/components/_listing.scss index ea82f6933e..0882c10ce0 100644 --- a/client/scss/components/_listing.scss +++ b/client/scss/components/_listing.scss @@ -253,6 +253,7 @@ ul.listing { } } + // stylelint-disable-next-line no-duplicate-selectors .button-secondary { background-color: $color-white; } @@ -450,6 +451,7 @@ ul.listing { word-wrap: break-word; } +// stylelint-disable-next-line no-duplicate-selectors ul.listing { border-top: 1px dashed $color-input-border; margin-bottom: 2em; @@ -534,9 +536,6 @@ table.listing { ul { @include unlist(); - } - - ul { margin-top: -1.7em; } @@ -739,6 +738,7 @@ table.listing { } } +// stylelint-disable no-duplicate-selectors // Transitions .listing { diff --git a/client/scss/components/_loading-mask.scss b/client/scss/components/_loading-mask.scss index 92432b7c78..4a3b2f691d 100644 --- a/client/scss/components/_loading-mask.scss +++ b/client/scss/components/_loading-mask.scss @@ -1,3 +1,4 @@ +@use "sass:map"; // Loading mask: overlays a certain area with a loading spinner and a faded out cover to prevent interaction .loading-mask { &.loading { @@ -26,9 +27,9 @@ left: 50%; top: 50%; margin: -15px 0 0 -15px; - font-family: wagtail; + font-family: $font-wagtail-icons; animation: spin-wag 0.5s infinite linear; - content: map-get($icons, 'spinner'); + content: map.get($icons, 'spinner'); z-index: 2; color: $color-teal; } diff --git a/client/scss/components/_main-nav.scss b/client/scss/components/_main-nav.scss index bec70c3452..387b98ea2e 100644 --- a/client/scss/components/_main-nav.scss +++ b/client/scss/components/_main-nav.scss @@ -1,3 +1,5 @@ +@use "sass:map"; + .nav-wrapper { position: relative; margin-left: -$menu-width; @@ -257,10 +259,10 @@ } &:before { - font-family: wagtail; + font-family: $font-wagtail-icons; font-weight: 200; text-transform: none; - content: map-get($icons, 'search'); + content: map.get($icons, 'search'); display: block; height: 100%; line-height: 3.3em; @@ -508,6 +510,7 @@ body.explorer-open { z-index: 5; } +// stylelint-disable-next-line no-duplicate-selectors .nav-wrapper { z-index: 2; } @@ -520,6 +523,7 @@ body.explorer-open { // .content-wrapper { // z-index: 3; // } +// stylelint-disable-next-line no-duplicate-selectors .nav-submenu { z-index: 6; } diff --git a/client/scss/components/_messages.scss b/client/scss/components/_messages.scss index bd87e698c5..2b22a1b2dc 100644 --- a/client/scss/components/_messages.scss +++ b/client/scss/components/_messages.scss @@ -1,6 +1,5 @@ // Messages are specific to Django's 'Messaging' system which adds messages into the session, // for display on the next page visited. These appear as an animated banner at the top of the page. -// // For inline help text, see typography.scss .messages { position: relative; diff --git a/client/scss/components/_status-tag.scss b/client/scss/components/_status-tag.scss index adca7d1c90..774ae59c7c 100644 --- a/client/scss/components/_status-tag.scss +++ b/client/scss/components/_status-tag.scss @@ -1,11 +1,13 @@ +@use "sass:color"; + .status-tag { border-radius: 2px; text-align: center; display: inline-block; text-transform: uppercase; padding: 0 0.5em; - border: 1px solid lighten($color-grey-2, 30%); - color: lighten($color-grey-2, 30%); + border: 1px solid color.adjust($color-grey-2, $lightness: 30%); + color: color.adjust($color-grey-2, $lightness: 30%); -webkit-font-smoothing: auto; line-height: 19px; font-size: 0.8em; diff --git a/client/scss/components/_switch.scss b/client/scss/components/_switch.scss index d917b991ff..65a7ac219b 100644 --- a/client/scss/components/_switch.scss +++ b/client/scss/components/_switch.scss @@ -1,9 +1,11 @@ +@use "sass:math"; + $switch-width: 40px; $switch-height: 20px; $switch-border: 2px; $switch-outline: 3px; -$switch-border-radius: ($switch-height + $switch-border * 2) / 2; +$switch-border-radius: math.div(($switch-height + $switch-border * 2), 2); $switch-outline-radius: $switch-border-radius + $switch-outline; // All the greys in Wagtail are really dark or really bright @@ -67,9 +69,6 @@ $switch-color-middle-grey: #777; [type=checkbox]:disabled + &__toggle::after { opacity: 0.5; - } - - [type=checkbox]:disabled + &__toggle::after { box-shadow: none; } diff --git a/client/scss/components/_tag.scss b/client/scss/components/_tag.scss index d054d9888c..a17815551f 100644 --- a/client/scss/components/_tag.scss +++ b/client/scss/components/_tag.scss @@ -1,18 +1,18 @@ +@use "sass:map"; // free tagging tags from taggit .tag { border-radius: 2px; background-color: $color-teal; - padding-right: 0.5em; padding: 0.2em 0.5em; color: $color-white; line-height: 2em; white-space: nowrap; &:before { - font-family: wagtail; + font-family: $font-wagtail-icons; display: inline-block; color: $color-white; - content: map-get($icons, 'tag'); + content: map.get($icons, 'tag'); padding-right: 0.5em; } diff --git a/client/scss/elements/_forms.scss b/client/scss/elements/_forms.scss index 7d44fdfa94..ab8a3f3b56 100644 --- a/client/scss/elements/_forms.scss +++ b/client/scss/elements/_forms.scss @@ -1,3 +1,4 @@ +@use "sass:map"; // These are the generic stylings for forms of any type. // If you're styling something specific to the page editing interface, // it probably ought to go in layouts/page-editor.scss @@ -168,7 +169,7 @@ input[type=radio] { input[type=radio]:before { border-radius: 100%; - font-family: wagtail; + font-family: $font-wagtail-icons; font-style: normal; text-align: center; position: absolute; @@ -176,7 +177,7 @@ input[type=radio]:before { left: -2px; cursor: pointer; display: block; - content: map-get($icons, 'radio-full'); + content: map.get($icons, 'radio-full'); width: 1em; height: 1em; line-height: 1.1em; @@ -187,7 +188,7 @@ input[type=radio]:before { } input[type=radio]:checked:before { - content: map-get($icons, 'radio-full'); + content: map.get($icons, 'radio-full'); color: $color-teal; } @@ -199,7 +200,7 @@ input[type=checkbox] { } input[type=checkbox]:before { - font-family: wagtail; + font-family: $font-wagtail-icons; font-style: normal; text-align: center; position: absolute; @@ -216,7 +217,7 @@ input[type=checkbox]:before { } input[type=checkbox]:checked:before { - content: map-get($icons, 'tick'); + content: map.get($icons, 'tick'); } input[type=checkbox][disabled]:before { diff --git a/client/scss/overrides/_vendor.datetimepicker.scss b/client/scss/overrides/_vendor.datetimepicker.scss index 1406fbd769..939f570ced 100644 --- a/client/scss/overrides/_vendor.datetimepicker.scss +++ b/client/scss/overrides/_vendor.datetimepicker.scss @@ -1,3 +1,5 @@ +@use "sass:map"; + .xdsoft_datetimepicker { box-shadow: 0 5px 10px -5px rgba(0, 0, 0, 0.4); background: $color-white; @@ -68,7 +70,7 @@ &:before { font-size: 1.5em; - font-family: wagtail; + font-family: $font-wagtail-icons; width: 1em; line-height: 1.3em; text-align: center; @@ -84,7 +86,7 @@ float: left; &:before { - content: map-get($icons, 'arrow-left'); + content: map.get($icons, 'arrow-left'); } } @@ -93,7 +95,7 @@ margin-left: 5px; &:before { - content: map-get($icons, 'home'); + content: map.get($icons, 'home'); } } @@ -101,7 +103,7 @@ float: right; &:before { - content: map-get($icons, 'arrow-right'); + content: map.get($icons, 'arrow-right'); } } @@ -127,11 +129,11 @@ } .xdsoft_prev:before { - content: map-get($icons, 'arrow-up'); + content: map.get($icons, 'arrow-up'); } .xdsoft_next:before { - content: map-get($icons, 'arrow-down'); + content: map.get($icons, 'arrow-down'); } .xdsoft_time_box { diff --git a/client/scss/overrides/_vendor.tagit.scss b/client/scss/overrides/_vendor.tagit.scss index ca2e78998a..a991a83a4c 100644 --- a/client/scss/overrides/_vendor.tagit.scss +++ b/client/scss/overrides/_vendor.tagit.scss @@ -1,3 +1,4 @@ +@use "sass:map"; // taggit tagging .tagit { padding: 0.6em 1.2em; @@ -31,10 +32,10 @@ } .ui-icon-close:before { - font-family: wagtail; + font-family: $font-wagtail-icons; display: block; color: $color-grey-3; - content: map-get($icons, 'cross'); + content: map.get($icons, 'cross'); } .ui-icon-close:hover:before { diff --git a/client/scss/settings/_variables.icons.scss b/client/scss/settings/_variables.icons.scss index 21450de3bf..cd2a8697cb 100644 --- a/client/scss/settings/_variables.icons.scss +++ b/client/scss/settings/_variables.icons.scss @@ -1,3 +1,4 @@ +@use "sass:map"; $icons: ( 'arrow-down-big': '\e030', 'arrow-down': '\e01a', @@ -84,7 +85,7 @@ $icons: ( ); $icons-after: ( - 'arrow-down-after': map-get($icons, 'arrow-down'), - 'arrow-right-after': map-get($icons, 'arrow-right'), - 'arrow-up-after': map-get($icons, 'arrow-up'), + 'arrow-down-after': map.get($icons, 'arrow-down'), + 'arrow-right-after': map.get($icons, 'arrow-right'), + 'arrow-up-after': map.get($icons, 'arrow-up'), ); diff --git a/client/scss/settings/_variables.scss b/client/scss/settings/_variables.scss index 6947c1d040..f914f40cc4 100644 --- a/client/scss/settings/_variables.scss +++ b/client/scss/settings/_variables.scss @@ -1,3 +1,4 @@ +@use "sass:color"; // paths // We can't use absolute paths here, because those are dependent on Django's @@ -48,13 +49,13 @@ $color-white: #fff; $color-black: #000; // darker to lighter -$color-grey-1: darken($color-white, 80); -$color-grey-2: darken($color-white, 70); -$color-grey-3: darken($color-white, 15); -$color-grey-4: darken($color-white, 10); -$color-grey-5: darken($color-white, 2); +$color-grey-1: color.adjust($color-white, $lightness: -80%); +$color-grey-2: color.adjust($color-white, $lightness: -70%); +$color-grey-3: color.adjust($color-white, $lightness: -15%); +$color-grey-4: color.adjust($color-white, $lightness: -10%); +$color-grey-5: color.adjust($color-white, $lightness: -2%); -$color-menu-text: darken($color-white, 20); +$color-menu-text: color.adjust($color-white, $lightness: -20%); $color-thead-bg: $color-grey-5; $color-header-bg: $color-teal; @@ -63,16 +64,16 @@ $color-fieldset-hover: $color-grey-5; $color-input-border: $color-grey-4; $color-input-focus: var(--color-input-focus); $color-input-focus-border: var(--color-input-focus-border); -$color-input-error-bg: lighten(saturate($color-red, 28), 45); +$color-input-error-bg: color.adjust(color.adjust($color-red, $saturation: 28%), $lightness: 45%); $color-button: $color-teal; $color-button-hover: $color-teal-darker; $color-button-yes: $color-green-dark; -$color-button-yes-hover: darken($color-button-yes, 8%); +$color-button-yes-hover: color.adjust($color-button-yes, $lightness: -8%); $color-button-no: $color-red-dark; -$color-button-no-hover: darken($color-button-no, 20%); +$color-button-no-hover: color.adjust($color-button-no, $lightness: -20%); $color-button-warning: $color-orange-dark; -$color-button-warning-hover: darken($color-button-warning, 20%); +$color-button-warning-hover: color.adjust($color-button-warning, $lightness: -20%); $color-link: $color-teal-darker; $color-link-hover: $color-teal-dark; @@ -81,8 +82,8 @@ $color-link-hover: $color-teal-dark; // because it shouldn’t be reused for anything else in the UI. $color-focus-outline: #ffbf47; -$color-text-base: darken($color-white, 85); -$color-text-input: darken($color-white, 90); +$color-text-base: color.adjust($color-white, $lightness: -85%); +$color-text-input: color.adjust($color-white, $lightness: -90%); // Color states $color-state-live: #59b524; @@ -98,6 +99,8 @@ $system-color-button-text: ButtonText; // Fonts $font-sans: Open Sans, Arial, sans-serif; $font-serif: Roboto Slab, Georgia, serif; +// Legacy icon font, to be removed in the near future. +$font-wagtail-icons: wagtail; // misc sizing $thumbnail-width: 130px; @@ -123,12 +126,12 @@ $draftail-editor-z-index: $nav-wrapper-inner-z-index + 1; $object-title-height: 40px; // Nav -$nav-grey-1: darken($color-white, 80); -$nav-grey-2: darken($color-white, 60); +$nav-grey-1: color.adjust($color-white, $lightness: -80%); +$nav-grey-2: color.adjust($color-white, $lightness: -60%); $nav-grey-3: #262626; $nav-item-hover-bg: rgba(100, 100, 100, 0.15); -$nav-item-active-bg: darken($color-white, 90); -$nav-submenu-bg: darken($color-white, 85); +$nav-item-active-bg: color.adjust($color-white, $lightness: -90%); +$nav-submenu-bg: color.adjust($color-white, $lightness: -85%); $nav-footer-account-bg: $nav-item-active-bg; $nav-footer-submenu-bg: $nav-submenu-bg; $nav-footer-closed-height: 50px; @@ -136,14 +139,14 @@ $nav-footer-submenu-height: 77px; $nav-footer-open-height: $nav-footer-closed-height + $nav-footer-submenu-height; // Nav search -$nav-search-color: darken($color-white, 20); -$nav-search-border: darken($color-white, 40); +$nav-search-color: color.adjust($color-white, $lightness: -20%); +$nav-search-border: color.adjust($color-white, $lightness: -40%); $nav-search-bg: $nav-grey-1; $nav-search-hover-bg: $nav-item-hover-bg; $nav-search-focus-color: $color-white; $nav-search-focus-bg: $nav-item-hover-bg; // Form Errors -$color-text-error: change-color($color-red, $saturation: 69, $lightness: 52); -$color-text-error-forced-color: change-color($color-red, $saturation: 100, $lightness: 50); -$color-text-warning-forced-color: change-color($color-orange, $saturation: 100, $lightness: 70); +$color-text-error: color.change($color-red, $saturation: 69%, $lightness: 52%); +$color-text-error-forced-color: color.change($color-red, $saturation: 100%, $lightness: 50%); +$color-text-warning-forced-color: color.change($color-orange, $saturation: 100%, $lightness: 70%); diff --git a/client/scss/tools/_functions.breakpoints.scss b/client/scss/tools/_functions.breakpoints.scss index 42a8f16bd1..a3d4cf4315 100644 --- a/client/scss/tools/_functions.breakpoints.scss +++ b/client/scss/tools/_functions.breakpoints.scss @@ -1,30 +1,28 @@ +@use "sass:list"; +@use "sass:map"; // Based upon the fine work and thoughts from Bootstrap v4. -// // Copyright 2011-2018 The Bootstrap Authors // Copyright 2011-2018 Twitter, Inc. // Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) // Name of the next breakpoint, or null for the last breakpoint. -// // >> breakpoint-next(sm) // md @function breakpoint-next($name) { - $breakpoint-names: map-keys($breakpoints); - $n: index($breakpoint-names, $name); - @return if($n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null); + $breakpoint-names: map.keys($breakpoints); + $n: list.index($breakpoint-names, $name); + @return if($n < list.length($breakpoint-names), list.nth($breakpoint-names, $n + 1), null); } // Minimum breakpoint width. Null for the smallest (first) breakpoint. -// // >> breakpoint-min(sm) // 50em @function breakpoint-min($name) { - $min: map-get($breakpoints, $name); + $min: map.get($breakpoints, $name); @return if($min != 0, $min, null); } // Maximum breakpoint width. Null for the largest (last) breakpoint. -// // >> breakpoint-max(sm) // 56.1875em @function breakpoint-max($name) { diff --git a/client/scss/tools/_mixins.breakpoints.scss b/client/scss/tools/_mixins.breakpoints.scss index faaa82feaa..fd2c91de26 100644 --- a/client/scss/tools/_mixins.breakpoints.scss +++ b/client/scss/tools/_mixins.breakpoints.scss @@ -1,5 +1,4 @@ // Based upon the fine work and thoughts from Bootstrap v4. -// // Copyright 2011-2018 The Bootstrap Authors // Copyright 2011-2018 Twitter, Inc. // Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) diff --git a/client/scss/tools/_mixins.general.scss b/client/scss/tools/_mixins.general.scss index b92d769118..1d872d5bda 100644 --- a/client/scss/tools/_mixins.general.scss +++ b/client/scss/tools/_mixins.general.scss @@ -87,7 +87,7 @@ @mixin icon () { @include font-smoothing; - font-family: 'wagtail'; + font-family: $font-wagtail-icons; font-style: normal; font-weight: normal; font-variant: normal; @@ -101,12 +101,6 @@ margin-right: 0.2em; } -@mixin svg-icon ($size: 1.5em, $position: text-top) { - width: $size; - height: $size; - vertical-align: $position; -} - // Applies given rules on hover, except for touch screens. // Relies on feature detection to add a no-touch class on the html element. @mixin hover { diff --git a/client/scss/tools/_mixins.grid.scss b/client/scss/tools/_mixins.grid.scss index 0b6ae790a8..f0a379c9e0 100644 --- a/client/scss/tools/_mixins.grid.scss +++ b/client/scss/tools/_mixins.grid.scss @@ -1,5 +1,7 @@ +@use "sass:math"; + // Utility variable - you should never need to modify this -$padding: $grid-gutter-width * 0.5; +$padding: math.div($grid-gutter-width, 2); // Our row container @mixin row($padding: 0) { @@ -22,32 +24,32 @@ $padding: $grid-gutter-width * 0.5; box-sizing: border-box; display: inline; float: left; - width: 100% * ($x / $grid-columns); + width: 100% * math.div($x, $grid-columns); padding-right: $padding; padding-left: $padding; } @mixin table-column($x, $padding: $padding, $grid-columns: $grid-columns) { box-sizing: border-box; - width: 100% * ($x / $grid-columns); + width: 100% * math.div($x, $grid-columns); } // Push adds left padding @mixin push($offset: 1, $grid-columns: $grid-columns) { - margin-left: 100% * ($offset / $grid-columns); + margin-left: 100% * math.div($offset, $grid-columns); } @mixin push-padding($offset: 1, $grid-columns: $grid-columns) { - padding-left: 100% * ($offset / $grid-columns); + padding-left: 100% * math.div($offset, $grid-columns); } // Pull adds right padding @mixin pull($offset: 1, $grid-columns: $grid-columns) { - margin-right: 100% * ($offset / $grid-columns); + margin-right: 100% * math.div($offset, $grid-columns); } @mixin pull-padding($offset: 1, $grid-columns: $grid-columns) { - padding-right: 100% * ($offset / $grid-columns); + padding-right: 100% * math.div($offset, $grid-columns); } // only used in places where padding not applied to same elements as row or row-flush diff --git a/client/scss/tools/_various.colors.scss b/client/scss/tools/_various.colors.scss index 37183e4486..2658018674 100644 --- a/client/scss/tools/_various.colors.scss +++ b/client/scss/tools/_various.colors.scss @@ -1,17 +1,22 @@ +@use "sass:math"; +@use "sass:color"; +@use "sass:list"; +@use "sass:meta"; + // $color is either a color or an hsl tuple @mixin define-color($name, $color) { $h: null; $s: null; $l: null; - @if type-of($color) == color { - $h: hue($color) / 1deg; // Cast to unitless - $s: saturation($color); - $l: lightness($color); + @if meta.type-of($color) == color { + $h: math.div(color.hue($color), 1deg); // Cast to unitless + $s: color.saturation($color); + $l: color.lightness($color); } @else { - $h: nth($color, 1); - $s: nth($color, 2); - $l: nth($color, 3); + $h: list.nth($color, 1); + $s: list.nth($color, 2); + $l: list.nth($color, 3); } --#{$name}-hue: #{$h}; @@ -25,38 +30,38 @@ } @function css-darken($hsl-tuple, $darken-by) { - $h: nth($hsl-tuple, 1); - $s: nth($hsl-tuple, 2); - $l: nth($hsl-tuple, 3); + $h: list.nth($hsl-tuple, 1); + $s: list.nth($hsl-tuple, 2); + $l: list.nth($hsl-tuple, 3); @return ($h, $s, calc(#{$l} - #{$darken-by + 0%})); } @function css-lighten($hsl-tuple, $lighten-by) { - $h: nth($hsl-tuple, 1); - $s: nth($hsl-tuple, 2); - $l: nth($hsl-tuple, 3); + $h: list.nth($hsl-tuple, 1); + $s: list.nth($hsl-tuple, 2); + $l: list.nth($hsl-tuple, 3); @return ($h, $s, calc(#{$l} + #{$lighten-by + 0%})); } @function css-saturate($hsl-tuple, $saturate-by) { - $h: nth($hsl-tuple, 1); - $s: nth($hsl-tuple, 2); - $l: nth($hsl-tuple, 3); + $h: list.nth($hsl-tuple, 1); + $s: list.nth($hsl-tuple, 2); + $l: list.nth($hsl-tuple, 3); @return ($h, calc(#{$s} + #{$saturate-by + 0%}), $l); } @function css-desaturate($hsl-tuple, $desaturate-by) { - $h: nth($hsl-tuple, 1); - $s: nth($hsl-tuple, 2); - $l: nth($hsl-tuple, 3); + $h: list.nth($hsl-tuple, 1); + $s: list.nth($hsl-tuple, 2); + $l: list.nth($hsl-tuple, 3); @return ($h, calc(#{$s} - #{$desaturate-by + 0%}), $l); } @function css-adjust-hue($hsl-tuple, $adjust-by) { - $h: nth($hsl-tuple, 1); - $s: nth($hsl-tuple, 2); - $l: nth($hsl-tuple, 3); + $h: list.nth($hsl-tuple, 1); + $s: list.nth($hsl-tuple, 2); + $l: list.nth($hsl-tuple, 3); @return (calc(#{$h} + #{$adjust-by}), $s, $l); } @function css-transparentize($hsl-tuple, $alpha) { - $h: nth($hsl-tuple, 1); - $s: nth($hsl-tuple, 2); - $l: nth($hsl-tuple, 3); + $h: list.nth($hsl-tuple, 1); + $s: list.nth($hsl-tuple, 2); + $l: list.nth($hsl-tuple, 3); @return ($h, $s, $l, $alpha); } diff --git a/client/src/components/CommentApp/main.scss b/client/src/components/CommentApp/main.scss index 3b6bbf3a50..502ed36d3c 100644 --- a/client/src/components/CommentApp/main.scss +++ b/client/src/components/CommentApp/main.scss @@ -144,6 +144,7 @@ $box-padding: 10px; pointer-events: none; } +// stylelint-disable no-invalid-position-at-import-rule @import 'components/CommentHeader/style'; @import 'components/Comment/style'; @import 'components/CommentReply/style'; diff --git a/client/src/components/Draftail/blocks/ImageBlock.scss b/client/src/components/Draftail/blocks/ImageBlock.scss index 8782e033bd..9d1121d744 100644 --- a/client/src/components/Draftail/blocks/ImageBlock.scss +++ b/client/src/components/Draftail/blocks/ImageBlock.scss @@ -1,3 +1,4 @@ +@use "sass:color"; @mixin wagtail-label-overrides { float: none; width: initial; @@ -24,7 +25,7 @@ color: $color-text-base; &[readonly] { - color: transparentize($color-text-base, 0.5); + color: color.adjust($color-text-base, $alpha: -0.5); } } diff --git a/client/src/components/Explorer/Explorer.scss b/client/src/components/Explorer/Explorer.scss index 55ceb0ecb6..d1fc7cbbcf 100644 --- a/client/src/components/Explorer/Explorer.scss +++ b/client/src/components/Explorer/Explorer.scss @@ -5,6 +5,8 @@ $c-explorer-secondary: #a5a5a5; $c-explorer-easing: cubic-bezier(0.075, 0.82, 0.165, 1); $menu-footer-height: 50px; +@use "sass:map"; + @import 'ExplorerItem'; .explorer__wrapper, @@ -181,8 +183,8 @@ $menu-footer-height: 50px; top: $margin + 3px; bottom: 0; width: 2em; - font-family: wagtail; - content: map-get($icons, 'arrow-down'); + font-family: $font-wagtail-icons; + content: map.get($icons, 'arrow-down'); text-align: center; font-size: 1.2em; pointer-events: none; diff --git a/client/src/components/Hallo/_halloeditor.scss b/client/src/components/Hallo/_halloeditor.scss index 8081a4fd19..f528cf1283 100644 --- a/client/src/components/Hallo/_halloeditor.scss +++ b/client/src/components/Hallo/_halloeditor.scss @@ -55,6 +55,7 @@ font-family: inherit; } + // stylelint-disable-next-line no-duplicate-selectors h2 { font-size: 2em; line-height: 1.2em; diff --git a/client/src/components/Hallo/_richtext-image.scss b/client/src/components/Hallo/_richtext-image.scss index 261141e4d8..5d980b9ead 100644 --- a/client/src/components/Hallo/_richtext-image.scss +++ b/client/src/components/Hallo/_richtext-image.scss @@ -1,7 +1,6 @@ // These styles correspond to the image formats defined in wagtailimages/formats.py, // so that images displayed in the rich text field receive more or less the same // styling that they would receive on the site front-end. -// // Wagtail installations that define their own image formats (in a myapp.image_formats module) // should ideally use the insert_editor_css hook to pass in their own custom CSS to have those // images render within the rich text area in the same styles that would appear on the front-end. diff --git a/client/src/components/PageExplorer/PageExplorer.scss b/client/src/components/PageExplorer/PageExplorer.scss index 9f547b894e..0299a452e0 100644 --- a/client/src/components/PageExplorer/PageExplorer.scss +++ b/client/src/components/PageExplorer/PageExplorer.scss @@ -5,6 +5,8 @@ $c-page-explorer-secondary: #a5a5a5; $c-page-explorer-easing: cubic-bezier(0.075, 0.82, 0.165, 1); $menu-footer-height: 50px; +@use "sass:map"; + @import 'PageExplorerItem'; .c-page-explorer { @@ -141,8 +143,8 @@ $explorer-header-horizontal-padding: 10px; top: $margin + 3px; bottom: 0; width: 2em; - font-family: wagtail; - content: map-get($icons, 'arrow-down'); + font-family: $font-wagtail-icons; + content: map.get($icons, 'arrow-down'); text-align: center; font-size: 1.2em; pointer-events: none; diff --git a/client/src/components/Sidebar/Sidebar.scss b/client/src/components/Sidebar/Sidebar.scss index 0ed52c4b48..01a73a74b9 100644 --- a/client/src/components/Sidebar/Sidebar.scss +++ b/client/src/components/Sidebar/Sidebar.scss @@ -113,7 +113,7 @@ } } - +// stylelint-disable no-invalid-position-at-import-rule @import 'SidebarPanel'; @import 'menu/MenuItem'; @import 'menu/SubMenuItem'; diff --git a/client/src/components/StreamField/scss/_variables.scss b/client/src/components/StreamField/scss/_variables.scss index 26c10cce32..46c38edf97 100644 --- a/client/src/components/StreamField/scss/_variables.scss +++ b/client/src/components/StreamField/scss/_variables.scss @@ -1,3 +1,5 @@ +@use "sass:math"; + $grid-gutter-width: 30px !default; $header-padding-horizontal: 4px !default; $header-padding-vertical: 6px; @@ -9,7 +11,7 @@ $add-button-size: 34px !default; $add-button-font-size: 24px !default; $type-button-padding-vertical: 10px !default; $type-button-padding-horizontal: 10px !default; -$children-container-padding: $add-button-size / 2 !default; +$children-container-padding: math.div($add-button-size, 2) !default; $content-padding-horizontal: 24px !default; $content-padding-vertical: 16px !default; $action-font-size: 18px; diff --git a/client/src/components/StreamField/scss/components/c-sf-add-panel.scss b/client/src/components/StreamField/scss/components/c-sf-add-panel.scss index 1a45f81d7d..075dc6218f 100644 --- a/client/src/components/StreamField/scss/components/c-sf-add-panel.scss +++ b/client/src/components/StreamField/scss/components/c-sf-add-panel.scss @@ -1,15 +1,17 @@ +@use "sass:math"; + .c-sf-add-panel { position: relative; - padding: $grid-gutter-width / 4 + padding: $grid-gutter-width * 0.25 0 $grid-gutter-width; border-radius: $border-radius; user-select: none; @media (min-width: $screen-l-min) { - padding: $grid-gutter-width / 4 + padding: $grid-gutter-width * 0.25 $grid-gutter-width * 2 - $add-button-size - $grid-gutter-width / 2; + $add-button-size - math.div($grid-gutter-width, 2); } &__group-title { @@ -22,7 +24,7 @@ flex-flow: row wrap; margin-left: -$add-panel-gutter; margin-right: -$add-panel-gutter; - margin-bottom: $grid-gutter-width / 2; + margin-bottom: math.div($grid-gutter-width, 2); &:last-child { margin-bottom: 0; diff --git a/client/src/components/StreamField/scss/components/c-sf-block.scss b/client/src/components/StreamField/scss/components/c-sf-block.scss index 356e7eb545..993eba1f34 100644 --- a/client/src/components/StreamField/scss/components/c-sf-block.scss +++ b/client/src/components/StreamField/scss/components/c-sf-block.scss @@ -1,11 +1,11 @@ // TODO: Reduce nesting further by splitting out more components. -// +// --- // There's quite a lot of nesting in here which makes parsing some segments difficult. // Some of this is to deal with the fact that .c-sf-block can contain many .c-sf-block's and so is // legitimate. A lot of these would ideally be their own components (eg the actions) however there // is a lot of interdependency of the elements which makes this hard // without fairly intensive rethinking of the HTML. -// +// --- // However, the new classes adequately sanitise streamfield only CSS so am leaving this for // now to avoid blocking the release of the new Streamfield. -@jonnyscholes .c-sf-block { diff --git a/client/src/components/StreamField/scss/components/c-sf-container.scss b/client/src/components/StreamField/scss/components/c-sf-container.scss index dc2500ae0f..3e00a4672f 100644 --- a/client/src/components/StreamField/scss/components/c-sf-container.scss +++ b/client/src/components/StreamField/scss/components/c-sf-container.scss @@ -1,3 +1,5 @@ +@use "sass:math"; + .c-sf-container { position: relative; display: flex; @@ -26,7 +28,7 @@ .c-sf-add-button { width: $add-button-size; height: 0; - transform: translate(-100%, -$add-button-size / 2); + transform: translate(-100%, math.div(-$add-button-size, 2)); overflow: visible; } } @@ -36,7 +38,7 @@ // opportunity for this is probably as part of Wagtails general CSS overhaul. -@jonnyscholes .field { + .field { - padding-top: $grid-gutter-width / 2; + padding-top: math.div($grid-gutter-width, 2); } // TODO: #CSSoverhaul global label styles need to be removed. These styles come from global @@ -65,7 +67,7 @@ &__label { display: block; font-weight: bold; - margin-bottom: $grid-gutter-width / 4; + margin-bottom: $grid-gutter-width * 0.25; } &.required > label::after { diff --git a/wagtail/admin/static_src/wagtailadmin/scss/layouts/page-editor.scss b/wagtail/admin/static_src/wagtailadmin/scss/layouts/page-editor.scss index 9d15b42abc..121d69a6eb 100644 --- a/wagtail/admin/static_src/wagtailadmin/scss/layouts/page-editor.scss +++ b/wagtail/admin/static_src/wagtailadmin/scss/layouts/page-editor.scss @@ -1,3 +1,7 @@ +@use "sass:color"; +@use "sass:map"; +@use "sass:math"; + @import 'wagtailadmin/scss/helpers'; .page-editor { @@ -176,7 +180,7 @@ top: $object-title-height; margin-top: 0; margin-bottom: -1em; - padding: 1em ($grid-gutter-width / 2) 1em 3em; + padding: 1em math.div($grid-gutter-width, 2) 1em 3em; opacity: 1; .icon-help { @@ -220,9 +224,9 @@ &:before { @include font-smoothing; text-shadow: none; - font-family: wagtail; + font-family: $font-wagtail-icons; text-transform: none; - content: map-get($icons, 'arrow-down'); + content: map.get($icons, 'arrow-down'); text-align: center; display: block; position: absolute; @@ -320,7 +324,7 @@ // special panel for the publishing fields, requires a bit more pizzazz &.publishing { > .title-wrapper:before { - content: map-get($icons, 'date'); + content: map.get($icons, 'date'); font-size: 1.8rem; line-height: 1.4em; width: 1.4em; @@ -329,7 +333,7 @@ &.privacy { > .title-wrapper:before { - content: map-get($icons, 'view'); + content: map.get($icons, 'view'); } } @@ -393,7 +397,7 @@ } &:hover:before { - background-color: darken($color-salmon, 5%); + background-color: color.adjust($color-salmon, $lightness: -5%); } } } @@ -410,7 +414,7 @@ .title-wrapper { &:before { - content: map-get($icons, 'collapse-up'); + content: map.get($icons, 'collapse-up'); cursor: pointer; } } @@ -418,7 +422,7 @@ &.collapsed { .title-wrapper { &:before { - content: map-get($icons, 'collapse-down'); + content: map.get($icons, 'collapse-down'); } } } @@ -472,8 +476,8 @@ footer .preview { height: 3em; } - background-color: lighten($color-grey-2, 10%); - border-color: lighten($color-grey-2, 10%); + background-color: color.adjust($color-grey-2, $lightness: 10%); + border-color: color.adjust($color-grey-2, $lightness: 10%); &:hover { background-color: $color-grey-2; @@ -486,8 +490,8 @@ footer .preview { input[type=submit], button, .button { - background-color: lighten($color-grey-2, 10%); - border-color: lighten($color-grey-2, 10%); + background-color: color.adjust($color-grey-2, $lightness: 10%); + border-color: color.adjust($color-grey-2, $lightness: 10%); &:hover { background-color: $color-grey-2; @@ -497,7 +501,7 @@ footer .preview { ul, .dropdown-toggle { - background-color: lighten($color-grey-2, 10%); + background-color: color.adjust($color-grey-2, $lightness: 10%); } .dropdown-toggle:hover, diff --git a/wagtail/admin/static_src/wagtailadmin/scss/layouts/report.scss b/wagtail/admin/static_src/wagtailadmin/scss/layouts/report.scss index 5c2c8a27cc..8d1c2a6097 100644 --- a/wagtail/admin/static_src/wagtailadmin/scss/layouts/report.scss +++ b/wagtail/admin/static_src/wagtailadmin/scss/layouts/report.scss @@ -47,9 +47,6 @@ float: unset; display: block; width: unset; - } - - label { padding-top: 1.2em; } } diff --git a/wagtail/admin/static_src/wagtailadmin/scss/userbar.scss b/wagtail/admin/static_src/wagtailadmin/scss/userbar.scss index 6ad1229d8f..6310743146 100644 --- a/wagtail/admin/static_src/wagtailadmin/scss/userbar.scss +++ b/wagtail/admin/static_src/wagtailadmin/scss/userbar.scss @@ -1,3 +1,8 @@ +@use "sass:color"; +@use "sass:map"; +@use "sass:math"; +@use "sass:string"; + @import 'wagtailadmin/scss/helpers'; // ============================================================================= @@ -70,13 +75,13 @@ $positions: ( @each $icon, $content in $icons { .#{$namespace}-icon-#{$icon}:before { - content: quote(#{$content}); + content: string.quote(#{$content}); } } @each $icon, $content in $icons-after { .#{$namespace}-icon-#{$icon}:after { - content: quote(#{$content}); + content: string.quote(#{$content}); } } @@ -247,7 +252,7 @@ $positions: ( } & + & { - border-top: 1px solid darken($color-grey-1, 3%); + border-top: 1px solid color.adjust($color-grey-1, $lightness: -3%); } @@ -318,9 +323,9 @@ $positions: ( // ============================================================================= @each $pos, $attrs in $positions { - $vertical: map-get($attrs, vertical); - $horizontal: map-get($attrs, horizontal); - $arrow: map-get($attrs, arrow); + $vertical: map.get($attrs, vertical); + $horizontal: map.get($attrs, horizontal); + $arrow: map.get($attrs, arrow); .#{$namespace}-userbar--#{$pos} { #{$vertical}: $position; @@ -342,7 +347,7 @@ $positions: ( .#{$namespace}-userbar-items:after { #{$vertical}: 2px; - #{$horizontal}: $size-home-button / 2 - $width-arrow / 2; + #{$horizontal}: math.div($size-home-button, 2) - math.div($width-arrow, 2); border-#{$arrow}-color: $color-grey-1; @if $vertical == 'bottom' { diff --git a/wagtail/contrib/styleguide/static_src/wagtailstyleguide/scss/styleguide.scss b/wagtail/contrib/styleguide/static_src/wagtailstyleguide/scss/styleguide.scss index eac83af37d..8e18776307 100644 --- a/wagtail/contrib/styleguide/static_src/wagtailstyleguide/scss/styleguide.scss +++ b/wagtail/contrib/styleguide/static_src/wagtailstyleguide/scss/styleguide.scss @@ -59,10 +59,6 @@ section { color: $color-salmon-light; } - .color-red-text { - color: $color-red; - } - .color-green-text { color: $color-green; } diff --git a/wagtail/images/static_src/wagtailimages/scss/add-multiple.scss b/wagtail/images/static_src/wagtailimages/scss/add-multiple.scss index 210de6b7cf..c196d8f80d 100644 --- a/wagtail/images/static_src/wagtailimages/scss/add-multiple.scss +++ b/wagtail/images/static_src/wagtailimages/scss/add-multiple.scss @@ -1,3 +1,5 @@ +@use "sass:color"; + @import 'wagtailadmin/scss/helpers'; .replace-file-input { @@ -94,7 +96,7 @@ width: 1em; font-size: 10em; line-height: 1.4em; - color: lighten($color-grey-4, 4%); + color: color.adjust($color-grey-4, $lightness: 4%); } canvas,