← back to blog

How to add any CSS framework to your project — Part 3

Explore how to extract Bootstrap colors, build a consistent color palette, and reuse variables across your project.

In the second part, we looked at how to integrate Bootstrap variables into your project, allowing easy customization without overwriting styles. By the end of that article, you had a single file containing all variables, with the ability to reuse them inside Angular component styles.

How to add any CSS framework to your project — Part 3

Color palette

Colors are one of the most important parts of any design system — and also one of the most complicated. If not handled properly, they can lead to confusion and inconsistency down the line. To avoid that, you need a clear, well-structured color system that stays consistent throughout the project.

If done right, you’ll be able to develop and maintain the entire project using only 6–8 core colors and their shades. In Bootstrap, the default functional colors are:

$primary: $blue;
$secondary: $gray-600;
$success: $green;
$info: $cyan;
$warning: $yellow;
$danger: $red;
$light: $gray-100;
$dark: $gray-900;

These may vary in other frameworks, but the concept remains the same. Since colors are so critical, I usually move them into a separate file: _palette.scss.


The _palette.scss file

Create this file inside the /src/styles/variables folder, next to the _bootstrap.scss file.

The next step is to move the import of Bootstrap’s functions from _bootstrap.scss into _palette.scss so you can use them:

// to support Angular components styles
@import 'bootstrap/scss/functions';

Now cut everything from _bootstrap.scss, starting at line 9 through line 359, and paste it into _palette.scss. This will include:

// Color system

// scss-docs-start gray-color-variables
$white: #fff;
$gray-100: #f8f9fa;
$gray-200: #e9ecef;
$gray-300: #dee2e6;
...
...
...
$warning-border-subtle: tint-color($warning, 60%);
$danger-border-subtle: tint-color($danger, 60%);
$light-border-subtle: $gray-200;
$dark-border-subtle: $gray-500;
// scss-docs-end theme-border-subtle-variables

The entry point for all variables

Since you’re now using multiple files for variables, you’ll need a new entry point to import them wherever needed. Create a new variables.scss file in the same /src/styles/variables folder and add the following:

@import './_palette.scss';
@import './_bootstrap.scss';

Next, modify the vendor.scss file to import variables.scss instead of _bootstrap.scss. Do the same in any Angular component styles where you want access to your variables.

Now let’s go back to _palette.scss and review how Bootstrap structures its color system.


Bootstrap’s color palette

There are two main ways how to handle colors in your project. The first one is when all color variables are named by the value of color:

...
$blue: #0d6efd;
$indigo: #6610f2;
$purple: #6f42c1;
$pink: #d63384;
$red: #dc3545;
...

and by the value of color shades:

$blue-300: tint-color($blue, 40%);
$blue-400: tint-color($blue, 20%);
$blue-500: $blue;
$blue-600: shade-color($blue, 20%);
$blue-700: shade-color($blue, 40%);

The tint-color() and shade-color() functions are provided by Bootstrap to generate lighter or darker variants of a color. More details can be found in the official docs.

This system lets you use colors variables clearly without worrying about their actual hex values. It’s convenient for large projects with stable color schemes.

However, Bootstrap also includes functional color variables like $primary, $success, and $info, which can be confusing when used together with the color values above. Consider this example:

// hero button
.hero__btn {
  background: $primary;

  &:hover,
  &:active {
    background: $blue-600;
  }
}

Here, we are setting a primary color as a background for the button, but to make it darker for hover and active states, we need to use another set of color variables. That’s because Bootstrap defines all color variables and their shades first and only afterward maps them to functional color variables.

My preference is a different approach.


Functional color palette

As an alternative solution, we can review how Ng-Zorro handles color palettes. They also define brand and functional colors, but they start by assigning both base and functional color variables:

Ng-Zorro uses Less instead of SCSS. Future examples use Less syntax, which is slightly different.

// ----- Colors ----------- //
@primary-color: @blue-6;
@info-color: @primary-color;
@success-color: @green-6;
@processing-color: @blue-6;
@error-color: @red-5;

Only after that do they generate all the different shades of functional variables:

// Color used by default to control hover and active backgrounds and for
// alert info backgrounds.
...
@primary-4: color(~`colorPalette('@{primary-color}', 4) `); // unused
@primary-5: color(~`colorPalette('@{primary-color}', 5) `); // color used to control the text color in many active and hover states, replace tint(@primary-color, 20%)
@primary-6: @primary-color; // color used to control the text color of active buttons, don't use, use @primary-color
@primary-7: color(~`colorPalette('@{primary-color}', 7) `); // replace shade(@primary-color, 5%)
@primary-8: color(~`colorPalette('@{primary-color}', 8) `); // unused
...

colorPalette() is Ng-Zorro’s function that creates different shades out of the provided color and selected index in the color palette. You can check more about it in the official documentation.

Let’s rewrite our earlier example with this system:

// hero button
.hero__btn {
  background: @primary-color;

  &:hover,
  &:active {
    background: @primary-7;
  }
}

With this structure, you can consistently use functional color variables and their shades only. This minimizes confusion and makes it easy to change your entire color scheme later — just update the @primary-color variable, and all related shades update automatically.

Of course, you can recreate the same system with Bootstrap by defining a set of new variables using the tint-color() and shade-color() functions.


Conclusion

In this article, we explored how to structure your color system for clarity and scalability. By now, you should have:

  1. A _palette.scss file containing all color-related variables.

  2. Set of functional color variables and their shades that are generated by specific rules of your color system.

  3. The ability to reuse all color variables across your project.

In the next post, we’ll cover how to modify form elements and Bootstrap components when changes can’t be made through variables alone. Stay tuned!