Origami aims to improve design consistency and reduce the time teams spend repeating work. Providing component APIs for customisation helps achieve those aims by allowing components to be used across different contexts and different brands, and to provide flexibility for novel projects which may introduce a more unique style (see Brands & Theme Definitions).
This document aims to help you decide if you should customise a component for your project, show the ways a component may be customised, and demonstrate why other approaches should be avoided.
TL;DR:The first step before customising an Origami component is to ask:
A good place to start is to ask for feedback in the #origami-support Slack channel. The core Origami team, along with the design team, can help identify similar existing styles or help make any relevant component updates to support your usecase without customisation.
Most Origami components are branded to provide a distinct appearance within different contexts. A project sets its brand which applies to all the components which it includes.
Origami maintained brands include:
Taking o-table
as an example, the “core” brand version offers a “row stripes” feature, which uses “core” brand colours such as “paper” and “wheat”:
The “internal” brand version also supports “row stripes” but uses a different colour palette:
The “whitelabel” brand does not support “row stripes” and therefore outputs no styles to support that feature:
Note: The “core” brand used to be known as the “master” brand. You may find references to “master” instead of “core” in older projects.
The “core” brand is the default brand, but your project may use any of the provided Origami brands. The brand is configured once and affects all components used by your project.
To select a brand within your project, see the tutorial for your method of including Origami components:
If your project has access to a component’s Sass API (see the package manager (npm) tutorial) it is possible to customise your chosen brand. For example, at the time of writing, the oTypographySetFont
mixin can be used to customise component fonts. This customises the font used by all components included in your project.
// Incomplete example for demo purposes only
// Set the brand.
$o-brand: 'whitelabel';
// Customise: Tell the o-typography component to use our custom
// font, it will affect all other components which
// are built using o-typography.
@include oTypographySetFont(
$type: 'sans',
$family: 'Comic Sans MS', sans-serif
);
// Customise: Tell the o-header-services we want hot pink
// in the navigation.
@include oHeaderServicesCustomize((
'nav-hover-background': hotpink
));
This is great to create a distinct brand, where a customisation should affect all instances of a component across a project.
If your project is based on the core or internal brand, however, it is more likely that you want to create new variants of a component to use alongside existing ones. For example to output an additional banner style to support a new marketing campaign.
If your project has access to a component’s Sass (see the manual build tutorial) your project may use Sass mixins to customise components by outputting a new variant of that component. A component variant is an instance of a component with modified appearance or functionality.
For instance, at the time of writing, the o-banner
component has an oBannerAddTheme
mixin which provides options for creating a banner variant with customised colour and background image:
@include oBannerAddTheme('my-pikachu-variant', (
background-image: url('https://example.org/pikachu.png'),
background-color: oColorsByName('lemon'),
text-color: oColorsByName('slate'),
button-background-color: oColorsByName('crimson'),
));
Another way to customise components is by applying additional CSS styles within your project. This is not recommended and should be avoided. Applying styles on top of a components style is unreliable and should be avoided as component CSS may change in future minor releases in a way that conflicts with your overrides.
For instance, given a component o-example-component
with the following code:
<!-- Component HTML (o-example-component) -->
<div class="o-example-component">
<div class="o-example-component__content">
Some text and <a href="#">a link</a> in the example component.
</div>
</div>
// Component CSS (o-example-component),
// styles the link text black in colour:
.o-example-component a {
color: black;
}
You could include the component CSS in your project and customise the link colour by adding your own CSS afterward:
// Your Project CSS:
// Override "o-example-component" links
// to be hotpink in colour:
.o-example-component a {
color: hotpink;
}
This would make the link of o-example-component
a hotpink colour in your project. However in a future, potentially minor, release of o-example-component
the component’s CSS could change and visually break your project.
In the below example the component’s CSS selector increases in specificity so the overrides no longer apply:
// Component CSS (o-example-component),
// styles the link text black in colour:
.o-example-component .o-example-component__content a {
color: black;
}
// Your Project CSS:
// Override no longer applies as the component's
// CSS selector is more specific.
.o-example-component a {
color: hotpink; // Does nothing now.
}
To ensure its overrides always apply a project could use overrides with a very high specificity, e.g. with the !important
keyword, but there are further problems with this approach. Using a high specificity to override styles may still visually break if the context around those overrides change. For example if the component introduces a hotpink background the project’s links would become invisible:
// Component CSS (o-example-component),
// styles the link text black in colour:
.o-example-component .o-example-component__content a {
color: black;
background-color: hotpink; // This is new.
}
// Your Project CSS:
// Override no longer applies as the component's
// CSS selector is more specific.
.o-example-component a {
// Still applies, now there is a hotpink foreground
// on a hotpink background, invisible links 😱
color: hotpink !important;
}
In conclusion customising components with un-documented CSS overrides is not recommended. It risks repeated work, a reduction in design consistency, and potentially unreliable code leading to a poor user experience further wasted effort in the future.
The core Origami team, along with the design team, can help identify any existing styles which could be reused, or, help update components to support your project without customisation — so your design is documented, demoed, and more teams can benefit from your work 🎉
When customisation does make sense use a component’s Sass API. Usually this means using Sass to create additional variants for use alongside existing component styles. Alternatively, you can customise your chosen brand to affect all instances of an existing component variant. Avoid CSS overrides as these are unsupported and likely to break.
If you have any questions about customising components, or feature requests, ask them in the #origami-support Slack channel, the core Origami team are here to help 😊