Back to Blog

When Is It OK To Override the Morningstar Design System?

Learn when and how to customize styling with MDS components

October 25, 2022 - Morningstar, like many other companies, has a fundamental business need for its products to be branded, responsive and accessible to all users across all devices. The Morningstar Design System (MDS) solves for and abstracts away many of these considerations, streamlining and driving consistency across design and development work.

However, there may be times when specific user needs call for a solution that diverges from what is available out-of-the box. In this article, we will explore some high-level questions to help you determine if overriding CSS with MDS is appropriate and how to do it as well.

For practical guidelines on how to override and to see an example on how to create a vertical version of the MDS stepper, you can go directly to the How to do it? section.

To Override or Not To Override?

Overriding MDS should be done when it serves the best interest of the product. However, making this choice may have implications beyond solving the immediate problem.

When existing components don't quite fit your needs, customizing them appears to be the obvious answer. Being able to be autonomous and fast in your work by not having to rely on another team to roll out features is an attractive prospect. Yet, this 'simple' solution not only re-introduces the need to solve for those previously-solved business constraints, it can also cause unintended consequences in the long term. The decision to override is not one to be taken lightly.

Any sort of changes made to local components will stay in place, even if official versions diverge. This introduces more technical debt and a higher risk of breakages when custom solutions aren't compatible with updates to core components. Ultimately, this results in additional maintenance work for teams, lower coherency across company products as a whole, and extra effort required for onboarding new engineers and designers onto projects.

There is also the potential duplication of efforts where independent product teams could be implementing CSS overrides to solve for the same problem. As an alternative to overriding, consider contributing your feature or design directly to the Morningstar Design System and make it official. By being vocal and sharing what your team requires from MDS, you open up the opportunity to help others at Morningstar get their own needs addressed as well. The MDS team is available to provide support and consultations for teams that require additional guidance when working with our system.

A Few Questions...

While determining if CSS overrides are appropriate for your situation, the following questions are important to think about throughout the process:

Are you using the appropriate MDS component for your desired functionality?

Each component is developed to provide specific functionality. If the MDS component is not fulfilling the needs of your design as-is, instead of modifying it, determine if there is another component that would be a better fit.

Cross reference each component's usage advice, found under the 'Design Guidelines' tab, to find recommendations for variations and alternative MDS components for common use-cases.

Each component documentation page has a Design Guidelines tab

Consider the following recommendations for the MDS Tabs component as a typical example:

Use When Creating top-level navigation within a product. Use the site navigation variation.
Creating secondary or tertiary navigation between sets of content. Use the in-page variation.
Don't Use When Providing a way to toggle between options for the display of a single item, e.g. changing the time period on a chart. Instead, use a button group or a select.

Did you review your visual design changes with design leaders and share with others in the Morningstar design community?

Is your customization purely a visual change because you didn't like the way the MDS component looked? Implementing changes for this reason would create visual inconsistency between your product and the others at Morningstar.

MDS is intended to be a communal system which relies on collective input, feedback and buy-in from all its users. If you or your team's designer would like to propose updates to the system, they should be discussed as a community.

Does the change you're considering align with Morningstar brand guidelines and visual language?

Morningstar's visual language is an integral part in portraying the company's identity. Ensure that your CSS overrides do not interfere with our Visual Language and Brand standards for things like: color usage, typography and fonts, iconography, illustrations, animations and more.

Each individual MDS component also has a 'Visual Language' section with component-specific details. As a simple example, the following standards are outlined for the MDS Button:

Use the same button size for adjacent buttons.

These are in reference to the different options for the size prop available on the MDS Button.

However, if your custom styling affects the size of some buttons (E.g. Adding more padding to only the primary variation for more visual emphasis), it would still go against the spirit of this guideline and would need to be reconciled.

Will your changes adhere to Morningstar and Web Content Accessibility Guidelines (WCAG)?

Using components in ways they weren't intended could result in a confusing and unintuitive experience for users that rely on their built-in accessibility features. Making changes such as styling links or divs to look like buttons could cause issues such as breaking keyboard navigation, innappropriately shifting browser focus, and providing wrong descriptions for screen readers.

See W3C - Designing for Accessibility for more in-depth advice and recommendations.

Additionally, many MDS components have their own accessibility implementations and best practices for product teams to follow.

Many component pages have an Accessibility tab that outlines relevant implementation and best practices details.

Depending on your team's implementation for your product, certain accessibility considerations might not be relevant or applicable and therefore must be looked at on a case-by-case basis.

How To Do It?

The offical MDS stance on style overrides is that they should be avoided where possible.

However, if you determine that overriding is appropriate for your requirements, it can be accomplished globally across an entire product or targeted to a specific case.

See the official documentation on style customization for high-level guidance on both global and component-specific overrides.

Example - Onboarding Form with Vertical Stepper

Here we will be exploring how to create a vertical stepper with component-specific overrides. We will be using the 4.0.0-beta.3 version of the MDS stepper which is the latest at the time of this writing.

