The following set of principles guide our team when naming things in the system. These principles are loosely based on the guidelines from Brad Frost’s CSS Architecture for Design Systems.

Make it modular #

Modularity reduces complexity and improves our system’s reusability. This applies to our naming as well. Different parts of the design system need to be clearly separated.

Keep it consistent #

Consistency enhances clarity and makes our design system more predictable and easy to use. We use the same language and naming wherever possible.

Prioritize legibility #

Developers and designers should be able to understand the system at a glance and understand the structure and purpose of any given part.

Avoid conflicts #

It’s critical to ensure that the design system’s naming doesn’t conflict with other libraries and systems. This is accomplished by the provided namespacing.

Clarity over succinctness #

The system may seem verbose, but it delivers clarity and resilience in exchange. Keeping naming legible and scalable sometimes means sacrificing a shorter syntax.


Colors #

Semantic colors #

Semantic colors carry meaning and imply how and where they should be used. Each semantic color name contains a role and an optional modifier. This accommodates needs such as state, interactivity, and emphasis for different Kesko brands. For example, a component may require color variations for :hover and :focus states.

  • Naming structure: k-color-{role}-{modifier}
  • Role: Each color has a specific role in the Kesko Design System such as theme, highlight, bg, border, text, or status.
  • Modifier: Modifiers are optional and may include variations such as dim, disabled, secondary, on-primary, or success.
  • Usage example:
    • k-color-text-primary
    • k-color-text-on-primary
    • k-color-bg-primary
    • k-color-highlight-primary
    • k-color-status-error
    • k-color-status-info

Primitive colors #

For the Kesko primitive palette, we use numeric scales (100, 200, 300, ..). This provides clear ordering and makes it easier to add values between the existing tokens when necessary.

  • Naming structure:
    • k-color-{name}-{variant}
  • Valid characters: Allowed characters include lowercase ASCII letters (a-z) and hyphens (-). Do not use uppercase characters, symbols, underscores (_) or dots (.). Digits appear only inside a scale step, such as 100 in k-color-orange-100 or 2xl in k-font-size-2xl.
  • Usage example:
    • k-color-orange-100
    • k-color-orange-200
    • k-color-red-100
    • k-color-red-200
    • k-color-blue-100
    • k-color-blue-200
  • Categories:
    • Orange
    • Beige
    • Blue
    • Green
    • Purple
    • Red
    • Teal
    • Yellow
    • Neutral
    • Neutral Dark
  • Tints and shades:
    • 100
    • 200
    • 300
    • 400
    • 500
    • 600
    • 700
    • 800
    • 900
    • 1000
    • 1100
    • 1200

Components #

Kesko’s component library ships React components alongside matching CSS classes and <k-*> elements, so consumers without React can reach the same visual styling through @kesko/css.

React components #

  • Format: PascalCase, for example Button, Spinner, Stack, VisuallyHidden.
  • Noun rather than verb: Components are not actions, they are conceptually “things.” Prefer Animation over Animating.
  • Meaningful: Not over specific, not overly abstract.
  • Short: Maximum of 2 words. Prefer 1 word when possible.
  • Pronounceable: We want to be able to talk about them.
  • Usage examples:
    • <Button />
    • <Input />
    • <Spinner />
    • <Stack />
    • <VisuallyHidden />

Custom elements #

  • Naming structure: {prefix}-{name}.
  • Prefix: Component names always start with a prefix and a hyphen. For example k-stack or k-spinner. “K” stands for “Kesko”. Prefixing is critical to ensure that our naming doesn’t conflict with other systems.
  • Noun rather than verb: Components are not actions, they are conceptually “things.” It is better to use nouns instead of verbs, such as <k-animation> instead of <k-animating>.
  • Must contain a hyphen: Must have at least one hyphen (-), such as k-element.
  • Valid characters: Allowed characters include lowercase ASCII letters (a-z) and hyphens (-). Do not use uppercase characters, symbols, underscores (_) or dots (.). Digits appear only inside a scale step, such as 100 in k-color-orange-100 or 2xl in k-font-size-2xl. Meaningful: Not over specific, not overly abstract.
  • Short: Maximum of 2 words after k- prefix.
  • Pronounceable: We want to be able talk about them.
  • Custom element spec compliant: Don’t use the following reserved names:
    • annotation-xml
    • color-profile
    • font-face
    • font-face-src
    • font-face-uri
    • font-face-format
    • font-face-name
    • missing-glyph
  • Usage examples:
    • <k-alert>
    • <k-badge>
    • <k-stack>
    • <k-icon>
    • <k-divider>
    • <k-visually-hidden>

