Docs
Search

CSS Methodology

This page covers the CSS design principles behind Lism.

Lism CSS Layer Structure

To address the common problem of CSS specificity becoming overly complex, Lism defines a clear layer structure.

LayerRole
SettingsSASS configuration variables, mixins, and other constructs that do not directly output styles.
Base
lism-base
The layer for Reset CSS, token definitions, variable sets, and initial element styles.
set--{name} classes are also defined here.
Block
lism-block
The layer where you define base styles for common, reusable site-wide parts (b--{name}) inside @layer lism-block. The core only declares the layer order and ships no styles of its own here.
Since it sits below the layers that follow, explicitly added classes (is-- / has-- / l--, etc.) always win over the b-- base styles.
Trait
lism-trait
The layer for classes that declaratively attach a role or feature to an element (is--{name}, has--{name}).
Primitives
lism-primitive

The layer for Primitives — the building blocks for composing layouts.
l--{layout} and a--{atomic} are defined here.

Custom
lism-custom
A customization layer for overriding existing Lism classes, or for placing custom classes (c--{name}).
Utility
lism-utility
The layer for utility classes with a clear purpose or style (u--{name}).
Props
-
Property Classes (-{prop}:{val}) tied to individual CSS properties.
This group is the only one placed outside of layers, giving it higher specificity while still allowing reasonable coexistence with external CSS.

Design Tokens

CSS custom properties are defined for key CSS properties — typography, spacing, color, shadows, and more — using stepped preset values and semantic keywords.

Using tokens brings consistency to the design, makes the intent behind property usage more readable, and improves maintainability by allowing site-wide adjustments to be made simply by updating token values.

See the Tokens reference page for details.

CSS Class Design

This section explains the design rationale behind the core class groups in Lism CSS.

Set Class

Set Classes are classes defined within the lism-base layer. They are used for HTML element base styling or for setting variables.

Category Format Example
Set Class set--{name} set--plain,
set--hov,
set--bxsh

Primitive Class

Primitive Classes are small building blocks for composing layouts.

These are further categorized into several types:

Category Format Example
Layout Primitives
Primitives that serve as layout building blocks
l--{name} l--grid,
l--columns
Atomic Primitives
The smallest layout unit primitives
a--{name} a--divider,
a--icon

Primitive Classes are standalone — they have no variations or child element classes. Only Block Class (b--) and Custom Class (c--), described later, follow a BEM structure.

Combining Primitive Classes follows these rules:

Combination Allowed Notes
l-- × l-- Not allowed Same category cannot be combined
a-- × a-- Not allowed Same category cannot be combined
l-- × a-- Discouraged Not typically combined on the same element

Trait Class

Trait Classes declare a role on an element or attach a feature to it.

Category Format Example
is-- Trait
Declares a role (“is a …”) on an element
is--{name} is--container,
is--wrapper,
is--layer,
is--boxLink
has-- Trait
Attaches a feature (“has a …”) to an element
has--{name} has--transition,
has--gutter,
has--snap

The criteria for choosing between is-- and has-- are:

is-- has--
Meaning “is a …” (role / existence declaration) “has a …” (feature attachment)
CSS variables Not required Required (provides customization points)

See the naming guide for the detailed decision criteria and usage guidelines.

Block Class

Block Classes prefixed with b-- are for common, reusable, site-wide base parts (button, badge, card-level components), defined on the premise that “base styles are managed in CSS”.

@layer lism-block {
.b--btn { /* ... */ }
}

The core lism-css only provides the dedicated layer (@layer lism-block) and does not ship any b-- classes.

Use b-- only for parts that satisfy all three of the following:

  1. It’s a common part reused across multiple pages or multiple places on the site.
  2. It’s a part where a single class should define nearly the entire base style.
  3. Its granularity is a self-contained, button/badge/card-level part.

If a part doesn’t meet all of these, use c-- instead.

b-- classes can have a BEM structure (Block / Modifier / Element), each defined in the following format:

Category Format Example
Block
The base class
b--{name} b--btn,
b--card
Modifier
Variation
b--{name}--{modifier} b--btn--outline
Element
Child element
b--{name}_{element} b--card_header,
b--card_body

Modifiers are used alongside the Block class, e.g. .b--btn.b--btn--outline.
Elements use a single underscore (_) as the separator.

Combining different Blocks (.b--xxx.b--yyy) is generally not allowed.

  • b-- can be combined with other classes. Not everything has to be written on the CSS side.
  • A b-- part can own its layout styles in CSS, or be built on the premise of combining it with l-- classes — both approaches work.
  • For breakpoint switches (e.g. -p_sm), hover styles, and other exceptional adjustments, Property Classes are a good fit.

Custom Class

Custom Classes prefixed with c-- are custom classes you’re free to define beyond the core’s built-in classes.
The name corresponds to the lism-custom layer, and you can use it for any granularity — components, zoning, page-specific elements, and more.

  • The basic approach is to compose their styles mainly from the other classes Lism provides.
  • Complex styles that Property Classes and the like can’t cover are defined in @layer lism-custom.
  • You can also use a c-- class purely as a name that shows what part it is, without writing any CSS.
@layer lism-custom {
.c--header { /* ... */ }
.c--pricing { /* ... */ }
}

Names use camelCase after the prefix (see the naming guide). For page-specific elements, including the page’s slug or similar in the name — as in c--landingHero — makes it clear from the name alone where the element belongs.

Also, c-- classes can follow the same BEM notation and combination rules as Block Class, giving them a BEM structure (Block / Modifier / Element).

Utility Class

Utility classes with a clear decorative or functional purpose are defined as follows:

Category Format Example
Utility Class u--{name} u--cbox,
u--trim

Property Class

In Lism CSS, classes that correspond to a single CSS property are defined as Property Classes.

Classes are provided for key properties, covering commonly used values and dedicated token values, with responsive support built in.

Property Classes come in three formats:

Format Description Example
-{prop}:{value} Classes for applying the primary values or token values for each property -fz:l,
-d:none
-{prop} A class that receives the --{prop} variable -p,
-fz
-{prop}_{bp} A class that receives the --{prop}_{bp} variable -p_sm,
-p_md

* Classes for all CSS properties are not available by default. * Breakpoint-responsive classes are also only available by default for a select subset of key properties.

See the Property Class reference page for the full list.

Responsive Property Classes

The -{prop}_{bp} class format combined with the --{prop}_{bp} variable format enables responsive styling.

↓
Practical usage example
BOX
Resize
<div class="-p:20 -p_sm -p_md -bd" style="--p_sm: var(--s40); --p_md: var(--s50)">BOX</div>

See the Responsive styling guide for details.

Adding and overriding existing classes

When you add your own classes that match one of Lism CSS’s existing class categories (set--, is--, has--, l--, a--, u--, -{prop}:{value}), use the same prefix and add them to the corresponding definition layer.

If you need to override an existing Lism class, do so within that same layer.

set-- overrides belong in @layer lism-base. Place them after the Lism main.css is loaded, or boost the specificity by repeating the class name (e.g. .set--xxx.set--xxx) to ensure the override takes effect.

@layer lism-base {
/* New addition */
.set--hoge { /* ... */ }
/* Override */
.set--plain.set--plain { /* ... */ }
}

Using data attributes for dynamic state

For state management that is dynamically toggled by JavaScript, use data attributes.

Example: [data-opened], [data-active]

© 2026 Lism CSS.