Skip to content

Commit

Permalink
ID-426 Rework how brand colours are calculated.
Browse files Browse the repository at this point in the history
Implemented WCAG functions for contrast. Moved the definitions of key colours up into pairs of colours that are calculated to pass AA contrast, and updated links and headings, both on the page and over the default box styles, use an alternative colour if the brand colour doesn't work.

Brand testcard now passes contrast for all the new brand colours.

Changed @text-color from #383838 to #202020 for a contrast boost.

Added vitest for LESS unit tests.
  • Loading branch information
halfninja committed Sep 25, 2024
1 parent 303a9a2 commit 9760f97
Show file tree
Hide file tree
Showing 17 changed files with 11,491 additions and 9,751 deletions.
11 changes: 11 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# https://editorconfig.org

root = true

[*]
end_of_line = lf
insert_final_newline = true

[*.{js,ts,tsx,jsx,mjs}]
indent_style = space
indent_size = 2
4 changes: 3 additions & 1 deletion babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ module.exports = function(api) {
api.cache.using(() => process.env.NODE_ENV);

return {
"presets": ["@babel/preset-env"],
"presets": [
"@babel/preset-env"
],
"plugins": ["lodash"]
};
};
12 changes: 6 additions & 6 deletions docs/assets/css/subsite.less
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@
}
}

#boxstyle > .filled(~'.box1', screen(@id7-brand-purple, darken(white, 40%)));
#boxstyle > .filled(~'.box2', screen(@id7-brand-purple, darken(white, 10%)));
#boxstyle > .filled(~'.box3', #e6e6e6);
#boxstyle > .image(~'.box4', ~'url(../site/site1/banner-image.jpg) top right no-repeat', white);
#boxstyle > .image(~'.box5', ~'url(../site/site3/banner-image.jpg) top right no-repeat', white);
#boxstyle.filled(~'.box1', screen(@id7-brand-purple, darken(white, 40%)), @text-color, @text-color);
#boxstyle.filled(~'.box2', screen(@id7-brand-purple, darken(white, 10%)), @text-color, @id7-brand-purple);
#boxstyle.filled(~'.box3', #e6e6e6, @text-color, @id7-brand-purple);
#boxstyle.image(~'.box4', ~'url(../site/site1/banner-image.jpg) top right no-repeat', white);
#boxstyle.image(~'.box5', ~'url(../site/site3/banner-image.jpg) top right no-repeat', white);

.feature-box {
.heading {
Expand Down Expand Up @@ -269,4 +269,4 @@ blockquote.branded {
line-height: @line-height-small;
padding: 3px 110px 3px 0;
}
}
}
2 changes: 1 addition & 1 deletion less/bootstrap-fixes.less
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ button.close {
color: @text-muted;
}

/* Contrast fixes ID-347 */
// Contrast fixes ID-347

.help-block {
color: darken(@text-muted, 10%);
Expand Down
2 changes: 2 additions & 0 deletions less/mixins.less
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@
@import 'mixins/bootstrap-fixes-labels.less';
@import 'mixins/bootstrap-fixes-alerts.less';
@import 'mixins/utility-bar-bg.less';
@import 'mixins/wcag.less';
@import 'mixins/debug.less';
25 changes: 14 additions & 11 deletions less/mixins/box-styles.less
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@
}

#boxstyle {
.box1-bg(@colour) {
@result: screen(@colour, lighten(black, 85%));
}

