From 76a4c47b1cf90369a77dd3f91b1de4e9005d281c Mon Sep 17 00:00:00 2001 From: Carlos Lopez Jr Date: Sun, 10 Jul 2016 14:26:57 +0000 Subject: [PATCH 1/4] fix(theming): update palette contrast types to current spec Previous values used out-of-spec colors for contrast. Low opacities values caused the design to not to meet AA standards of minimum 4.5 contrast ratio for default text. * Set hues with contrast type `light` to `strongLight`. * Set contrast type for `green` `500` to `dark`. Fixes #8992. Fixes #10164. --- src/core/services/theming/theme.palette.js | 24 +++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/core/services/theming/theme.palette.js b/src/core/services/theming/theme.palette.js index c6a3e5368a..7791500598 100644 --- a/src/core/services/theming/theme.palette.js +++ b/src/core/services/theming/theme.palette.js @@ -17,7 +17,7 @@ angular.module('material.core.theming.palette', []) 'A700': '#d50000', 'contrastDefaultColor': 'light', 'contrastDarkColors': '50 100 200 300 A100', - 'contrastStrongLightColors': '400 500 600 700 A200 A400 A700' + 'contrastStrongLightColors': '400 500 600 700 800 900 A200 A400 A700' }, 'pink': { '50': '#fce4ec', @@ -36,7 +36,7 @@ angular.module('material.core.theming.palette', []) 'A700': '#c51162', 'contrastDefaultColor': 'light', 'contrastDarkColors': '50 100 200 A100', - 'contrastStrongLightColors': '500 600 A200 A400 A700' + 'contrastStrongLightColors': '300 400 500 600 700 800 900 A200 A400 A700' }, 'purple': { '50': '#f3e5f5', @@ -55,7 +55,7 @@ angular.module('material.core.theming.palette', []) 'A700': '#aa00ff', 'contrastDefaultColor': 'light', 'contrastDarkColors': '50 100 200 A100', - 'contrastStrongLightColors': '300 400 A200 A400 A700' + 'contrastStrongLightColors': '300 400 500 600 700 800 900 A200 A400 A700' }, 'deep-purple': { '50': '#ede7f6', @@ -74,7 +74,7 @@ angular.module('material.core.theming.palette', []) 'A700': '#6200ea', 'contrastDefaultColor': 'light', 'contrastDarkColors': '50 100 200 A100', - 'contrastStrongLightColors': '300 400 A200' + 'contrastStrongLightColors': '300 400 500 600 700 800 900 A200 A400 A700' }, 'indigo': { '50': '#e8eaf6', @@ -93,7 +93,7 @@ angular.module('material.core.theming.palette', []) 'A700': '#304ffe', 'contrastDefaultColor': 'light', 'contrastDarkColors': '50 100 200 A100', - 'contrastStrongLightColors': '300 400 A200 A400' + 'contrastStrongLightColors': '300 400 500 600 700 800 900 A200 A400 A700' }, 'blue': { '50': '#e3f2fd', @@ -112,7 +112,7 @@ angular.module('material.core.theming.palette', []) 'A700': '#2962ff', 'contrastDefaultColor': 'light', 'contrastDarkColors': '50 100 200 300 400 A100', - 'contrastStrongLightColors': '500 600 700 A200 A400 A700' + 'contrastStrongLightColors': '500 600 700 800 900 A200 A400 A700' }, 'light-blue': { '50': '#e1f5fe', @@ -131,7 +131,7 @@ angular.module('material.core.theming.palette', []) 'A700': '#0091ea', 'contrastDefaultColor': 'dark', 'contrastLightColors': '600 700 800 900 A700', - 'contrastStrongLightColors': '600 700 800 A700' + 'contrastStrongLightColors': '600 700 800 900 A700' }, 'cyan': { '50': '#e0f7fa', @@ -169,7 +169,7 @@ angular.module('material.core.theming.palette', []) 'A700': '#00bfa5', 'contrastDefaultColor': 'dark', 'contrastLightColors': '500 600 700 800 900', - 'contrastStrongLightColors': '500 600 700' + 'contrastStrongLightColors': '500 600 700 800 900' }, 'green': { '50': '#e8f5e9', @@ -187,8 +187,8 @@ angular.module('material.core.theming.palette', []) 'A400': '#00e676', 'A700': '#00c853', 'contrastDefaultColor': 'dark', - 'contrastLightColors': '500 600 700 800 900', - 'contrastStrongLightColors': '500 600 700' + 'contrastLightColors': '600 700 800 900', + 'contrastStrongLightColors': '600 700 800 900' }, 'light-green': { '50': '#f1f8e9', @@ -317,7 +317,7 @@ angular.module('material.core.theming.palette', []) 'A700': '#5d4037', 'contrastDefaultColor': 'light', 'contrastDarkColors': '50 100 200 A100 A200', - 'contrastStrongLightColors': '300 400' + 'contrastStrongLightColors': '300 400 500 600 700 800 900 A400 A700' }, 'grey': { '50': '#fafafa', @@ -354,6 +354,6 @@ angular.module('material.core.theming.palette', []) 'A700': '#455a64', 'contrastDefaultColor': 'light', 'contrastDarkColors': '50 100 200 300 A100 A200', - 'contrastStrongLightColors': '400 500 700' + 'contrastStrongLightColors': '400 500 600 700 800 900 A400 A700' } }); From d9350eec5e5f5bff4b3f78708bf8799a27bdbcc8 Mon Sep 17 00:00:00 2001 From: Michael Prentice Date: Wed, 1 Jul 2020 01:34:37 -0400 Subject: [PATCH 2/4] fix(theming, toolbar, subheader, input): align color palettes and contrasts with AA standards - properly theme `md-icon`s in toolbars with `md-warn` - all colors and their contrasts meet 4.5 contrast ratio requirements - except a few edge cases which have comments to explain them - add `aria-labels` to demoInputsInToolbar - increase opacity of subheader text to meet AA contrast ratio requirements - increase opacity of input placeholders and labels to meet AA contrast ratio requirements - minor regexp adjustments for `md-colors` - fix colors/demoThemePicker and colors/demoBasicUsage to pass Lighthouse a11y audit - update button/demoBasicUsage to pass Lighthouse a11y audit - add missing alt tag in demoInCardActions and demoCardActionButtons - adjust docs app theme to define valid contrast colors for `docs-blue` - fix inaccurate JSDoc Fixes #8992. Fixes #10164. Closes #8993. BREAKING CHANGE: The contrast colors (the text or icon color, for example on a raised button) of many of our default palettes have been updated to meet the [AA level of the contrast guidelines](https://www.w3.org/TR/WCAG21/#contrast-minimum) for web accessibility. If you are using our default palettes directly, the accessibility of your application should be improved. However, we recommend that you evaluate this after updating to `1.2.0`. There may be edge cases in your app or custom styles that need to be updated to meet accessibility guidelines. If you find significant accessibility issues after updating, please report them to us. In `1.2.x`, we have a lot more control over our component theming in regards to hues and opacities. If your app is using a custom palette, whether based on a copy of default palette or not, we encourage you to evaluate that your contrast configuration meets the WebAIM guidelines. Please review our guide on [Defining Custom Palettes](https://material.angularjs.org/latest/Theming/03_configuring_a_theme#defining-custom-palettes) for details. --- docs/app/js/app.js | 10 ++- .../button/demoBasicUsage/index.html | 14 ++-- .../button/demoBasicUsage/script.js | 2 - .../button/demoBasicUsage/style.css | 2 +- .../card/demoCardActionButtons/index.html | 2 +- .../card/demoInCardActions/index.html | 2 +- src/components/colors/colors.js | 2 +- .../colors/demoBasicUsage/index.html | 4 +- .../colors/demoThemePicker/index.html | 4 +- src/components/input/input-theme.scss | 4 +- src/components/subheader/subheader-theme.scss | 2 +- .../toolbar/demoInputsInToolbar/index.html | 24 +++--- src/components/toolbar/toolbar-theme.scss | 5 ++ src/core/core.js | 2 +- src/core/services/theming/theme.palette.js | 84 ++++++++++++------- 15 files changed, 94 insertions(+), 69 deletions(-) diff --git a/docs/app/js/app.js b/docs/app/js/app.js index b633f09518..ef79c4c0a3 100644 --- a/docs/app/js/app.js +++ b/docs/app/js/app.js @@ -51,8 +51,8 @@ function(SERVICES, COMPONENTS, DEMOS, PAGES, '800': '#014AB6', '900': '#013583', 'contrastDefaultColor': 'light', - 'contrastDarkColors': '50 100 200 A100', - 'contrastStrongLightColors': '300 400 A200 A400' + 'contrastDarkColors': '50 100 200 300 400 A100 A200', + 'contrastStrongLightColors': '500 600 700 800 900 A400 A700' })); $mdThemingProvider.definePalette('docs-red', $mdThemingProvider.extendPalette('red', { 'A100': '#DE3641' @@ -76,8 +76,10 @@ function(SERVICES, COMPONENTS, DEMOS, PAGES, .defaultIconSet('img/icons/sets/core-icons.svg', 24); $mdThemingProvider.theme('default') - .primaryPalette('docs-blue') - .accentPalette('docs-red'); + .primaryPalette('docs-blue') + .accentPalette('docs-red', { + 'default': 'A700' + }); $mdThemingProvider.enableBrowserColor(); diff --git a/src/components/button/demoBasicUsage/index.html b/src/components/button/demoBasicUsage/index.html index 05a305d6c4..30a3ba196e 100644 --- a/src/components/button/demoBasicUsage/index.html +++ b/src/components/button/demoBasicUsage/index.html @@ -2,10 +2,10 @@
- {{title1}} + Button Primary (md-noink) Disabled - {{title4}} + Warn
Flat
@@ -14,7 +14,7 @@ Button Primary Disabled - Warn + Accent
Raised
@@ -58,10 +58,10 @@
- Primary Hue 1 - Warn Hue 2 - Accent - Accent Hue 1 + Primary Hue 2 + Warn Hue 1 + Accent Hue 2 + Accent Hue 3
Themed
diff --git a/src/components/button/demoBasicUsage/script.js b/src/components/button/demoBasicUsage/script.js index 4201838b25..7153f0d1e3 100644 --- a/src/components/button/demoBasicUsage/script.js +++ b/src/components/button/demoBasicUsage/script.js @@ -1,7 +1,5 @@ angular.module('buttonsDemoBasic', ['ngMaterial']) .controller('AppCtrl', function($scope) { - $scope.title1 = 'Button'; - $scope.title4 = 'Warn'; $scope.isDisabled = true; $scope.googleUrl = 'http://google.com'; }); diff --git a/src/components/button/demoBasicUsage/style.css b/src/components/button/demoBasicUsage/style.css index 65e021f6d5..ac3c84a632 100644 --- a/src/components/button/demoBasicUsage/style.css +++ b/src/components/button/demoBasicUsage/style.css @@ -13,5 +13,5 @@ section .md-button { bottom: 5px; left: 7px; font-size: 14px; - opacity: 0.54; + color: rgba(0, 0, 0, 0.54); } diff --git a/src/components/card/demoCardActionButtons/index.html b/src/components/card/demoCardActionButtons/index.html index 1dbe3a7e37..b1b7caaa02 100644 --- a/src/components/card/demoCardActionButtons/index.html +++ b/src/components/card/demoCardActionButtons/index.html @@ -90,7 +90,7 @@ - + Washed Out AngularJS diff --git a/src/components/card/demoInCardActions/index.html b/src/components/card/demoInCardActions/index.html index 90c87a7bc5..dbfb927233 100644 --- a/src/components/card/demoInCardActions/index.html +++ b/src/components/card/demoInCardActions/index.html @@ -30,7 +30,7 @@ - + Washed Out User diff --git a/src/components/colors/colors.js b/src/components/colors/colors.js index 5007e812b6..c285639ccc 100644 --- a/src/components/colors/colors.js +++ b/src/components/colors/colors.js @@ -5,7 +5,7 @@ * Use a RegExp to check if the `md-colors=""` is static string * or one that should be observed and dynamically interpolated. */ - var STATIC_COLOR_EXPRESSION = /^{((\s|,)*?["'a-zA-Z-]+?\s*?:\s*?('|")[a-zA-Z0-9-.]*('|"))+\s*}$/; + var STATIC_COLOR_EXPRESSION = /^{((\s|,)*?["'a-zA-Z-]+?\s*?:\s*?(['"])[a-zA-Z0-9-.]*(['"]))+\s*}$/; var colorPalettes = null; /** diff --git a/src/components/colors/demoBasicUsage/index.html b/src/components/colors/demoBasicUsage/index.html index 20011e0e3a..2dd2a83346 100644 --- a/src/components/colors/demoBasicUsage/index.html +++ b/src/components/colors/demoBasicUsage/index.html @@ -1,6 +1,6 @@

- Custom component implementations using Material elements often want to easily apply theme colors + Custom component implementations using Material elements often want to apply theme colors to their custom components. Consider the custom <user-card> component below where the md-colors attribute is used to color the background and text colors using either the current or specified theme palette colors. @@ -18,7 +18,7 @@

<user-card> coloring using the 'fores

Note: The md-colors directive allows pre-defined theme colors to be applied as CSS style properties. md-colors uses the palettes defined in the - + Material Design Colors and the themes defined using $mdThemingProvider. This directive is an extension of the $mdTheming features.

diff --git a/src/components/colors/demoThemePicker/index.html b/src/components/colors/demoThemePicker/index.html index a61b006fcb..aec84e63cd 100644 --- a/src/components/colors/demoThemePicker/index.html +++ b/src/components/colors/demoThemePicker/index.html @@ -1,12 +1,12 @@

- Select two of the Material Palettes + Select two of the Material Palettes below:

{{color}} diff --git a/src/components/input/input-theme.scss b/src/components/input/input-theme.scss index 14e47ba2d2..5dd1de0151 100644 --- a/src/components/input/input-theme.scss +++ b/src/components/input/input-theme.scss @@ -1,6 +1,6 @@ md-input-container.md-THEME_NAME-theme { .md-input { - @include input-placeholder-color('\'{{background-default-contrast-hint}}\''); + @include input-placeholder-color('\'{{background-default-contrast-secondary}}\''); color: '{{background-default-contrast}}'; border-color: '{{background-default-contrast-divider}}'; } @@ -11,7 +11,7 @@ md-input-container.md-THEME_NAME-theme { label, .md-placeholder { - color: '{{background-default-contrast-hint}}'; + color: '{{background-default-contrast-secondary}}'; } label.md-required:after { diff --git a/src/components/subheader/subheader-theme.scss b/src/components/subheader/subheader-theme.scss index 60fd59123c..a9a2991970 100644 --- a/src/components/subheader/subheader-theme.scss +++ b/src/components/subheader/subheader-theme.scss @@ -1,5 +1,5 @@ .md-subheader.md-THEME_NAME-theme { - color: '{{ foreground-2-0.23 }}'; + color: '{{ foreground-2-0.54 }}'; background-color: '{{background-default}}'; &.md-primary { diff --git a/src/components/toolbar/demoInputsInToolbar/index.html b/src/components/toolbar/demoInputsInToolbar/index.html index e77c3cbf89..1685f8540c 100644 --- a/src/components/toolbar/demoInputsInToolbar/index.html +++ b/src/components/toolbar/demoInputsInToolbar/index.html @@ -9,15 +9,15 @@ - + - + - + @@ -31,15 +31,15 @@ - + - + - + @@ -53,27 +53,27 @@ - + - + - + - + - + - +
diff --git a/src/components/toolbar/toolbar-theme.scss b/src/components/toolbar/toolbar-theme.scss index 56185eae49..a8b3b4f348 100644 --- a/src/components/toolbar/toolbar-theme.scss +++ b/src/components/toolbar/toolbar-theme.scss @@ -107,6 +107,11 @@ md-toolbar.md-THEME_NAME-theme:not(.md-menu-toolbar) { background-color: '{{warn-color}}'; color: '{{warn-contrast}}'; + md-icon { + color: '{{accent-contrast}}'; + fill: '{{accent-contrast}}'; + } + md-input-container[md-no-float] { .md-input { @include input-placeholder-color('\'{{warn-default-contrast-hint}}\''); diff --git a/src/core/core.js b/src/core/core.js index 7e36957493..4246fd7745 100644 --- a/src/core/core.js +++ b/src/core/core.js @@ -59,7 +59,7 @@ function rAFDecorator($delegate) { * our callback will only be fired once per frame, with the last resize * event that happened before that frame. * - * @param {function} callback function to debounce + * @param {function} cb function to debounce */ $delegate.throttle = function(cb) { var queuedArgs, alreadyQueued, queueCb, context; diff --git a/src/core/services/theming/theme.palette.js b/src/core/services/theming/theme.palette.js index 7791500598..21b381c188 100644 --- a/src/core/services/theming/theme.palette.js +++ b/src/core/services/theming/theme.palette.js @@ -16,8 +16,8 @@ angular.module('material.core.theming.palette', []) 'A400': '#ff1744', 'A700': '#d50000', 'contrastDefaultColor': 'light', - 'contrastDarkColors': '50 100 200 300 A100', - 'contrastStrongLightColors': '400 500 600 700 800 900 A200 A400 A700' + 'contrastDarkColors': '50 100 200 300 400 500 600 A100 A200 A400', + 'contrastStrongLightColors': '700 800 900 A700' }, 'pink': { '50': '#fce4ec', @@ -35,8 +35,10 @@ angular.module('material.core.theming.palette', []) 'A400': '#f50057', 'A700': '#c51162', 'contrastDefaultColor': 'light', - 'contrastDarkColors': '50 100 200 A100', - 'contrastStrongLightColors': '300 400 500 600 700 800 900 A200 A400 A700' + 'contrastDarkColors': '50 100 200 300 400 A100 A200 A400', + // White on 500 does not meet the minimum 4.5 contrast ratio (at 4.34), + // but it's worse with a dark foreground (3.61). + 'contrastStrongLightColors': '500 600 700 800 900 A700' }, 'purple': { '50': '#f3e5f5', @@ -54,8 +56,8 @@ angular.module('material.core.theming.palette', []) 'A400': '#d500f9', 'A700': '#aa00ff', 'contrastDefaultColor': 'light', - 'contrastDarkColors': '50 100 200 A100', - 'contrastStrongLightColors': '300 400 500 600 700 800 900 A200 A400 A700' + 'contrastDarkColors': '50 100 200 300 A100 A200 A400', + 'contrastStrongLightColors': '400 500 600 700 800 900 A700' }, 'deep-purple': { '50': '#ede7f6', @@ -73,8 +75,8 @@ angular.module('material.core.theming.palette', []) 'A400': '#651fff', 'A700': '#6200ea', 'contrastDefaultColor': 'light', - 'contrastDarkColors': '50 100 200 A100', - 'contrastStrongLightColors': '300 400 500 600 700 800 900 A200 A400 A700' + 'contrastDarkColors': '50 100 200 300 A100', + 'contrastStrongLightColors': '400 500 600 700 800 900 A200 A400 A700' }, 'indigo': { '50': '#e8eaf6', @@ -92,8 +94,8 @@ angular.module('material.core.theming.palette', []) 'A400': '#3d5afe', 'A700': '#304ffe', 'contrastDefaultColor': 'light', - 'contrastDarkColors': '50 100 200 A100', - 'contrastStrongLightColors': '300 400 500 600 700 800 900 A200 A400 A700' + 'contrastDarkColors': '50 100 200 300 A100 A200', + 'contrastStrongLightColors': '400 500 600 700 800 900 A400 A700' }, 'blue': { '50': '#e3f2fd', @@ -111,8 +113,10 @@ angular.module('material.core.theming.palette', []) 'A400': '#2979ff', 'A700': '#2962ff', 'contrastDefaultColor': 'light', - 'contrastDarkColors': '50 100 200 300 400 A100', - 'contrastStrongLightColors': '500 600 700 800 900 A200 A400 A700' + // White on A400 does not meet the minimum 4.5 contrast ratio (at 3.98), + // but it's worse with a dark foreground (3.94). + 'contrastDarkColors': '50 100 200 300 400 500 600 A100 A200', + 'contrastStrongLightColors': '700 800 900 A400 A700' }, 'light-blue': { '50': '#e1f5fe', @@ -130,8 +134,10 @@ angular.module('material.core.theming.palette', []) 'A400': '#00b0ff', 'A700': '#0091ea', 'contrastDefaultColor': 'dark', - 'contrastLightColors': '600 700 800 900 A700', - 'contrastStrongLightColors': '600 700 800 900 A700' + // Dark on 700 does not meet the minimum 4.5 contrast ratio (at 4.07), + // but it's worse with a white foreground (3.85). + 'contrastLightColors': '800 900 A700', + 'contrastStrongLightColors': '800 900 A700' }, 'cyan': { '50': '#e0f7fa', @@ -149,8 +155,10 @@ angular.module('material.core.theming.palette', []) 'A400': '#00e5ff', 'A700': '#00b8d4', 'contrastDefaultColor': 'dark', - 'contrastLightColors': '700 800 900', - 'contrastStrongLightColors': '700 800 900' + // Dark on 700 does not meet the minimum 4.5 contrast ratio (at 4.47), + // but it's worse with a white foreground (3.5). + 'contrastLightColors': '800 900', + 'contrastStrongLightColors': '800 900' }, 'teal': { '50': '#e0f2f1', @@ -168,8 +176,12 @@ angular.module('material.core.theming.palette', []) 'A400': '#1de9b6', 'A700': '#00bfa5', 'contrastDefaultColor': 'dark', - 'contrastLightColors': '500 600 700 800 900', - 'contrastStrongLightColors': '500 600 700 800 900' + // Dark on 500 does not meet the minimum 4.5 contrast ratio (at 4.27), + // but it's worse with a white foreground (3.67). + // White on 600 does not meet the minimum 4.5 contrast ratio (at 4.31), + // but it's worse with a dark foreground (3.64). + 'contrastLightColors': '600 700 800 900', + 'contrastStrongLightColors': '600 700 800 900' }, 'green': { '50': '#e8f5e9', @@ -187,8 +199,10 @@ angular.module('material.core.theming.palette', []) 'A400': '#00e676', 'A700': '#00c853', 'contrastDefaultColor': 'dark', - 'contrastLightColors': '600 700 800 900', - 'contrastStrongLightColors': '600 700 800 900' + // White on 700 does not meet the minimum 4.5 contrast ratio (at 4.11), + // but it's worse with a dark foreground (3.81). + 'contrastLightColors': '700 800 900', + 'contrastStrongLightColors': '700 800 900' }, 'light-green': { '50': '#f1f8e9', @@ -206,8 +220,8 @@ angular.module('material.core.theming.palette', []) 'A400': '#76ff03', 'A700': '#64dd17', 'contrastDefaultColor': 'dark', - 'contrastLightColors': '700 800 900', - 'contrastStrongLightColors': '700 800 900' + 'contrastLightColors': '800 900', + 'contrastStrongLightColors': '800 900' }, 'lime': { '50': '#f9fbe7', @@ -278,8 +292,8 @@ angular.module('material.core.theming.palette', []) 'A400': '#ff9100', 'A700': '#ff6d00', 'contrastDefaultColor': 'dark', - 'contrastLightColors': '800 900', - 'contrastStrongLightColors': '800 900' + 'contrastLightColors': '900', + 'contrastStrongLightColors': '900' }, 'deep-orange': { '50': '#fbe9e7', @@ -296,9 +310,12 @@ angular.module('material.core.theming.palette', []) 'A200': '#ff6e40', 'A400': '#ff3d00', 'A700': '#dd2c00', - 'contrastDefaultColor': 'light', - 'contrastDarkColors': '50 100 200 300 400 A100 A200', - 'contrastStrongLightColors': '500 600 700 800 900 A400 A700' + 'contrastDefaultColor': 'dark', + // Dark on 700 does not meet the minimum 4.5 contrast ratio (at 4.01), + // but it's worse with a white foreground (3.91). + // White on 800 does not meet the minimum 4.5 contrast ratio (at 4.43), + // but it's worse with a dark foreground (3.54). + 'contrastLightColors': '800 900 A400 A700', }, 'brown': { '50': '#efebe9', @@ -316,8 +333,8 @@ angular.module('material.core.theming.palette', []) 'A400': '#8d6e63', 'A700': '#5d4037', 'contrastDefaultColor': 'light', - 'contrastDarkColors': '50 100 200 A100 A200', - 'contrastStrongLightColors': '300 400 500 600 700 800 900 A400 A700' + 'contrastDarkColors': '50 100 200 300 A100 A200', + 'contrastStrongLightColors': '400 500 600 700 800 900 A400 A700' }, 'grey': { '50': '#fafafa', @@ -335,7 +352,8 @@ angular.module('material.core.theming.palette', []) 'A400': '#303030', 'A700': '#616161', 'contrastDefaultColor': 'dark', - 'contrastLightColors': '600 700 800 900 A200 A400 A700' + 'contrastLightColors': '600 700 800 900 A200 A400 A700', + 'contrastStrongLightColors': '600' }, 'blue-grey': { '50': '#eceff1', @@ -353,7 +371,9 @@ angular.module('material.core.theming.palette', []) 'A400': '#78909c', 'A700': '#455a64', 'contrastDefaultColor': 'light', - 'contrastDarkColors': '50 100 200 300 A100 A200', - 'contrastStrongLightColors': '400 500 600 700 800 900 A400 A700' + 'contrastDarkColors': '50 100 200 300 400 A100 A200 A400', + // White on 500 does not meet the minimum 4.5 contrast ratio (at 4.37), + // but it's worse with a dark foreground. + 'contrastStrongLightColors': '500 600 700 800 900 A700' } }); From 203847aecfb63e034d2b3d8d5dea534617e62799 Mon Sep 17 00:00:00 2001 From: Michael Prentice Date: Thu, 2 Jul 2020 01:23:57 -0400 Subject: [PATCH 3/4] fix(theming): dark contrast used incorrectly when only contrastStrongLightColors defined - if `contrastStrongLightColors` is defined and `contrastLightColors` is not, `getContrastType()` was incorrectly picking `dark` instead of `strongLight` - remove all of the duplicate `contrastLightColors` entries that had to remain before, due to this bug - improve JSDoc - checkbox's checkmark should always match the background color and never depend on the contrast of the accent color - remove duplicate theme style generation for checkbox and button --- src/components/button/button-theme.scss | 15 ------------- .../button/demoBasicUsage/style.css | 1 - src/components/checkbox/checkbox-theme.scss | 15 +------------ src/core/services/theming/theme.palette.js | 11 ++-------- src/core/services/theming/theming.js | 21 ++++++++++++++++++- 5 files changed, 23 insertions(+), 40 deletions(-) diff --git a/src/components/button/button-theme.scss b/src/components/button/button-theme.scss index 322c1fddb9..966401c8c0 100644 --- a/src/components/button/button-theme.scss +++ b/src/components/button/button-theme.scss @@ -52,21 +52,6 @@ } } } - &.md-fab { - background-color: '{{accent-color}}'; - color: '{{accent-contrast}}'; - &:not([disabled]) { - .md-icon { - color: '{{accent-contrast}}'; - } - &:hover { - background-color: '{{accent-A700}}'; - } - &.md-focused { - background-color: '{{accent-A700}}'; - } - } - } &.md-raised { color: '{{background-900}}'; diff --git a/src/components/button/demoBasicUsage/style.css b/src/components/button/demoBasicUsage/style.css index ac3c84a632..236e0800be 100644 --- a/src/components/button/demoBasicUsage/style.css +++ b/src/components/button/demoBasicUsage/style.css @@ -13,5 +13,4 @@ section .md-button { bottom: 5px; left: 7px; font-size: 14px; - color: rgba(0, 0, 0, 0.54); } diff --git a/src/components/checkbox/checkbox-theme.scss b/src/components/checkbox/checkbox-theme.scss index 414782a22d..9c83daffd6 100644 --- a/src/components/checkbox/checkbox-theme.scss +++ b/src/components/checkbox/checkbox-theme.scss @@ -28,7 +28,7 @@ md-checkbox.md-THEME_NAME-theme { } &.md-checked .md-icon:after { - border-color: '{{accent-contrast-0.87}}'; + border-color: '{{background-default}}'; } &:not([disabled]) { @@ -60,10 +60,6 @@ md-checkbox.md-THEME_NAME-theme { &.md-checked.md-focused:not([disabled]) .md-container:before { background-color: '{{warn-color-0.26}}'; } - - &.md-checked .md-icon:after { - border-color: '{{background-200}}'; - } } } @@ -76,17 +72,8 @@ md-checkbox.md-THEME_NAME-theme { background-color: '{{foreground-3}}'; } - &.md-checked .md-icon:after { - border-color: '{{background-200}}'; - } - - .md-icon:after { - border-color: '{{foreground-3}}'; - } - .md-label { color: '{{foreground-3}}'; } } - } diff --git a/src/core/services/theming/theme.palette.js b/src/core/services/theming/theme.palette.js index 21b381c188..c859a323fd 100644 --- a/src/core/services/theming/theme.palette.js +++ b/src/core/services/theming/theme.palette.js @@ -136,7 +136,6 @@ angular.module('material.core.theming.palette', []) 'contrastDefaultColor': 'dark', // Dark on 700 does not meet the minimum 4.5 contrast ratio (at 4.07), // but it's worse with a white foreground (3.85). - 'contrastLightColors': '800 900 A700', 'contrastStrongLightColors': '800 900 A700' }, 'cyan': { @@ -157,7 +156,6 @@ angular.module('material.core.theming.palette', []) 'contrastDefaultColor': 'dark', // Dark on 700 does not meet the minimum 4.5 contrast ratio (at 4.47), // but it's worse with a white foreground (3.5). - 'contrastLightColors': '800 900', 'contrastStrongLightColors': '800 900' }, 'teal': { @@ -180,7 +178,6 @@ angular.module('material.core.theming.palette', []) // but it's worse with a white foreground (3.67). // White on 600 does not meet the minimum 4.5 contrast ratio (at 4.31), // but it's worse with a dark foreground (3.64). - 'contrastLightColors': '600 700 800 900', 'contrastStrongLightColors': '600 700 800 900' }, 'green': { @@ -201,7 +198,6 @@ angular.module('material.core.theming.palette', []) 'contrastDefaultColor': 'dark', // White on 700 does not meet the minimum 4.5 contrast ratio (at 4.11), // but it's worse with a dark foreground (3.81). - 'contrastLightColors': '700 800 900', 'contrastStrongLightColors': '700 800 900' }, 'light-green': { @@ -220,7 +216,6 @@ angular.module('material.core.theming.palette', []) 'A400': '#76ff03', 'A700': '#64dd17', 'contrastDefaultColor': 'dark', - 'contrastLightColors': '800 900', 'contrastStrongLightColors': '800 900' }, 'lime': { @@ -239,7 +234,6 @@ angular.module('material.core.theming.palette', []) 'A400': '#c6ff00', 'A700': '#aeea00', 'contrastDefaultColor': 'dark', - 'contrastLightColors': '900', 'contrastStrongLightColors': '900' }, 'yellow': { @@ -292,7 +286,6 @@ angular.module('material.core.theming.palette', []) 'A400': '#ff9100', 'A700': '#ff6d00', 'contrastDefaultColor': 'dark', - 'contrastLightColors': '900', 'contrastStrongLightColors': '900' }, 'deep-orange': { @@ -315,7 +308,7 @@ angular.module('material.core.theming.palette', []) // but it's worse with a white foreground (3.91). // White on 800 does not meet the minimum 4.5 contrast ratio (at 4.43), // but it's worse with a dark foreground (3.54). - 'contrastLightColors': '800 900 A400 A700', + 'contrastStrongLightColors': '800 900 A400 A700', }, 'brown': { '50': '#efebe9', @@ -352,7 +345,7 @@ angular.module('material.core.theming.palette', []) 'A400': '#303030', 'A700': '#616161', 'contrastDefaultColor': 'dark', - 'contrastLightColors': '600 700 800 900 A200 A400 A700', + 'contrastLightColors': '700 800 900 A200 A400 A700', 'contrastStrongLightColors': '600' }, 'blue-grey': { diff --git a/src/core/services/theming/theming.js b/src/core/services/theming/theming.js index 789ca0f9bf..0ab9bc14b0 100644 --- a/src/core/services/theming/theming.js +++ b/src/core/services/theming/theming.js @@ -1217,8 +1217,13 @@ function generateAllThemes($injector, $mdTheming) { delete palette.contrastStrongLightColors; delete palette.contrastDarkColors; + /** + * @param {string} hueName + * @return {'dark'|'light'|'strongLight'} + */ function getContrastType(hueName) { - if (defaultContrast === 'light' ? darkColors.indexOf(hueName) !== -1 : lightColors.indexOf(hueName) === -1) { + if (defaultContrast === 'light' ? darkColors.indexOf(hueName) !== -1 : + (lightColors.indexOf(hueName) === -1 && strongLightColors.indexOf(hueName) === -1)) { return 'dark'; } if (strongLightColors.indexOf(hueName) !== -1) { @@ -1226,6 +1231,11 @@ function generateAllThemes($injector, $mdTheming) { } return 'light'; } + + /** + * @param {'dark'|'light'|'strongLight'} contrastType + * @return {[number, number, number]} [red, green, blue] array + */ function getContrastColor(contrastType) { switch (contrastType) { default: @@ -1237,6 +1247,11 @@ function generateAllThemes($injector, $mdTheming) { return DARK_CONTRAST_COLOR; } } + + /** + * @param {'dark'|'light'|'strongLight'} contrastType + * @return {{secondary: number, divider: number, hint: number, icon: number, disabled: number}} + */ function getOpacityValues(contrastType) { switch (contrastType) { default: @@ -1313,6 +1328,10 @@ function checkValidPalette(theme, colorType) { } } +/** + * @param {string} clr rbg or rgba color + * @return {number[]|undefined} [red, green, blue] array if it can be computed + */ function colorToRgbaArray(clr) { if (angular.isArray(clr) && clr.length === 3) return clr; if (/^rgb/.test(clr)) { From fb27d37d1f7374fe4238c8b1faa9154ab7d2ec41 Mon Sep 17 00:00:00 2001 From: Michael Prentice Date: Thu, 2 Jul 2020 01:27:06 -0400 Subject: [PATCH 4/4] docs(theming): update Defining Custom Palettes guide w/ new contrast settings - change docs app's warn theme 500 value to 700 value to make flat warn buttons pass contrast checks - revert docs-red palette defaulting to `A700` since that breaks hover and focus styles - remove the override of the `.demo-toolbar` color since it is no longer needed after the toolbar contrast fixes --- docs/app/css/style.css | 1 - docs/app/js/app.js | 10 ++- .../content/Theming/03_configuring_a_theme.md | 66 +++++++++++++++---- 3 files changed, 60 insertions(+), 17 deletions(-) diff --git a/docs/app/css/style.css b/docs/app/css/style.css index f1709e4313..29f868110c 100644 --- a/docs/app/css/style.css +++ b/docs/app/css/style.css @@ -554,7 +554,6 @@ md-tabs.demo-source-tabs .active md-tab-label { md-toolbar.demo-toolbar { border-radius: 3px 3px 0 0; box-shadow: 0 1px rgba(255, 255, 255, 0.1); - color: white; } md-toolbar.demo-toolbar md-tab-label { color: #99E4EE; diff --git a/docs/app/js/app.js b/docs/app/js/app.js index ef79c4c0a3..971fb09467 100644 --- a/docs/app/js/app.js +++ b/docs/app/js/app.js @@ -54,10 +54,15 @@ function(SERVICES, COMPONENTS, DEMOS, PAGES, 'contrastDarkColors': '50 100 200 300 400 A100 A200', 'contrastStrongLightColors': '500 600 700 800 900 A400 A700' })); + $mdThemingProvider.definePalette('docs-red', $mdThemingProvider.extendPalette('red', { 'A100': '#DE3641' })); + $mdThemingProvider.definePalette('docs-warn', $mdThemingProvider.extendPalette('deep-orange', { + '500': '#d32f2f' // Override 500 with 700 hue for improved contrast on flat buttons + })); + $mdThemingProvider.theme('docs-dark', 'default') .primaryPalette('yellow') .dark(); @@ -77,9 +82,8 @@ function(SERVICES, COMPONENTS, DEMOS, PAGES, $mdThemingProvider.theme('default') .primaryPalette('docs-blue') - .accentPalette('docs-red', { - 'default': 'A700' - }); + .accentPalette('docs-red') + .warnPalette('docs-warn'); $mdThemingProvider.enableBrowserColor(); diff --git a/docs/content/Theming/03_configuring_a_theme.md b/docs/content/Theming/03_configuring_a_theme.md index 1cd46cdf20..9618514843 100644 --- a/docs/content/Theming/03_configuring_a_theme.md +++ b/docs/content/Theming/03_configuring_a_theme.md @@ -4,7 +4,7 @@ ## Configuring a theme -By default your AngularJS Material application will use the default theme, a theme +By default, your AngularJS Material application will use the default theme, a theme that is pre-configured with the following palettes for intention groups: - *primary* - indigo @@ -72,16 +72,24 @@ angular.module('myApp', ['ngMaterial']) ### Defining Custom Palettes -As mentioned before, AngularJS Material ships with the Material Design -Spec's color palettes built in. In the event that you need to define a custom color palette, you can use `$mdThemingProvider` to define it, thereby making -it available to your theme for use in its intention groups. Note that you must -specify all hues in the definition map. +As mentioned before, AngularJS Material ships with the Material Design Spec's color palettes built +in. In the event that you need to define a custom color palette, you can use `$mdThemingProvider` +to define it. This makes the palette available to your theme for use in its intention groups. +Note that you must specify all hues in the definition map. If you only want to override a few hues, +please extend a palette (above). + +For a dark colored, custom palette, you should specify the default contrast color as `light`. +For lighter hues in the palette, you may need to add them to the list of `contrastDarkColors` to +meet contrast guidelines. Similarly, you may need to add darker hues to `contrastStrongLightColors`, +which has been updated to the latest Material Design guidelines for +[Color Usability](https://material.io/archive/guidelines/style/color.html#color-usability). +The update to the guidelines changed primary text on dark backgrounds from 87% to 100% opacity. angular.module('myApp', ['ngMaterial']) .config(function($mdThemingProvider) { - $mdThemingProvider.definePalette('amazingPaletteName', { + $mdThemingProvider.definePalette('amazingDarkPaletteName', { '50': 'ffebee', '100': 'ffcdd2', '200': 'ef9a9a', @@ -96,17 +104,49 @@ angular.module('myApp', ['ngMaterial']) 'A200': 'ff5252', 'A400': 'ff1744', 'A700': 'd50000', - 'contrastDefaultColor': 'light', // whether, by default, text (contrast) - // on this palette should be dark or light - - 'contrastDarkColors': ['50', '100', //hues which contrast should be 'dark' by default - '200', '300', '400', 'A100'], - 'contrastLightColors': undefined // could also specify this if default was 'dark' + // By default, text (contrast) on this palette should be white with 87% opacity. + 'contrastDefaultColor': 'light', + // By default, for these lighter hues, text (contrast) should be 'dark'. + 'contrastDarkColors': '50 100 200 300 400 500 600 A100 A200 A400', + // By default, for these darker hues, text (contrast) should be white with 100% opacity. + 'contrastStrongLightColors': '700 800 900 A700' }); $mdThemingProvider.theme('default') - .primaryPalette('amazingPaletteName') + .primaryPalette('amazingDarkPaletteName') +}); + + +For a light colored, custom palette, you should specify the default contrast color as `dark`. +Then `contrastStrongLightColors` can be used if any hues are too dark for dark text. + + +angular.module('myApp', ['ngMaterial']) +.config(function($mdThemingProvider) { + $mdThemingProvider.definePalette('amazingLightPaletteName', { + '50': '#f1f8e9', + '100': '#dcedc8', + '200': '#c5e1a5', + '300': '#aed581', + '400': '#9ccc65', + '500': '#8bc34a', + '600': '#7cb342', + '700': '#689f38', + '800': '#558b2f', + '900': '#33691e', + 'A100': '#ccff90', + 'A200': '#b2ff59', + 'A400': '#76ff03', + 'A700': '#64dd17', + // By default, text (contrast) on this palette should be dark with 87% opacity. + 'contrastDefaultColor': 'dark', + // By default, for these darker hues, text (contrast) should be white with 100% opacity. + 'contrastStrongLightColors': '800 900' + }); + + $mdThemingProvider.theme('default') + .accentPalette('amazingLightPaletteName') });