CSS Properties #

  • Naming structure: var(--k-{component}-{property}) for public properties.
  • Private properties: var(--_k-{component}-{property}) for private properties.
  • Prefix: --k- prefixes a public custom property, meaning developers can use it to fine tune components. --_k- prefixes a private custom property, which is reserved for internal design system use.
  • Usage examples:
    • var(--k-button-radius)
    • var(--k-button-bg)
    • var(--k-button-text)
    • var(--k-button-bg-hover)

Design Tokens #

Designers and developers should be able to understand the purpose of a design token at a glance. To make sure naming stays consistent and legible, we follow these guidelines for design tokens:

  • Naming structure:
    • {prefix}-{category}-{name}-{variant}
    • {prefix}-{category}-{subcategory}-{name}-{variant}
  • Prefix: Design token names always start with a prefix and a hyphen. For example k-color-theme-primary or k-font-size-xl. “K” stands for “Kesko”. Prefixing is critical to ensure that our naming doesn’t conflict with other systems.
  • Noun rather than verb: Design Tokens are not actions, they are conceptually “things.” It is better to use nouns instead of verbs, such as k-color-success instead of k-color-succeed.
  • Valid characters: Allowed characters include lowercase ASCII letters (a-z) and hyphens (-). Do not use uppercase characters, symbols, underscores (_), dots (.), or digits (0-9).
  • Default value: When naming sizes, {prefix}-{category}-{name}-md is always the default value. For other categories, such as colors, we use {prefix}-{category}-{name}-base convention.
  • Shorthands: A bare group name is a shorthand for that group's default token: --k-space stands for --k-space-md and --k-color-text for --k-color-text-base. Shorthands are emitted only in CSS, SCSS and LESS as references to the full name, and they are never written into the token source; the full list lives in shorthands.json in @kesko/tokens.
  • Categorization: Design token names always include at least one category, like color,font, or similar. If it makes sense, you can also include a subcategory, for example k-font-size-xl or k-color-status-error.
  • Usage examples:
    • k-color-theme-primary
    • k-color-text-base
    • k-color-text-link
    • k-color-text-on-primary
    • k-color-bg-base
    • k-color-bg-primary
    • k-color-status-error
    • k-color-status-success
    • k-font-size-xl
    • k-font-weight-bold
    • k-font-family-sans
    • k-font-leading-md
  • Font weights:
    • base (alias of regular, the default weight)
    • black
    • bold
    • medium
    • regular
  • Categories and subcategories:
    • Color
      • Theme
      • Highlight
      • Bg
      • Border
      • Overlay
      • Status
      • Text
      • Orange
      • Beige
      • Blue
      • Green
      • Purple
      • Red
      • Teal
      • Yellow
      • Neutral
      • Neutral Dark
      • Brand
    • Font
      • Family
      • Leading
      • Size
      • Weight
    • Layer
    • Motion
      • Duration
      • Easing
    • Radius
    • Shadow
    • Size
      • Border
    • Space

Icons Draft #

Our design system styles follow a simple icon naming structure based on {name}-{variant}-{suffix} format.

  • Noun rather than verb: Icons are not actions, they are conceptually “things.” Prefer animation over animating.
  • Context free: Icons are used in multiple contexts. Name them based on what they represent, not how they should be used.
  • Short: Maximum of 3 words. Prefer 1 word when possible.
  • Pronounceable: We want to be able to talk about them.
  • Naming structure:
    • {name}-{variant}-{suffix}
  • Suffix: Some icons may be tailored for use in e.g. specific sizes. This can be indicated with a suffix: arrow-left-sm.
  • Usage examples:
    • arrow-left
    • arrow-right
    • engine
    • home