.image(@class, @bg-image, @text-colour: @text-color) {
.apply() {
&@{class} {
Expand Down Expand Up @@ -127,7 +131,7 @@
}
}

.filled(@class, @bg, @text-colour: @text-color) {
.filled(@class, @bg, @text-colour, @link-colour) {
// Filled boxstyles should flush at widths that the padding isn't added at
.flush() {
&@{class} {
Expand Down Expand Up @@ -168,23 +172,22 @@
}
}

.filled(@class, @bg, @text-colour) when (lightness(@bg) < 50%) {
.filled(@class, @bg, @text-colour, @link-colour) when not (@text-colour = inherit) {
.boxstyle_, .boxstyle-xs, .boxstyle-sm, .boxstyle-md, .boxstyle-lg {
&@{class} {
.link-colour(@text-colour);
.header-colour(@text-colour);

blockquote.quotes {
color: inherit;
}
}
}
}

.filled(@class, @bg, @text-colour: @text-color) when not (@text-colour = inherit) {
.filled(@class, @bg, @text-colour, @link-colour) when not (@link-colour = inherit) {
.boxstyle_, .boxstyle-xs, .boxstyle-sm, .boxstyle-md, .boxstyle-lg {
&@{class} {
.header-colour(@text-colour);
// ID-78 Hanging fire on this for now .link-colour(@text-colour);

blockquote.quotes {
color: inherit;
}
.link-colour(@text-colour);
}
}
}
Expand Down Expand Up @@ -251,4 +254,4 @@
}
}
}
}
}
90 changes: 67 additions & 23 deletions less/mixins/branding.less
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

.apply-navbar-brand(@colour, @active-colour: screen(@colour, lighten(black, 30%))) {
@border-colour: multiply(@colour, darken(white, 20%));
@contrast-colour: contrast(@colour, @text-color, white, 50%);
@contrast-colour: #wcag.contrast(@colour, white, @text-color)[@result];

.apply-navbar-brand(@colour,
@contrast-colour,
Expand Down Expand Up @@ -211,20 +211,70 @@
}
}

// Generates a set of valid colours for a given brand colour.
// Colours are grouped into pairs for use in different contexts.
// Colours of a pair should pass AA contrast.
.calculate-brand-colours(@colour) {
@primary: @colour;
@primary-contrast: #wcag.contrast(@primary, white, @text-color)[@result];

// don't use directly, use @secondary
@base-secondary: tint(@colour, 30%);

// ultra-contrast may end up darkening or lightening the background to achieve AA
@secondary-calc-msg: #wcag.ultra-contrast(@base-secondary, white, @text-color)[@msg];
@secondary: #wcag.ultra-contrast(@base-secondary, white, @text-color)[@bg];
@secondary-contrast: #wcag.ultra-contrast(@base-secondary, white, @text-color)[@fg];
// Used for some minor link hover states
@secondary-accent: multiply(@secondary, darken(white, 20%));

// A colour we can place on white. For links and headings
@white-emphasis: #wcag.contrast-fallback(white, @primary, @text-color)[@result];

// A deeper colour we can place on white. May be the same as @white-emphasis if they are both black
@white-deep-emphasis: #wcag.contrast-fallback(white, darken(@primary, 20%), @text-color)[@result];

// Links/headings on a pale tint of brand colour
@pale: tint(@colour, 85%);
@pale-emphasis: #wcag.contrast-fallback(@pale, @primary, @text-color)[@result];

// Links/headings on pale grey
@pale-grey: @gray-lighter;
@pale-grey-emphasis: #wcag.contrast-fallback(@pale-grey, @primary, @text-color)[@result];

}

