Overriding default styles
This section focuses on how to override the default styles of the Genesis RapidButton
component in your custom MyButton
component.
Using CSS custom properties, you can adjust colours, spacing, typography, and more to align your component with your design system.
The styles in this page including baseStyles
and appearance styles, are specific to buttons - in this case, RapidButton
.
RapidButton
is made up of:
- 'base styles' provide structural and default functional styles for all
RapidButton
instances. - 'appearance styles' are variations layered on top of the base styles to create visually distinct versions of the component, such as primary, danger, neutral, etc.
Here we focus our attention on how to override the appearance styles in our custom MyButton
component - which is what you'll probably be doing most of the time.
You can achieve this by adding or modifying CSS custom properties. In Genesis, design tokens are implemented as custom properties, so you can customize them directly.
Before we move on let's clarify the difference between custom properties and design tokens:
Aspect | Custom Properties (CSS variables) | Design Tokens |
---|---|---|
Definition | Flexible variables defined in component styles. | Semantic variables representing design decisions. |
Purpose | Enable local, flexible customizations. | Promote shared theming and consistency. |
Runtime | Updates Scoped updates for specific components. | Global updates applied to all components. |
Examples | x--button-padding, --border-radius. | --accent-fill-rest, --neutral-foreground-rest. |
Usage | Directly in component styles for local changes. | Exposed as CSS variables for global theming. |
In modern web design systems, including Genesis, design tokens are often implemented as CSS custom properties (CSS variables). This implementation allows the design system to use the flexibility of CSS variables for both consistency and dynamic runtime theming.
Overriding base styles
You can override the structural properties defined in the baseStyles
by adding or modifying the CSS custom properties.
Custom base styles
import { css } from '@genesislcap/web-core';
// Defining base styles for MyButton
export const myButtonStyles = css`
/* Using custom properties for structural adjustments */
:host {
font-weight: 700; /* Custom property (direct value) */
font-size: var(
--type-ramp-base-font-size
); /* Design token for semantic font size */
height: calc(
((var(--base-height-multiplier) + 2) * var(--design-unit)) * 1px
); /* Design tokens for height */
}
.control {
padding: 0 calc((20 + var(--design-unit) * 2 * var(--density)) * 1px); /* Design tokens for padding */
}
`;
Key notes
- Custom Properties:
font-weight: 700
: Directly defines a value.- Design Tokens:
- var(
--type-ramp-base-font-size
): Semantic font size token.- var(
--design-unit
): Represents consistent spacing and sizing across components.
Usage in HTML
<my-button>Custom Base Button</my-button>
Results
- Bold font weight (700).
- Semantic font size (--type-ramp-base-font-size).
- Adjusted height and padding based on design tokens.
Customizing appearance styles in buttons
Appearance styles define visual variations, such as primary, danger, or link. They often rely on design tokens for consistent theming across appearances.
Reusing existing appearances
If the default appearance styles meet your needs, simply use the appearance attribute without any redefinition.
<my-button appearance="neutral">Neutral Button</my-button>
<my-button appearance="primary">Primary Button</my-button>
The neutral
and primary
appearances will behave as defined in baseStyles
:
- Neutral Appearance:
- Background: Transparent neutral fill.
- Border: Neutral border color.
- Text: Neutral foreground.
Customizing the existing appearance
If you want to tweak or redefine the existing appearance (e.g., neutral
), you can override the styles in your custom MyButton
.
import { css } from '@genesislcap/web-core';
import { rapidButtonStyles } from '@genesislcap/rapid-design-system';
const customNeutralAppearance = css`
:host([appearance="neutral"]) {
background: var(
--custom-neutral-background,
#f0f0f0
); /* Custom neutral background */
border: 2px solid var(--custom-neutral-border, #ccc); /* Custom border */
color: var(--custom-neutral-text, #333); /* Custom text color */
}
:host([appearance="neutral"]:hover) {
background: var(--custom-neutral-hover, #e0e0e0); /* Custom hover state */
}
`;
// Combine base styles with custom behaviors
export const myButtonStyles = (
context: ElementDefinitionContext,
definition: FoundationElementDefinition
): ElementStyles =>
css`
${rapidButtonStyles(context, definition)}/* Include base styles */
`.withBehaviors(
// our defined custom behaviour
appearanceBehavior(
"neutral",
customNeutralAppearance
) /* Add custom neutral behavior */
);
The above snippet uses this helper function:
import { ElementStyles, PropertyStyleSheetBehavior } from '@genesis/web-core';
/**
* Behavior that will conditionally apply a stylesheet based on the elements
* appearance property
*
* @param value - The value of the appearance property
* @param styles - The styles to be applied when condition matches
*
* @public
*/
export function appearanceBehavior(value: string, styles: ElementStyles) {
return new PropertyStyleSheetBehavior("appearance", value, styles);
}
Key notes
rapidButtonStyles
: Retain all existing base styles and behaviors for consistency.withBehaviors
: Add or extend behaviors without replacing existing ones.- Custom Neutral Appearance: Override only the styles you want to change.
This approach ensures that your custom
MyButton
inherits the full functionality ofRapidButton
while applying your customizations.
Adding new appearance styles
To define a completely new appearance (e.g., success), use the appearanceBehavior
utility.
const successAppearance = css`
:host([appearance="success"]) {
background: var(--success-fill, #4caf50); /* Green success background */
color: var(--neutral-foreground-rest); /* White text color */
border: 2px solid var(--success-border, #388e3c); /* Dark green border */
}
:host([appearance="success"]:hover) {
background: var(--success-hover-fill, #66bb6a); /* Lighter hover state */
}
`;
export const myButtonStyles = (
context: ElementDefinitionContext,
definition: FoundationElementDefinition
): ElementStyles =>
css`
${rapidButtonStyles(context, definition)}/* Include base styles */
`.withBehaviors(
appearanceBehavior(
"success",
successAppearance
) /* Define the new "success" appearance */
);
Usage in HTML
<my-button appearance="success">Success Button</my-button>
Key points for overriding default styles:
- Base styles
- Use these for structural adjustments (e.g., typography, padding).
- Directly modify or override with CSS custom properties or design tokens.
- Appearance styles
- Reusing: Default appearances (e.g., neutral, primary) are already defined in
baseStyles
. No need to redefine unless necessary.- Customizing: Override existing appearances for unique designs.
- Adding: Define new appearances for entirely new behaviours.