Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you create an angular material theme using ONLY hex values?

Absolutely every single demo I've seen for creating an angular material theme involves the use of a pre-defined color palette (e.g. $mat-blue). I want to create a theme starting solely from HEX values. How can I do this? (Surely I'm not expected to start with my HEX values and somehow work backward to find the corresponding pallete in material's extremely limited predefined universe?!)

Here's an example of the HEX values I want to use: https://material.io/resources/color/#!/?view.left=0&view.right=1&primary.color=2C3E50&secondary.color=95a5a6&primary.text.color=ffffff&secondary.text.color=000000

Edit: for clarification, I know how to create custom themes using pre-defined colors supplied by angular-material (e.g. basing $primary off of $mat-blue), but what I want to be able to base $primary off of e.g. #2C3E50.

like image 696
Magnus Avatar asked May 18 '26 16:05

Magnus


1 Answers

Here's the workflow I settled on to get as close as possible to what I wanted to achieve.

First of all, make sure you know your scss fundamentals when attempting theming. If you don't know what these items and their syntax are (i.e. how they translate to css):

  • map and get-map
  • mixin
  • function

... then you need to first read the linked documentation. (They're not complicated and won't take long.) At the end of the day, angular themes are just scss maps of maps, so building them and accessing their contents just comes down to some scss know-how.

In angular material, you basically start with three choices of color to build your theme around: primary, accent, and warn. Suppose you choose the three colors #375a7f, #444444, and #eb0000 respectively. Go to this site and, for each color, name the palette (e.g. darkprimarymap) and input the HEX color into the menu like so:

enter image description here

... then click on View Code, select Angular 2, then copy and paste the code you see from something like this:

enter image description here

... into your theming file. An "out-of-the-box" theming file looks like this:

$app-dark-primary: mat-palette($mat-grey, 700, 300, 900);
$app-dark-accent: mat-palette($mat-blue-grey, 400);
$app-dark-warn: mat-palette($mat-red, 500);

$app-dark-theme: mat-dark-theme($app-dark-primary, $app-dark-accent, $app-dark-warn);

... where mat-palette is a function that accepts nested maps of the form we just copied. So paste the code we copied to create alternative palette variables like this:

@import '~@angular/material/theming';

// Create nested scss map
$dark-primary-map: (
  50: #e7ebf0,
  100: #c3ced9,
  200: #9badbf,
  300: #738ca5,
  400: #557392,
  500: #375a7f, // original primary color you built this map around
  600: #315277,
  700: #2a486c,
  800: #233f62,
  900: #162e4f,
  A100: #8bb8ff,
  A200: #5898ff,
  A400: #2579ff,
  A700: #0c69ff,
  contrast: (
    50: #000000,
    100: #000000,
    200: #000000,
    300: #000000,
    400: #ffffff,
    500: #ffffff,
    600: #ffffff,
    700: #ffffff,
    800: #ffffff,
    900: #ffffff,
    A100: #000000,
    A200: #000000,
    A400: #ffffff,
    A700: #ffffff
  )
);

$dark-accent-map: (
  50: #e9e9e9,
  100: #c7c7c7,
  200: #a2a2a2,
  300: #7c7c7c,
  400: #606060,
  500: #444444, // original accent color you built this map around
  600: #3e3e3e,
  700: #353535,
  800: #2d2d2d,
  900: #1f1f1f,
  A100: #f07a7a,
  A200: #eb4c4c,
  A400: #ff0505,
  A700: #eb0000,
  contrast: (
    50: #000000,
    100: #000000,
    200: #000000,
    300: #ffffff,
    400: #ffffff,
    500: #ffffff,
    600: #ffffff,
    700: #ffffff,
    800: #ffffff,
    900: #ffffff,
    A100: #000000,
    A200: #ffffff,
    A400: #ffffff,
    A700: #ffffff
  )
);

$dark-warn-map: (
  50: #fde0e0,
  100: #f9b3b3,
  200: #f58080,
  300: #f14d4d,
  400: #ee2626,
  500: #eb0000,  // original warn color you built this map around
  600: #e90000,
  700: #e50000,
  800: #e20000,
  900: #dd0000,
  A100: #ffffff,
  A200: #ffd1d1,
  A400: #ff9e9e,
  A700: #ff8585,
  contrast: (
    50: #000000,
    100: #000000,
    200: #000000,
    300: #ffffff,
    400: #ffffff,
    500: #ffffff,
    600: #ffffff,
    700: #ffffff,
    800: #ffffff,
    900: #ffffff,
    A100: #000000,
    A200: #000000,
    A400: #000000,
    A700: #000000
  )
);

// Convert maps into 'palettes'
$dark-primary-palette: mat-palette($dark-primary-map);
$dark-accent-palette: mat-palette($dark-accent-map);
$dark-warn-palette: mat-palette($dark-warn-map);

// Create 'theme' from palettes
$app-dark-theme: mat-dark-theme($dark-primary-palette, $dark-accent-palette, $dark-warn-palette);

You can of course manually create/edit these maps (which might be smart since the linked site makes simplistic extrapolations from your single-color input). If this code is in a file called dark-theme.scss, you then incorporate that theme into your angular app with this sort of syntax in your main/global styles.scss file:

@import '~@angular/material/theming';
@include mat-core();
@import 'themes/dark-theme.scss'; // imports $app-dark-theme

.dark-theme {
  @include angular-material-theme($app-dark-theme);
  @include custom-components-theme($app-dark-theme);
}

Now, when you color a material component with the color="primary" directive on this theme, it will get colored as #375a7f, and so on.

To pull other colors out of these palettes for use in your app in customized components, you use this sort of syntax in a app.component.scss-theme.scss file:

@import '~@angular/material/theming';

// Define scss mixin that takes a $theme map and injects its content 
// into css styles; we'll inject our $app-dark-theme here later
@mixin app-component-theme($theme) {
  // Get the primary, secondary and warn palettes 
  // you created back from the active theme using the map-get() function
  $primary: map-get($theme, primary);
  $accent: map-get($theme, accent);
  $warn: map-get($theme, warn);

  // Extract colors from those palettes using the mat-color() function
  // E.g. use the 'darker' input to get the color keyed by '700'
  $color1: mat-color($primary, darker);

  // E.g. use 'A100' to get the color keyed by 'A100' (A = Additional I think)
  $color2: mat-color($primary, A100);

  // E.g. use 'A100-contrast' to get the color keyed by 'A100' within the contrast sub-map
  $color3: mat-color($primary, A100-contrast);

  // Then use these color-value variables as per normal scss. E.g.
  mat-sidenav-container {
      background: $color1;
    mat-toolbar {
      background-color: $color2;
      mat-list{
        background-color: $color3;
      }
    }
  }
}

... then incorporate all such custom-component themes into your main/global styles.scss file like so:

@import 'component.scss-theme';

// Define custom component themes
@mixin custom-components-theme($theme) {
  @include app-component-theme($theme);
}
like image 88
Magnus Avatar answered May 22 '26 12:05

Magnus



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!