Current version 22.0.0

Customising Tangram

When to customise Tangram

Sometimes it’s healthy and/or necessary to deviate from a design system. This is particularly the case if the design system doesn’t have what you need.

YesNoDoes an existing Tangram component fulfil your needs?New componentBug or fault with an exisiting component Build this feature in your project. It’s likely you’ll be able to build it with pieces of Tangram.Discuss the scenario in the #tangram Slack channel. You may be able to override an existing component, have found a bug, or identified a potential new Tangram component.Could it be added to Tangram in the future?Can you apply a fix by overriding the component?Override an existing componentImplement the override in your project.Leave the comment:in your code.Ensure the functional outcome of your workaround is covered by tests.Apply the fix in your project, leave the comment:in your code. Create a Jira case on the TGM backlog to track the issue with the label “Bug”.Create a Jira case on the TGM backlog to track the issue with the label “Bug”.Create a Jira case on the TGM backlog to track the issue. Add the label “New component”.Leave the comment:in your code.Ensure the functional outcome of your feature is covered by tests.You’re all done!You just saved a bunch of time! Go ahead with the component, and head to the #tangram Slack channel for support.NoYesNoYesFlowchart for customising Tangram

We're here to help!

Join the conversation at #tangram

Creating something custom?

If you create something custom when a suitable component or pattern is available, you are likely to hear the following questions from your Design Lead or the Tangram team:

  • Have you explored using existing Tangram components and patterns? Could they been extended to meet your needs?
  • What does your proposed changes achieve that existing components or patterns don’t provide?
  • What is the use case that prompted the proposed change?
  • Have your proposed changes been user tested?
  • Is there a precedence for this outside of Trade Me?

How to override Tangram CSS

Summary

There will be times when you need to override Tangram styles to customise the user interface.

  • Overrides in your product must be covered by tests.
  • Read Tangram documentation first in case there is already an available API option.
  • Only use CSS classes for overriding Tangram styles to keep CSS specificity simple.
  • Be aware that class names, styles and HTML structure of Tangram component templates may change with patch versions of Tangram.
  • Do not use !important or inline styles.
  • Ensure your overrides are scoped appropriately and not globally. Use the default view encapsulation settings and be careful when using ::ng-deep.

Overriding responsibly

CSS class names, styles or HTML structure of Tangram component templates are not part of the public API. Therefore, these things may change in any version release, including minor and patch releases.

If you have overridden Tangram styles, this may break your overrides. Therefore, the functionality of your overrides must be covered by appropriate tests. The Tangram squad will run tests in FrEnd, where they exist. If your Trade Me product is using Tangram and you’d like us to run your tests in a similar way, please get in touch with us to discuss this further.

By overriding Tangram component styles, you are responsible for the maintenance responsibility that comes with this decision. For this reason you may choose to update to each version manually instead of automatically update to patch versions when installing packages.

FrEnd specifics

If Tangram squads get failing tests in FrEnd when updating to a new Tangram Web UI package version, we will aim to fix these during the update and let the relevant squads know. If there are too many issues to fix with reasonable turnaround, we will discuss this with your team and make a plan for moving forward.

If tests pass, the Tangram squad won’t investigate any further.

Tangram classes vs your custom classes

When you have direct access to Tangram component HTML tags in your template (i.e. the component selectors and content slots that are part of the public API), adding your own class specific to your component may be the best option for readability and reducing the risk of side effects. This is likely most relevant when adding styles rather than overriding previously set styles from Tangram. There will be times when you need to target the internal template of a Tangram component, and in these cases you will have no option but to use the Tangram class.

.tm-your-component__element .tm-your-component__accordion {
    // your styles
}

Example of using your own class

.tm-your-component__element .o-accordion__item-header {
    // your styles
}

Example of using a Tangram class

Scope / View encapsulation

It is important that you consider what other styles your override may adversely affect. If using Angular’s default emulated view encapsulation this is less of a risk, however if needing to use ::ng-deep to escape this, view encapsulation will no longer help you with reducing style bleed / side effects. Ensure there is at least one class which belongs to your component before the Tangram class in your selector.

.tm-your-component__element ::ng-deep .o-accordion__item-header {
    // your styles
}

You are breaking out of using view encapsulation for anything after the ::ng-deep.

Media queries do not provide encapsulation in this way, so the following code would cause side effects.

@media (min-width: $tg-md-min) {
        .o-accordion__item-header {
        // global styles here! Will affect other accordions
            background-color: $tg-silver-fern-10;
        }

        .o-accordion__item.s-is-active .o-accordion__item-header {
            background-color: inherit;
        }
}
Don't

In this example of accidental global styles view encapsulation has been turned off and these styles will affect any accordions on the page while these styles are present in the document head.

Keeping CSS specificity simple, low and intuitive

To keep CSS specificity as simple as possible, stick to using only CSS classes e.g. .o-accordion__item-header

For this reason we recommend using the class .o-accordion instead of the element selector tg-accordion. Element selectors have less weight in CSS specificity than classes, which can complicate things. Up to your team on this one. See below.

.tm-your-component__element .o-accordion {
    // your styles
}

You wouldn’t need ::ng-deep here if the tg-accordion is directly present in your component template as Tangram uses Hostbinding on it’s components.

Using element selectors for components

You may decide to keep specificity as low as possible and use the element selectors when you are able to. If so, please ensure your team is willing to understand how this affects specificity and when to use the element vs the class selector, as you will likely need to use both depending on the context. This is a specificity win but a loss of consistency and potentially readability and long term maintenance.

.tm-your-component__element tg-accordion {
    // your styles
}

If you choose to use element selectors, it may be harder for some members of the team to calculate the specificity of your selectors.

Inline styles

Inline styles will take precedence over any styles in external stylesheets. They should be avoided. If using inline styles use extreme caution and only use them in special cases (e.g. where you may be dynamically generating CSS on the fly).

!important

Do not use !important. Although in general practice there are cases where it is appropriate (when you are 100% sure that no one will ever need to override this style) this is generally not the case when working on a large project and/or with big teams.

CSS, HTML and Tangram semver

As mentioned above, HTML and CSS for Tangram components are not considered part of the public API and as such are subject to change between any Tangram version including patches. See above for more info on test setup expectations.

Customising modal

When a modal is triggered the modal content is moved to the top of the DOM, and the host element and class are lost. To allow overrides, the host class of the modal is transferred to the dialog element. You will need to prefix your class selector with ::ngDeep if the component file that declares your modal has view encapsulation enabled.

<tg-modal
    *ngIf=”showmodal”
    class=”tm-your-modal-override-class”>
    ...
</tg-modal>
::ng-deep .tm-your-modal-override-class {
    // your custom dialog styles
}

Note the use of ::ng-deep, this is only necessary if the component that declares your modal has view encapsulation enabled.

Proudly made by © 2026 Trade Me Limited