Sizes #

Kesko Design System defines semantic sizes using the t-shirt metaphor. This makes it possible for anyone, technical or non-technical person, to understand the differences and how they relate to each other at a glance.

  • Keep it consistent and short: Always use the short form version (sm, md, lg, xl) when naming things. This makes it quicker for developers and designers to reference the sizes.
  • Default size: md is always the default value.
  • Larger than default: When you want to define a size larger than medium, use lg, xl, 2xl, 3xl.
  • Smaller than default: When you want to define a size smaller than medium, we use sm, xs, 2xs, 3xs.
  • Icon size: Icon sizes are indicated with a suffix, such as -sm.
  • Usage example:
    • k-font-size-2xl
    • k-font-size-xl
    • k-font-size-lg
    • k-font-size-md
    • k-font-size-sm
    • arrow-left-sm

Styles #

Our design system styles follow a simple naming structure based on .{prefix}-{name}-{modifier} format.

  • Naming structure: .{prefix}-{name}-{modifier}.
  • Prefix: Styles always start with a prefix and a hyphen. For example .k-button or .k-input. “K” stands for “Kesko”. Prefixing is critical to ensure that our naming doesn’t conflict with other systems.
  • Modifiers: Modifier is a flag on an element. Use them to change appearance or behavior. For example .k-button-primary or .k-button-plain.
  • Status: Status is a modifier on the component class, .{prefix}-{name}-{status}. For example .k-button-loading.
  • Usage examples:
    • .k-button
    • .k-input
    • .k-button-plain
    • .k-button-loading

Properties #

When naming component properties, it’s important to pay attention to the consistency between the different components so that the API stays as predictable as possible. The same conventions apply to component properties in Figma.

React props #

  • Mirror HTML where possible: When an equivalent HTML attribute exists, use the same name — e.g. disabled, size, type. This makes the React API read naturally alongside native element properties and is especially important for form components.
  • Format: camelCase for multi-word names (e.g. onClick, iconOnly), lowercase for single-word names (e.g. size, variant). Event handlers follow the on{Event} pattern (e.g. onClick, onFocus).
  • Meaningful: Not over specific, not overly abstract.
  • Short: Maximum of 2 words. Prefer 1 word when possible.
  • Pronounceable: We want to be able to talk about them.
  • Sizes: Use a property called size and follow our sizes guideline for naming.
  • Disabled state: Use a boolean property named disabled.
  • Style variants: Use a property called variant for style variants such as primary, secondary, or plain.
  • Reserved names: Avoid property names that collide with React’s own reserved names:
    • children
    • className
    • style
    • ref
    • key
    • dangerouslySetInnerHTML

