# Style Customization

All Widgets in this catalog use a flat, minimal design based on Bootstrap, waiting to be adapted to a client's designs and guidelines. Remember that these Widgets are intended to be used as the basis for finished products and not as a products themselves.

For both the style base and the grid used in Widgets, we use Bootstrap (opens new window) version 4.5.x, which includes useful helpers and classes. This way the number of custom styles in our Widgets is very low, making them simple and easy to modify.

TIP

To make the most of Bootstrap's potential, we use SCSS as the css pre-processor, which allows us to modify the default variable values used in Bootstrap.

 
 




<div class="bg-white px-3 pt-3 pb-2 rounded mt-3">
<div class="d-flex justify-content-between mb-2">
<!-- content -->
</div>
</div>

# File structure and style loading

In the src folder of the project we will find a folder called scss that has the following structure:




 
 
 


├── src/
│   ├── ...
│   ├── scss/
│   │   ├── _theme.scss
│   │   ├── _variables.scss
│   │   └── custom.scss
│   ├── ...

# Topic

The _theme.scss file is used for:

  • Global Widget Styles
  • Extend bootstrap using your mixins

 
 




 


 


// Example: We use the mixin bg-variant to create more background colors
@include bg-variant (".bg-tertiary", $tertiary, true);
@include bg-variant (".bg-tertiary-10", $tertiary-10, true);

// In these following examples we use the mixin button-variant that allows us to create new buttons with all their states
.btn-tertiary {
  @include button-variant ($tertiary, $tertiary);
}
.btn-outline-tertiary {
  @include button-outline-variant ($tertiary, $white, $primary-80, $primary-80);
  color: $secondary-100;
}

You can find a list with the available mixins here (opens new window) and a detailed explanation here (opens new window)

# Variables

The _variables.scss file contains all the default bootstrap variables (colors, sizes, buttons, etc). Here we can change the values we need to adjust the base bootstrap styles to our design, avoiding having to write or add more classes to our project (you can read more about how to modify bootstrap here (opens new window)).

# Example

Formerly

// ...
$light: $secondary-10;
// ...
$border-width: 1px;
$border-color: $primary-10;
$border-radius: 0.35rem;
//...

After


 

 
 
 



//...
$light: lightblue;
//...
$border-width: 2px;
$border-color: $second;
$border-radius: 1.35rem;
//...

# Custom

In the custom.scss file we import and give order to all the other stylesheets that we have in thescss folder along with the Bootstrap base.

 



@import". /variables ";//always before bootstrap
@import "~bootstrap";
@import". /theme.scss ";

# :::tip

Order is important, variables always go before importing bootstrap. :::

Thisscss file is imported into the project's main.js file.




 







import Vue from "vue";
//...
import "bootstrap"; // only import javascript, not the styles
import "./scss/custom.scss";
//...
new Vue({
  store,
  i18n,
  render: (h) => h(App),
}).$mount("#my-Widget");

Important

The @import 'bootstrap' of this file only imports bootstrap.js and not styles!

Component Styles

Some of the widget components have their own styles and these are written in the same component (.vue). By using the scoped attribute, we can define the scope of these styles at the component level without affecting other parts of the Widget.





 












<template>...</template>

<script>
  ...
</script>

<style lang="scss" scoped>
  .consumer-loan-months-selector {
    .card {
      border: 1px solid $primary-10;
    }
    .card-header {
      padding: 0.75rem 1.25rem;
    }
  }
</style>

# PurgeCSS

When you're building a Widget with Bootstrap (or another style framework) you'll likely only use a small portion of it, and many unused CSS styles could be included. This is where PurgeCSS comes into play. PurgeCSS analyzes your content and CSS files. It then matches the selectors used in your files to those in your content files, and removes the unused selectors from your CSS, resulting in smaller CSS files.

Widgets use PurgeCSS (opens new window) in conjunction with PostCSS (opens new window) as part of the development flow. This way we manage to remove those extra bytes that we don't need and optimize our Widgets. Excellent!

# ::: danger PROBLEM!

What happens to the styles NOT declared in the content, but that ARE used in the Widget? :::

Sometimes we may encounter some style problems, for example when we use the Bootstrap modal component and the modal-backdrop style does not load since this element is created dynamically when you open the modal; or when we use external component libraries in our Widgets where the styles have not been loaded and are not on the site. This happens because PurgeCSS does not know where to read the contents of the external component.

To include the styles that we need on the site but PurgeCSS has removed, we need to declare them in a PostCSS configuration file. This file is located at the root of the Widget and is called postcss.config.js

const PURGE_CSS = require("@fullhuman/postcss-purgecss");

const IN_PRODUCTION = process.env.NODE_ENV === "production";
const plugins = {};

if (IN_PRODUCTION) {
  plugins.purgecss = PURGE_CSS({
    content: ["./public/**/*.html", "./src/**/*.vue"],
    defaultExtractor(content) {
      const contentWithoutStyleBlocks = content.replace(
        /<style[^]+?<\/style>/gi,
        ""
      );
      return (
        contentWithoutStyleBlocks.match(/[A-Za-z0-9-_/:]*[A-Za-z0-9-_/]+/g) ||
        []
      );
    },
    whitelist: [],
    whitelistPatterns: [
      /-(leave|enter|appear)(|-(to|from|active))$/,
      /^(?!(|.*?:)cursor-move).+-move$/,
      /^router-link(|-exact)-active$/,
      /data-v-.*/,
      /svg.*/,
      /fa.*/,
      /^d-*/,
    ],
  });
}
// ...

In this file we can force PurgeCSS to include styles in 3 different ways:

Add the content file to the content property. This way PurgeCss is able to read the content and determine which styles it should include.

Add keywords to the whitelist property

Add regex patterns to the WhiteListPatterns property

  • Add the content file to the content property. This way PurgeCss is able to read the content and determine which styles it should include.






     




    // ...
    plugins.purgecss = PURGE_CSS({
      content: [
        './public/**/*.html',
        './src/**/*.vue',
        'node_modules/@modyo/financial-commons/src/components/MStepper/**/*.vue'
      ]
      defaultExtractor(content) { // block code }
    // ...
    
  • Add keywords to the whitelist property


     



    ...
      defaultExtractor(content) { // block code }
      whitelist: ['modal-backdrop', 'fade', 'show'],
    ...
    
  • Add regex patterns to the WhiteListPatterns property






     



    // ...
      defaultExtractor(content) { // block code }
      whitelist: ['fade', 'show'],
      whitelistPatterns: [
      // ...
        /modal-.*/
      ]
    // ...