Allow different brand colors per tenant

Until now, overwriting the styles for a certain tenant was a very
tedious task. For example, if we wanted to use a different brand color
for a tenant, we had to manually overwrite the styles for every element
using that color.

It isn't possible to use different SCSS variables per tenant unless we
generate a different stylesheet per tenant. However, doing so would make
the CSS compilation take way too long on installations with more than a
couple of tenants, and it wouldn't allow to get the colors dynamically
from the database, which we intend to support in the future.

So we're using CSS variables instead. These variables are supported by
97% of the browsers (as of October 2022), and for the other 3% of the
browsers we're using the default colors (SCSS variables) instead.

CSS variables have some limitations: for instance, it isn't possible to
use functions like `lighten`, `darken` or `scale-color` with CSS
variables, so the application might behave in a strange way when we use
these functions.

It also isn't possible to automatically get whether black or white text
makes a better contrast with a certain background color. To overcome
this limitation, we're providing variables ending with `-contrast`. For
instance, since the default `$brand` color is a dark one, when assigning
a light color to `--brand`, we probably want to assign
`--brand-contrast: #{$black}` as well, so the text is still readable.
This commit is contained in:
Javi Martín
2022-10-12 17:57:29 +02:00
parent a2c032573f
commit fcc63cb436
10 changed files with 75 additions and 23 deletions

View File

@@ -5,7 +5,7 @@
position: relative;
li {
border-top: 4px solid $brand;
@include brand-border(top, 4px);
display: inline-block;
font-size: $small-font-size;
font-weight: bold;
@@ -13,7 +13,7 @@
text-transform: uppercase;
&::before {
background: $brand;
@extend %brand-background;
border-radius: 50%;
content: "";
height: 20px;

View File

@@ -4,7 +4,7 @@
position: relative;
&::after {
background: $brand;
@extend %brand-background;
bottom: 0;
content: "";
height: rem-calc(6);

View File

@@ -48,7 +48,7 @@
.keep-scrolling {
@include has-fa-icon(angle-double-down, solid, after);
color: $brand;
@include brand-color;
font-weight: bold;
text-decoration: none;
text-transform: uppercase;

View File

@@ -0,0 +1,15 @@
// If you're using multitenancy, you can override styles for a certain
// tenant by styling the `<html>` element with the class
// `tenant-<tenant_name>`. For example, to style the public (main)
// tenant without these styles affecting any other tenants, use the
// `.tenant-public` selector.
//
// You can use CSS variables to customize the colors. Here's an example
// changing the brand color for just the main tenant.
//
// .tenant-public {
// --brand: #351;
// }
//
// NOTE: If you are **not** using mulitenancy, we recommend overwriting
// SCSS variables in the `_consul_custom_overrides.scss` file instead

View File

@@ -20,7 +20,7 @@
thead {
tr th {
border: 1px solid $brand;
@include brand-border;
}
}
}

View File

@@ -125,8 +125,7 @@ button,
.button {
@extend %button;
@include inverted-selection($brand);
background: $brand;
@include brand-background;
&.medium {
font-size: $small-font-size;
@@ -949,7 +948,7 @@ footer {
}
.sidebar-title {
border-top: 2px solid $brand;
@include brand-border(top, 2px);
display: inline-block;
font-size: rem-calc(16);
font-weight: bold;
@@ -969,7 +968,7 @@ footer {
}
.auth-image {
@include background-with-text-contrast($brand);
@include brand-background;
background-repeat: no-repeat;
background-size: cover;
@@ -1358,8 +1357,8 @@ form {
}
&::before {
@include brand-color;
background: $body-background;
color: $brand;
content: "\4d";
font-family: "icons" !important;
font-size: $small-font-size;
@@ -2505,8 +2504,8 @@ table {
h3 {
&.title {
@include brand-border(top, 4px);
display: inline-block;
border-top: 4px solid $brand;
margin-bottom: 0;
padding: $line-height / 2 0;
}

View File

@@ -264,7 +264,7 @@
}
.control input:checked ~ .control-indicator {
background-color: $brand;
@include brand-background;
border: 0;
}

View File

@@ -1,6 +1,7 @@
@import "mixins/colors";
@mixin base-button {
@include button-base;
font-size: $base-font-size;
&:focus,
@@ -18,16 +19,35 @@
}
@mixin regular-button($color: $brand) {
@include button($background: $color);
@include inverted-selection($color);
@include base-button;
@if $color == $brand {
@include brand-background;
} @else {
@include background-with-text-contrast($color);
}
&:hover,
&:focus {
@include background-with-text-contrast($button-background-hover);
}
}
@mixin hollow-button($color: $anchor-color) {
@include button($style: hollow, $background: $color);
@include normal-selection;
@include base-button;
border-color: currentcolor;
color: $color;
margin-bottom: 0;
@if $color == $brand {
@include brand-color;
}
&:hover,
&:focus {
color: scale-color($color, $lightness: $button-hollow-hover-lightness);
}
}
@mixin link {

View File

@@ -1,19 +1,35 @@
@mixin background-with-text-contrast($color, $check-invert-selection: true) {
@mixin background-with-text-contrast($color, $property-name: null, $check-invert-selection: true) {
background-color: $color;
color: color-pick-contrast($color);
@if $property-name {
background-color: var(--#{$property-name}, $color);
color: var(--#{$property-name}-contrast, color-pick-contrast($color));
}
@if $check-invert-selection {
@include inverted-selection($color);
}
}
@mixin brand-background {
@include background-with-text-contrast($brand);
@include background-with-text-contrast($brand, brand);
}
@mixin brand-color {
@include normal-selection;
color: $brand;
color: var(--brand, $brand);
}
@mixin brand-border($position: null, $width: 1px) {
@if $position == null {
border: $width solid $brand;
border: $width solid var(--brand, $brand);
} @else {
border-#{$position}: $width solid $brand;
border-#{$position}: $width solid var(--brand, $brand);
}
}
@mixin body-colors {
@@ -25,7 +41,7 @@
&::selection,
*::selection {
@include background-with-text-contrast($brand, $check-invert-selection: false);
@include background-with-text-contrast($brand, brand, $check-invert-selection: false);
}
}
@@ -34,7 +50,9 @@
&::selection,
*::selection {
background-color: rgba(color-pick-contrast($brand), 0.99);
background-color: var(--brand-contrast, rgba(color-pick-contrast($brand), 0.99));
color: $brand;
color: var(--brand, $brand);
}
}
}

View File

@@ -256,7 +256,7 @@
aside {
h2 {
border-top: 2px solid $brand;
@include brand-border(top, 2px);
display: inline-block;
font-size: rem-calc(16);
margin: -1px 0 rem-calc(12);
@@ -1097,7 +1097,7 @@
}
.progress-meter {
background: $brand;
@include brand-background;
border-radius: rem-calc(12);
border-bottom-right-radius: 0;
border-top-right-radius: 0;
@@ -1133,7 +1133,7 @@
white-space: nowrap;
&::before {
color: $brand;
@include brand-color;
content: "\57";
font-family: "icons";
font-size: $small-font-size;
@@ -1180,7 +1180,7 @@
}
.subtitle {
border-left: 2px solid $brand;
@include brand-border(left, 2px);
margin: $line-height / 2 0;
padding-left: $line-height / 2;
}
@@ -1442,7 +1442,7 @@
width: $line-height / 2;
&.is-active {
background-color: $brand;
@include brand-background;
}
}