Custom element attributes #

  • Generic rules: Follow the HTMLElement API to make sure the developer- and LLM-facing APIs are as predictable as possible. This is especially important for form components.
  • Valid characters: Allowed characters include lowercase ASCII letters (a-z) and hyphens (-). Do not use uppercase characters, symbols, underscores (_), dots (.), or digits (0-9).
  • Meaningful: Not over specific, not overly abstract.
  • Short: Maximum of 2 words. Prefer 1 word when possible.
  • Pronounceable: We want to be able to talk about them.
  • Sizes: Use a property called size and follow our sizes guideline for naming.
  • Disabled state: Use a boolean property nameddisabled.
  • Style variants: Use a property called variant for style variants such as success, error and such.
  • Reserved names: You should be careful that the property names do not conflict with existing standardized prototype members. Reserved names include:
    • align
    • title
    • lang
    • translate
    • dir
    • dataset
    • hidden
    • tabIndex
    • accessKey
    • draggable
    • spellcheck
    • autocapitalize
    • contentEditable
    • isContentEditable
    • inputMode
    • offsetParent
    • offsetTop
    • offsetLeft
    • offsetWidth
    • offsetHeight
    • style
    • innerText
    • outerText
    • oncopy
    • oncut
    • onpaste
    • onabort
    • onblur
    • oncancel
    • oncanplay
    • oncanplaythrough
    • onchange
    • onclick
    • onclose
    • oncontextmenu
    • oncuechange
    • ondblclick
    • ondrag
    • ondragend
    • ondragenter
    • ondragleave
    • ondragover
    • ondragstart
    • ondrop
    • ondurationchange
    • onemptied
    • onended
    • onerror
    • onfocus
    • onfocusin
    • onfocusout
    • oninput
    • oninvalid
    • onkeydown
    • onkeypress
    • onkeyup
    • onload
    • onloadeddata
    • onloadedmetadata
    • onloadstart
    • onmousedown
    • onmouseenter
    • onmouseleave
    • onmousemove
    • onmouseout
    • onmouseover
    • onmouseup
    • onmousewheel
    • onpause
    • onplay
    • onplaying
    • onprogress
    • onratechange
    • onreset
    • onresize
    • onscroll
    • onseeked
    • onseeking
    • onselect
    • onstalled
    • onsubmit
    • onsuspend
    • ontimeupdate
    • ontoggle
    • onvolumechange
    • onwaiting
    • onwheel
    • onauxclick
    • ongotpointercapture
    • onlostpointercapture
    • onpointerdown
    • onpointermove
    • onpointerup
    • onpointercancel
    • onpointerover
    • onpointerout
    • onpointerenter
    • onpointerleave
    • onselectstart
    • onselectionchange
    • nonce
    • click
    • focus
    • blur
    • namespaceURI
    • prefix
    • localName
    • tagName
    • id
    • className
    • classList
    • slot
    • attributes
    • shadowRoot
    • assignedSlot
    • innerHTML
    • outerHTML
    • scrollTop
    • scrollLeft
    • scrollWidth
    • scrollHeight
    • clientTop
    • clientLeft
    • clientWidth
    • clientHeight
    • attributeStyleMap
    • onbeforecopy
    • onbeforecut
    • onbeforepaste
    • onsearch
    • previousElementSibling
    • nextElementSibling
    • children
    • firstElementChild
    • lastElementChild
    • childElementCount
    • onfullscreenchange
    • onfullscreenerror
    • onwebkitfullscreenchange
    • onwebkitfullscreenerror
    • setPointerCapture
    • releasePointerCapture
    • hasPointerCapture
    • hasAttributes
    • getAttributeNames
    • getAttribute
    • getAttributeNS
    • setAttribute
    • setAttributeNS
    • removeAttribute
    • removeAttributeNS
    • hasAttribute
    • hasAttributeNS
    • toggleAttribute
    • getAttributeNode
    • getAttributeNodeNS
    • setAttributeNode
    • setAttributeNodeNS
    • removeAttributeNode
    • closest
    • matches
    • webkitMatchesSelector
    • attachShadow
    • getElementsByTagName
    • getElementsByTagNameNS
    • getElementsByClassName
    • insertAdjacentElement
    • insertAdjacentText
    • insertAdjacentHTML
    • requestPointerLock
    • getClientRects
    • getBoundingClientRect
    • scrollIntoView
    • scroll
    • scrollTo
    • scrollBy
    • scrollIntoViewIfNeeded
    • animate
    • computedStyleMap
    • before
    • after
    • replaceWith
    • remove
    • prepend
    • append
    • querySelector
    • querySelectorAll
    • requestFullscreen
    • webkitRequestFullScreen
    • webkitRequestFullscreen
    • part
    • createShadowRoot
    • getDestinationInsertionPoints
    • nodeType
    • nodeName
    • baseURI
    • isConnected
    • ownerDocument
    • parentNode
    • parentElement
    • childNodes
    • firstChild
    • lastChild
    • previousSibling
    • nextSibling
    • nodeValue
    • textContent
    • hasChildNodes
    • getRootNode
    • normalize
    • cloneNode
    • isEqualNode
    • isSameNode
    • compareDocumentPosition
    • contains
    • lookupPrefix
    • lookupNamespaceURI
    • isDefaultNamespace
    • insertBefore
    • appendChild
    • replaceChild
    • removeChild