.apply-brand(@colour) {
.header-colour(@colour);
.link-colour(@colour);

@colours: .calculate-brand-colours(@colour);

@primary-colour: @colours[@primary];
@secondary-colour: @colours[@secondary];
@secondary-accent-colour: @colours[@secondary-accent];
@secondary-contrast-colour: @colours[@secondary-contrast];

.debug(--secondary-debug, @colours[@secondary-calc-msg]);

// Only really for the tertiary nav
@tertiary-accent-colour: multiply(@id7-navigation-tertiary-background-colour, darken(white, 20%));
@tertiary-contrast-colour: contrast(@id7-navigation-tertiary-background-colour, @text-color, white, 50%);

.header-colour(@colours[@white-emphasis]);
.link-colour(@colours[@white-emphasis]);

// capture the colour used
@link-colour: .link-colour(@colour)[@c];

blockquote.quotes {
color: darken(@colour, 20%);
color: @colours[@white-deep-emphasis];

&::before {
color: @colour;
color: @colours[@white-deep-emphasis];
}
}

.brand-bg {
@contrast-colour: contrast(@colour, @text-color, white, 50%);
@contrast-colour: @colours[@primary-contrast];

background: @colour;
color: @contrast-colour;
Expand All @@ -238,8 +288,8 @@

.brand-border { border-color: @colour; }

@btn-brand-color: contrast(@colour, @text-color, white, 50%);
@btn-brand-bg: @colour;
@btn-brand-color: @colours[@primary-contrast];
@btn-brand-bg: @colours[@primary];
@btn-brand-border: darken(@btn-brand-bg, 5%);

// Brand colour button variant
Expand All @@ -260,11 +310,8 @@
background-color: transparent;
}

@primary-colour: @colour;
@secondary-colour: screen(@colour, lighten(black, 30%));

.id7-navigation .navbar-primary {
.apply-navbar-brand(@primary-colour, @secondary-colour);
.apply-navbar-brand(@colours[@primary], @colours[@secondary]);
}

@breadcrumbs-colour: @colour;
Expand All @@ -273,9 +320,6 @@
}

.navbar-secondary {
@secondary-accent-colour: multiply(@secondary-colour, darken(white, 20%));
@secondary-contrast-colour: contrast(@secondary-colour, @text-color, white, 50%);

.apply-navbar-brand(
@secondary-colour,
@secondary-contrast-colour,
Expand Down Expand Up @@ -307,9 +351,6 @@
}

.navbar-tertiary {
@tertiary-accent-colour: multiply(@id7-navigation-tertiary-background-colour, darken(white, 20%));
@tertiary-contrast-colour: contrast(@id7-navigation-tertiary-background-colour, @text-color, white, 50%);

.apply-navbar-brand(
@id7-navigation-tertiary-background-colour,
@tertiary-contrast-colour,
Expand Down Expand Up @@ -430,11 +471,14 @@
}

.apply-boxstyles-brand(@colour) {
#boxstyle > .filled(~".box1", screen(@colour, lighten(black, 85%)));
#boxstyle > .filled(~".box2", @gray-lighter);
#boxstyle > .bordered(~".box3", @colour);
#boxstyle > .bordered(~".box4", @gray-light);
#boxstyle > .filled(~".box5", @colour, white);
// Use the approved colour pairings from this mixin
@colours: .calculate-brand-colours(@colour);

#boxstyle.filled(~".box1", @colours[@pale], @text-color, @colours[@pale-emphasis]);
#boxstyle.filled(~".box2", @colours[@pale-grey], @text-color, @colours[@pale-grey-emphasis]);
#boxstyle.bordered(~".box3", @colour);
#boxstyle.bordered(~".box4", @gray-light);
#boxstyle.filled(~".box5", @colours[@primary], @colours[@primary-contrast], @colours[@primary-contrast]);
}

.apply-pagination-brand(@colour) {
Expand Down
14 changes: 14 additions & 0 deletions less/mixins/debug.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@debug-enabled: false;

// If @debug-enabled is true, outputs some debug data at the
// current location. Normally the key might be a CSS variable name.
// Useful for debugging intermediate values that you aren't otherwise
// using.
// May not work inside a mixin that is being captured into a variable.
.debug(@key, @value) when (@debug-enabled) {
.debug-data {
@{key}: @value;
}
}

.debug(@key, @value) when (default()) {}
8 changes: 5 additions & 3 deletions less/mixins/link-styles.less
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
.link-colour(@base, @hover) {
@c: @base;

a, a:link, a:visited {
color: @base;
color: @c;
}

a:hover, a:focus, a:active {
color: @hover;
}

.popover button.close {
color: @base;
color: @c;
&:hover {
color: @hover;
}
Expand All @@ -23,7 +25,7 @@
}

.btn-link {
color: @base;
color: @c;
&:hover,
&:focus {
color: @hover;
Expand Down
Loading

0 comments on commit 9760f97

Please sign in to comment.