Note: Like with any CSS override, there is the possibility of breakages with any updates to the official MDS stepper component. Please keep this in mind when implementing the following or any other overrides.

Step 1 - Initial Setup

To start, we have the regular horizontal stepper with a simple form underneath. We will be wrapping them inside a container and applying styling to add margins and arrange the form controls.

Initial layout with a horizontal stepper with a form underneath

<template>
    <div class="component-container">
        <mds-stepper>
            <mds-stepper-step title="Account" has-items complete>
                <mds-stepper-item title="1.1" complete></mds-stepper-item>
                <mds-stepper-item title="1.2" complete></mds-stepper-item>
            </mds-stepper-step>
            <mds-stepper-step title="Personal" active></mds-stepper-step>
            <mds-stepper-step title="Payment"></mds-stepper-step>
        </mds-stepper>
        <div class="form-container">
            <mds-form>
                <!--Form Inputs-->
            </mds-form>
            <div class="btn-container">
                <mds-button variation="secondary">Back</mds-button>
                <mds-button variation="primary">Next</mds-button>
            </div>
        </div>
    </div>
</template>

Any overrides to MDS components must be done using CSS modules. Inside our Vue file we will include two seperate style blocks, one for the regular styles and the other (with a module attribute) for the overrides. We will also use the :global() utility provided by CSS modules with the .component-container class to wrap the override styles and make sure they are targeted only to this specific case. This will make it so that the .component-container class does not receive the CSS Module ID suffix like the rest of the classes.

<style lang="scss">
    // Product-specific Styles
    @import '@mds/constants';

    .component-container {
        margin: $mds-space-3-x;
    }
    .form-container {
        margin: $mds-space-3-x;
        display: flex;
        flex-direction: column;
    }

    .btn-container {
        margin-top: $mds-space-2-and-a-half-x;
        align-self: end;
    }
</style>

<style module lang="scss">
    :global(.component-container) {
        // MDS Overrides Will Go Here!
    }

</style>

Step 2 - Determine Required Overrides and Relevant Elements

The MDS stepper is composed of many different elements with complex styling and logic on its own. To preserve as much of the original functionality, not interfere with any accessibility features, and reduce the complexity and amount of overrides, we're going to simply rotate and re-position the relevent stepper parts.

With this course of action in mind, we would actually only need to restyle a small subset of elements.

Image showing the stepper elements that will be overridden and their relevant classes.

Here are where these elements live within the underlying HTML structure of the stepper component:

<div class="mds-stepper">
    <ul class="mds-stepper__list">
        <a class="mds-stepper__list-item-label"></a>
        <li>
            <div>
                <a class="mds-stepper__step-indicator"></a>
            </div>
        </li>
    </ul>
</div>

The simplest way to determine these is by inspecting the component in the dev tools console. Alternatively, you could also look at the source code (found near the top of each component's respective documentation page via the BitBucket link).

By taking advantage of SCSS nesting, the relevant classes can be concisely translated into the following and included inside the override style block in our Vue file.

<style module lang="scss">
    :global(.component-container) {
        .mds-stepper {
            &__step-indicator {}
            &__list {
                &-item-label {}
            }
        }
    }
</style>

Step 3 - Applying the Overrides

First, we need to put the stepper beside the form beside each other and add the desired width.

The stepper beside the form with the desired smaller width applied.

<style lang="scss">
    .component-container {
        display: flex;
    }
</style>

<style module lang="scss">
    :global(.component-container) {
        .mds-stepper {
            width: 150px;
        }
    }
</style>

Next, we are going to rotate the step indicators (where the icons are), the step labels and the underlying list element itself.

The stepper with the step indicators, labels and indicator lines rotated so they are readable in a vertical arrangement.

.mds-stepper {
    &__step-indicator {
        transform: rotate(-90deg);
    }
    &__list {
        transform: rotate(90deg);
        &-item-label {
            transform: rotate(-90deg);
        }
    }
}

Lastly, we are going to change the width of the list element to how long we want the stepper to be and then move it into position. We also need to adjust the position of the step labels to align better with the step indicators

Image that shows the initial position of the vertical stepper after width is applied to the list element is on top of the form and needs to be adjusted. Image showing the repositioning of the step labels to better align with the step indicators.

Here are the final styles with these new additions:

.mds-stepper {
    width: 150px;

    &__step-indicator {
        transform: rotate(-90deg);
    }
    &__list {
        transform: rotate(90deg) translate(170px, 200px);
        width: 500px;

        &-item-label {
            transform: rotate(-90deg) translate(10px, 15px);
            text-align: initial;
        }
    }
}

Final Result

Conclusion

The Morningstar Design System team continuously works to make sure that our components are flexible and configurable enough to fit the majority of use-cases and needs of product teams across Morningstar.

Instead of using style overrides, please consider reaching out to the MDS team to help the Morningstar Design System work best for you. We are always happy to answer questions, provide suggestions and offer consultations. Feedback from our colleagues is invaluable and informs us how to evolve the system and make sure it serves all teams better.

Both designers and engineers are encouraged to post discussions, questions and implementation details in the Morningstar Design System support channels (internal only).