Skip to content

Flight rules

Edit on GitHub

Flight rules are the hard-won knowledge recorded by NASA astronauts for handling specific situations — what to do when X happens, and why. These are ours.

Whether you’re migrating from VCC UI, integrating @volvo-cars/css into an existing app, or starting fresh, this page helps you make confident decisions.


Some granular spacing and sizing values from older tokens have been deprecated. When you encounter them, round up to the nearest available value.

<!-- ✅ Do: use the base font size or a utility class -->
<p>Base font size is now 16px</p>
<p class="font-16">Also available as a utility class</p>
<!-- ❌ Don't: force legacy pixel values -->
<p style="font-size: 14px">Don't do this</p>

Some component behaviours have been intentionally changed, and escape hatches that existed in VCC UI have been removed. If you can’t reproduce the exact behaviour of a VCC UI component, that may be by design.

Example: Icon buttons now have a fixed minimum size to comply with accessibility touch-target specifications. Don’t override their size to match older designs.


It’s not practically or economically viable to migrate everything at once. Adding new CSS components alongside existing VCC UI ones will introduce minor visual differences.

This is acceptable. We don’t have a perfectly consistent UI experience today. Moving towards @volvo-cars/css is two steps forward for every one step back.


If you receive designs that use old tokens, VCC UI components, or “snowflake” values that don’t exist in the design system, query that with your designer. Advocate strongly for maintaining parity with the design system whenever you find yourself writing custom styles.


When you do need a custom style — and sometimes you will — here are the recommended approaches, in order of preference:

Best for styles reused by multiple components within your application.

your-app/utilities.css
.app-card-shadow {
box-shadow: 0 2px 8px rgb(0 0 0 / 0.08);
}
<!-- Used alongside @volvo-cars/css classes -->
<div class="flex bg-secondary app-card-shadow">...</div>

Best for components that require complex styling not achievable with utility classes alone. Styles are scoped to the component and code-split automatically.

card.module.css
.card {
/* complex styles here */
}

Best for one-off values that are unlikely to be reused.

<div className="flex p-16" style={{ backgroundImage: `url(${imageUrl})` }} />

The design system adds consistent keyboard focus styles to all focusable elements by default. Never override the focus outline. If you need to make a non-interactive element focusable, use tabindex="0" — the focus ring will appear automatically.


Style element states using standard HTML and ARIA attributes instead of toggling class names. This keeps the visible appearance and accessibility state in sync.

<!-- ✅ Do: use aria attributes -->
<a href="#" aria-current="page">Current page</a>
<!-- ❌ Don't: use state class names -->
<a href="#" class="nav-link--active">Current page</a>

Learn more in Interaction states.


If you find yourself writing a lot of custom CSS to make something work, step back and ask:

  1. Is there an existing component or pattern that solves this? Check the component docs.
  2. Is this a one-off or will it be reused? If reused, consider proposing it to the design system team.
  3. Does this deviate from the design system intentionally? If so, confirm with your designer that the deviation is justified.

We’re available for any questions. Find us on Slack in #design-system-web.