Text Case Format Converter: Code Examples

Convert any text between 14 case formats instantly. Nothing leaves your browser.

ZERO UPLOAD · ALL LOCAL
  1. Type or paste text into the input box — all 14 conversions appear instantly.
  2. The Character Case Formats section shows 5 character-level transformations.
  3. The Word Case Formats section shows 9 word-level transformations.
  4. Use the Copy buttons to grab any individual result.
  5. Click "Use as input" to chain conversions (e.g. snake_case → camelCase → kebab-case).

INPUT TEXT

CHARACTER CASE FORMATS

lower case
UPPER CASE
Capitalized Case
aLtErNaTiNg cAsE
InVeRsE CaSe

WORD CASE FORMATS

camelCase
PascalCase
snake_case
SCREAMING_SNAKE
kebab-case
dot.case
path/case
sentence case
Title Case

snake_case Naming Conventions in Python

Inside every production Python codebase, snake_case is the default. PEP 8 (the official Python style guide, authored by Guido van Rossum in 2001) specifies snake_case for all variables, function names, method names, and module names.1 Deviating from it is not a syntax error, but it signals unfamiliarity with the language to anyone reading your code.

Building on this, Python's naming conventions are deliberately consistent: one style for most identifiers (snake_case), one for constants (SCREAMING_SNAKE_CASE), and one for classes (PascalCase). Knowing which to use where prevents the most common naming mistakes before they reach code review.

PEP 8 specification

PEP 8 specifies: variables and function names use snake_case; class names use PascalCase (called "CapWords" in PEP 8); module and package names use short, all-lowercase names, preferably with underscores when readability requires it; constants use SCREAMING_SNAKE_CASE.1 Furthermore, instance method names and class method names use snake_case with "self" or "cls" as the first parameter. Private attributes use a leading underscore: _private_method. Name-mangled attributes use a double underscore: __private (Python rewrites these to avoid subclass conflicts).2 The __init__.py file that marks a directory as a Python package follows the dunder convention, and special module-level variables like __name__, __version__, and __all__ use the same double-underscore pattern. PEP 8 also specifies that function annotations (type hints) follow the same snake_case convention as the variables they annotate.

Where snake_case appears in the Python ecosystem

The standard library follows PEP 8 entirely. SQLAlchemy ORM models map Python snake_case attribute names directly to database column names. FastAPI routes accept snake_case path parameters and query string parameters. Django model fields, form fields, and template tags use snake_case. Pytest test function names are snake_case: test_user_login, test_order_creation. Building on this, type annotations in Python (introduced in PEP 484) follow the same convention: annotated variables and function parameters are snake_case. The asyncio module, pathlib, dataclasses, and every other module added to the standard library in Python 3.x follows snake_case for all public functions and variables. Even third-party packages published to PyPI overwhelmingly follow PEP 8, making snake_case the universal expectation for any Python code that will be shared or reviewed by other developers.

Framework and library conventions

Django, Flask, and FastAPI all follow PEP 8 in their public APIs and generated code. SQLAlchemy column names in ORM models are snake_case by default, with the column name matching the Python attribute unless explicitly overridden. Data science libraries (pandas, NumPy, scikit-learn) use snake_case for all public API methods. Consequently, when contributing to any of these libraries or building plugins for them, using camelCase or PascalCase for non-class identifiers will fail style checks and be rejected in code review. The black formatter enforces PEP 8 naming indirectly by refusing to format files with syntax errors, and the pep8-naming flake8 plugin catches naming violations directly. When you run flake8 --select=N on a Python project, every snake_case violation produces a specific error code (N801 for class names, N802 for function names, N803 for argument names),3 making it easy to automate enforcement in CI.

snake_case in Python type annotations and variable declarations

Type annotations in Python follow the same snake_case rules as untyped identifiers. Adding type hints to a variable or function parameter does not change the naming convention; PEP 484 and PEP 526 both follow PEP 8 naming rules. The annotation specifies what type a value should be, but the identifier that holds that value remains snake_case because the annotation is metadata attached to the name rather than a transformation of the name itself.

Annotated function parameters and return types

A function parameter annotated with a type uses snake_case: def create_user(user_id: int, first_name: str) -> UserProfile. The annotation does not change the identifier name. Developers coming from Java or C# sometimes capitalize variable names when they add type annotations, a habit carried from statically typed languages where types have PascalCase names. In Python, the parameter stays snake_case regardless of the type annotation or the type's own name.

The distinction matters most when a type and its value sit next to each other in the same signature. The parameter keeps snake_case while the annotation carries a PascalCase type name, and a reader who expects both to match can misread the parameter as a type. Static analysis tools like mypy and pyright read the annotation as the type and the identifier as the variable, so they never confuse the two, but human reviewers sometimes do. Keeping the parameter lowercase regardless of the annotation avoids that moment of doubt during review and keeps Python signatures consistent with every other function in the module.

TypedDict keys and dataclass field names

TypedDict class keys and @dataclass field names both follow snake_case, since they map directly to dictionary keys and instance attribute names. class UserSchema(TypedDict): user_id: int follows PEP 8, while class UserSchema(TypedDict): userId: int does not. Pydantic models follow the same rule: field names are snake_case by default, and Pydantic provides an alias_generator configuration to expose them under a different name in JSON output. Using snake_case field names in your data model and configuring aliases for the API layer keeps the Python code PEP 8 compliant while producing camelCase JSON for JavaScript consumers.

Pydantic model field naming and alias configuration for APIs

Pydantic is the dominant data validation library in Python web development, used by FastAPI and increasingly by Django REST Framework. Its field naming conventions follow PEP 8, but its alias system provides a clean way to serve camelCase JSON without violating Python style rules. Understanding this alias mechanism before building your first API model prevents the common mistake of choosing between snake_case Python and camelCase JSON as an either-or decision when Pydantic lets you satisfy both conventions simultaneously.

Setting model_config with alias_generator = to_camel (using pydantic.alias_generators.to_camel) produces camelCase keys in the JSON response while keeping snake_case attribute names internally.4 Your Python code uses user.user_id; your API returns "userId"; no naming convention is violated in either direction. The populate_by_name=True setting in the same config block ensures that your Python code can initialize models using snake_case names while the API layer translates them transparently to camelCase for external consumers.

Why this matters before you write your first model

Discovering that FastAPI's default JSON output uses snake_case only after your JavaScript frontend is built means a refactor of either the frontend types or the API serialization layer. Knowing the Pydantic alias pattern before writing your first model prevents that refactor. Configure alias_generator at the model level or in the global model_config, verify the output with a test request, and your API serves camelCase JSON while your Python code stays idiomatic.

When to use this

Use snake_case for all Python variables, function names, method names, and module names. Use SCREAMING_SNAKE for module-level constants. Use PascalCase only for class names.

Notes

Python does not enforce PEP 8 at the interpreter level,any valid identifier works regardless of case. Tools like flake8, pylint, and black enforce style conventions during CI. The black formatter does not rename identifiers but flags inconsistent capitalization in combination with the pep8-naming plugin.

Examples

Variable and function names (snake_case)

user_id = 42
first_name = "Alice"

def get_user_profile(user_id: int) -> dict:
    return {"id": user_id}

Constants and class names (SCREAMING_SNAKE and PascalCase)

MAX_RETRIES = 3
DATABASE_URL = "postgresql://localhost/mydb"

class UserProfile:
    def __init__(self, user_id: int):
        self.user_id = user_id

Verify with the Text Case Format Converter tool.

Variable and function names (snake_case)

user_id = 42
first_name = "Alice"

def get_user_profile(user_id: int) -> dict:
    return {"id": user_id}
Sources
  1. 1.

    Guido van Rossum, Barry Warsaw, and Alyssa Coghlan, "PEP 8 – Style Guide for Python Code," python.org, July 2001. https://peps.python.org/pep-0008/

  2. 2.

    Python Software Foundation, "6. Expressions — Python 3.14.6 documentation," docs.python.org, accessed June 2026. https://docs.python.org/3/reference/expressions.html#private-name-mangling

  3. 3.

    PyCQA, "pep8-naming: Naming Convention checker for Python," github.com, accessed June 2026. https://github.com/PyCQA/pep8-naming

  4. 4.

    Pydantic, "Alias," docs.pydantic.dev, accessed June 2026. https://docs.pydantic.dev/latest/concepts/alias/

FAQ

camelCase Naming Conventions in JavaScript

When a Python API returns snake_case JSON and your JavaScript frontend expects camelCase properties, every field name is a potential mismatch. The conversion happens somewhere, or bugs appear at runtime. Understanding how JavaScript naming works, and where the boundaries with other formats lie, prevents those mismatches before they reach production.

The boundary problem: snake_case APIs meeting camelCase frontends

The W3C DOM API uses camelCase for all property names and methods: getElementById, addEventListener, innerHTML.1 This convention predates JavaScript style guides and was established by the browser APIs themselves. The ECMAScript specification follows the same pattern for all built-in method names: Array.prototype.forEach, Object.prototype.hasOwnProperty. Building on this, every JavaScript runtime (browser, Node.js, Deno, Bun) inherits these camelCase APIs, making camelCase the de facto standard for the language's own interfaces before any community style guide was written. When a Python or Ruby backend returns snake_case JSON and your JavaScript frontend expects camelCase properties, every field name is a potential mismatch. The conversion happens somewhere in your code, or bugs appear at runtime as undefined values that are silently ignored.

Where JavaScript naming appears in the browser and Node.js

The browser's DOM style object uses camelCase for CSS properties: element.style.backgroundColor, element.style.fontSize.2 React's synthetic event handlers are camelCase: onClick, onSubmit, onChange.3 Node.js built-in modules use camelCase for their exports: fs.readFile, path.resolve, http.createServer. npm package names follow kebab-case (a separate convention for file system identifiers), but the imported module variable uses camelCase. Consequently, const expressApp = require('express-app') is the standard pattern. The window object and globalThis expose all browser APIs in camelCase, and the Web Workers API, the Fetch API, and the Web Storage API all follow the same convention. Even the newer navigator.userAgentData and scheduler.postTask APIs maintain camelCase naming, ensuring consistency across decades of web platform evolution.

TypeScript additions to JavaScript conventions

TypeScript adds interface and type alias names, which follow PascalCase. Enums use PascalCase for the enum name and PascalCase for members (per the TypeScript Handbook).4 Generics use single uppercase letters (T, K, V) for simple cases or PascalCase for descriptive names (TItem, TResponse). Building on this, TypeScript decorators follow camelCase when they are used as functions: @injectable(), @controller("/api"). React component prop types are PascalCase with "Props" suffix: UserCardProps, ButtonProps. TypeScript utility types like Partial<T>, Pick<T, K>, and Omit<T, K> use PascalCase, following the same convention as class and interface names. The declare keyword for ambient type definitions follows the same camelCase rules for variables and functions, ensuring that type declarations match the runtime naming of the JavaScript code they describe.

ESLint rules for enforcing camelCase naming in JavaScript and TypeScript

Linting makes camelCase a checked constraint rather than just a convention. Understanding the relevant ESLint rules helps you configure enforcement at the right level of strictness for your project. Configuring these rules before your first commit prevents naming inconsistencies from accumulating in the codebase, because once a non-camelCase identifier is committed, removing it requires a coordinated rename across every file that references it.

The camelcase rule and its limitations

ESLint's built-in camelcase rule checks variable, parameter, and property names.5 It flags user_id and first_name but allows SCREAMING_SNAKE names for constants. The rule has an allow array for exceptions, useful when consuming a third-party API that uses snake_case keys and you want to name a local variable after the raw field. Configure allow: ["raw_field_name"] for those specific cases rather than disabling the rule globally.

The rule also accepts an ignoreDestructuring option to skip checks on destructured property names, which is helpful when you cannot control the incoming key names but still want to enforce camelCase for your local bindings. Setting ignoreDestructuring: true lets you write const { user_id } = response without a lint warning while keeping the rest of your code compliant.

@typescript-eslint/naming-convention for fine-grained control

The @typescript-eslint/naming-convention rule provides per-identifier-type configuration.6 You can require camelCase for variables, PascalCase for classes and interfaces, SCREAMING_SNAKE for constants, and camelCase with a leading underscore for private class members, all in a single rule configuration. This is the recommended approach for TypeScript projects because it handles the full range of identifier types that the simpler camelcase rule does not cover. Most shared ESLint config packages (Airbnb, Google, StandardJS) include a version of this configuration by default.

Managing camelCase conventions at JavaScript system boundaries

JavaScript codebases interact with external systems that may not follow camelCase. The boundary between your JavaScript code and those systems is where convention violations most often appear. A Python backend sending snake_case JSON, a CSS stylesheet using kebab-case property names, and an HTTP API returning Train-Case headers all introduce naming formats that conflict with JavaScript conventions, and each boundary requires a different conversion strategy to keep the JavaScript codebase internally consistent.

A common pattern is to write a transformation function at the data access layer that converts incoming snake_case API response fields to camelCase before the data reaches component or business logic code. The camelcase-keys npm package automates this for entire response objects, recursively converting all keys. Running your API response field names through this converter first gives you the expected output to verify the library produces the same result.

Writing selective mapping objects at the data layer

When you need selective renaming rather than automatic conversion of all keys, a hand-written mapping object is cleaner than a library. Paste the raw snake_case field names from your API response into this converter, copy the camelCase output, and use both lists to build the mapping: { user_id: "userId", first_name: "firstName" }. You get a type-safe, explicit map that documents exactly which fields you are consuming and how you are renaming them.

When to use this

Use camelCase for all JavaScript variables, function names, object properties, and method names. Use PascalCase for classes, React components, and TypeScript interfaces. Use SCREAMING_SNAKE for module-level constants.

Notes

ESLint with the camelcase rule enforces camelCase for identifiers. The @typescript-eslint/naming-convention rule provides more granular control over interface, enum, and type alias naming. Most JavaScript/TypeScript projects run ESLint in CI, so naming violations are caught before merge.

Examples

Variables, functions, and constants

const maxRetries = 3;
const API_BASE_URL = "https://api.example.com";

function getUserProfile(userId) {
  return fetch(`${API_BASE_URL}/users/${userId}`);
}

Classes and React components

class UserService {
  getUser(userId) { ... }
}

function UserCard({ userName, userEmail }) {
  return <div>{userName}</div>;
}

Verify with the Text Case Format Converter tool.

Variables, functions, and constants

const maxRetries = 3;
const API_BASE_URL = "https://api.example.com";

function getUserProfile(userId) {
  return fetch(`${API_BASE_URL}/users/${userId}`);
}
Sources
  1. 1.

    W3C, "Document Object Model Core," w3.org, November 2000. https://www.w3.org/TR/DOM-Level-2-Core/core.html

  2. 2.

    Mozilla Developer Network, "CSS Object Model (CSSOM)," developer.mozilla.org, accessed June 2026. https://developer.mozilla.org/en-US/docs/Web/API/CSS_Object_Model

  3. 3.

    React, "Responding to Events," react.dev, accessed June 2026. https://react.dev/learn/responding-to-events

  4. 4.

    Microsoft, "TypeScript Coding Guidelines," github.com, accessed June 2026. https://github.com/microsoft/TypeScript-wiki/blob/756ece4f/Coding-guidelines.md

  5. 5.

    ESLint, "camelcase," eslint.org, accessed June 2026. https://eslint.org/docs/latest/rules/camelcase

  6. 6.

    typescript-eslint, "naming-convention," typescript-eslint.io, accessed June 2026. https://typescript-eslint.io/rules/naming-convention/

FAQ

PascalCase Naming Conventions in C#

Microsoft's C# Coding Conventions are the most prescriptive naming rules of any major language.1 Every public identifier, from class names to method parameters, follows a specific casing rule that communicates its role in the codebase. Understanding these rules helps you read any C# project and immediately recognize the purpose of each identifier.

The full C# naming convention reference

C# has the most fully documented naming conventions of any major language. Microsoft's C# Coding Conventions specify PascalCase for every publicly visible identifier: classes, methods, properties, events, namespaces, and enumerations.2 Private fields use camelCase, often with a leading underscore. Local variables use camelCase without a prefix. Consequently, a well-named C# codebase communicates access level and type through casing alone: uppercase means public, lowercase means private or local. This convention is enforced by tools like Roslyn analyzers and StyleCop, making it one of the most consistently applied in the .NET ecosystem. The .editorconfig file in a C# project configures naming rules per symbol kind, and IDE1006 warnings surface violations directly in Visual Studio and JetBrains Rider as you type, making it nearly impossible to introduce a naming violation without immediate feedback.

Where PascalCase appears in the .NET ecosystem

The entire BCL (Base Class Library) and .NET runtime use PascalCase: List<T>, Dictionary<TKey, TValue>, HttpClient, StreamReader. ASP.NET Core controllers, actions, and route parameters use PascalCase for class and method names. Entity Framework Core model class names and navigation property names use PascalCase. xUnit and NUnit test method names use PascalCase by convention. Building on this, NuGet package namespaces follow PascalCase (Microsoft.AspNetCore.Mvc), and XML serialization by default maps property names to PascalCase XML element names. The .NET runtime source code itself follows these conventions rigorously, and the .NET team maintains a public coding style document that contributors must follow.3 When you browse the reference source at source.dot.net, every public method, property, and class follows PascalCase without exception, providing a definitive reference for how the conventions apply in practice.

Private fields and local variable conventions

Private instance fields in C# use camelCase with an optional leading underscore: _userId, _orderRepository. The Microsoft convention in .NET runtime source code uses the underscore prefix; some teams omit it. Local variables and method parameters use camelCase without any prefix: userId, firstName, orderTotal. Conversely, constants in C# use PascalCase rather than SCREAMING_SNAKE ("MaxRetries" rather than "MAX_RETRIES"), which surprises developers coming from Python or JavaScript.3 The rationale is consistency: since all other public identifiers use PascalCase, constants follow the same rule. The readonly keyword (rather than casing) signals immutability in C#, which is a different approach from languages that use naming conventions to communicate mutability. Static readonly fields also use PascalCase: public static readonly int DefaultTimeout = 30;.

Using Roslyn analyzers and StyleCop to enforce PascalCase in CI

C# naming rules are enforced at the build level through Roslyn analyzers and static analysis tools. Configuring these in a new project prevents naming violations from reaching code review, where they waste reviewer time on issues the toolchain can catch automatically. By shifting enforcement left into the editor and build, you eliminate an entire class of style comments and keep code review focused on architecture and logic rather than formatting.

The .editorconfig file supports dotnet_naming_rule entries that enforce PascalCase for specific symbol kinds.2 IDE analyzers (IDE1006 in Visual Studio, equivalent rules in JetBrains Rider) surface violations as warnings or errors in the editor and during dotnet build.4 Adding these rules to a project's .editorconfig makes naming conventions part of the build process rather than relying on reviewers to catch them. New contributors learn the convention through editor feedback before their first PR.

StyleCop.Analyzers in CI pipelines

StyleCop.Analyzers is a NuGet package that enforces C# coding conventions including naming rules.5 Adding it to your project enables rules like SA1300 (element must begin with an uppercase letter) for class and method names. Running dotnet build in CI with StyleCop enabled fails the build on naming violations. Configure rule severity in stylecop.json or suppress specific rules with #pragma warning disable when an exception is justified by the local context.

When C# types are serialized to JSON and XML with different naming

C# code uses PascalCase by convention, but the JSON APIs you build or consume may use camelCase. Managing this translation is a standard concern in .NET web applications, because the naming mismatch between your server models and the wire format affects every controller endpoint that serializes a response. Without a consistent serialization policy, some endpoints return PascalCase while others return camelCase, creating unpredictable JSON structures that break client-side deserialization.

System.Text.Json camelCase serialization

System.Text.Json serializes C# property names as-is (PascalCase) by default, which means a property named UserId appears as UserId in the JSON output. To produce camelCase JSON for JavaScript clients, configure JsonSerializerOptions with PropertyNamingPolicy = JsonNamingPolicy.CamelCase.6 Clients consuming your API then receive userId, firstName, and createdAt rather than UserId, FirstName, and CreatedAt. Your C# model keeps PascalCase properties throughout the codebase, and the serialization layer handles the translation at the boundary without any changes to your domain logic.

The JsonNamingPolicy class also provides KebabCaseLower and SnakeCaseLower options for APIs that require those formats, and you can implement a custom JsonNamingPolicy by overriding the ConvertName method when your API needs a non-standard casing convention. This extensibility means the serialization boundary can adapt to any external contract without leaking casing logic into your domain models.

Newtonsoft.Json attribute-based name overrides

For projects using Newtonsoft.Json (Json.NET), the [JsonProperty("camelCaseName")] attribute overrides the serialized name for individual properties without affecting the C# property name at all. This is useful when you need different casing for specific fields rather than applying a global naming policy to every property. For global camelCase output across the entire API, configure CamelCasePropertyNamesContractResolver in your serializer settings.7 Both approaches let your C# model stay PascalCase while the JSON output follows whatever convention your client expects.

When to use this

Use PascalCase for all C# classes, interfaces, methods, properties, enumerations, and namespaces. Use camelCase (with optional _ prefix) for private fields and local variables. Avoid SCREAMING_SNAKE,C# constants use PascalCase.

Notes

Roslyn analyzers (IDE0003, IDE1006) and StyleCop enforce these conventions in CI and IDEs. The .editorconfig file configures naming rules per project. Visual Studio and Rider apply quick-fix suggestions for naming violations automatically.

Examples

Class, interface, and method naming

public interface IUserRepository
{
    Task<UserProfile> GetByIdAsync(int userId);
}

public class UserService : IUserService
{
    private readonly IUserRepository _userRepository;

    public async Task<UserProfile> GetUserAsync(int userId)
    {
        return await _userRepository.GetByIdAsync(userId);
    }
}

Constants and enumerations (PascalCase, not SCREAMING_SNAKE)

public const int MaxRetries = 3;
public static readonly string DefaultApiUrl = "https://api.example.com";

public enum OrderStatus
{
    Pending,
    Processing,
    Shipped,
    Delivered
}

Verify with the Text Case Format Converter tool.

Class, interface, and method naming

public interface IUserRepository
{
    Task<UserProfile> GetByIdAsync(int userId);
}

public class UserService : IUserService
{
    private readonly IUserRepository _userRepository;

    public async Task<UserProfile> GetUserAsync(int userId)
    {
        return await _userRepository.GetByIdAsync(userId);
    }
}
Sources
  1. 1.

    Microsoft, ".NET Coding Conventions – C#," learn.microsoft.com, accessed June 2026. https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions

  2. 2.

    Microsoft, "Code-style naming rules," learn.microsoft.com, accessed June 2026. https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/naming-rules

  3. 3.

    .NET Foundation, "C# Coding Style," github.com, accessed June 2026. https://github.com/dotnet/runtime/blob/main/docs/coding-guidelines/coding-style.md

  4. 4.

    JetBrains, "Code inspection: Inconsistent Naming," jetbrains.com, accessed June 2026. https://www.jetbrains.com/help/rider/InconsistentNaming.html

  5. 5.

    DotNetAnalyzers, "SA1300 — Element must begin with an upper-case letter," github.com, accessed June 2026. https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1300.md

  6. 6.

    Code Maze, "Using System.Text.Json for Camel Case Serialization," code-maze.com, May 2023. https://code-maze.com/csharp-using-system-text-json-for-camel-case-serialization/

  7. 7.

    Newtonsoft, "Serialization using ContractResolver," newtonsoft.com, accessed June 2026. https://www.newtonsoft.com/json/help/html/ContractResolver.htm

FAQ

kebab-case Naming Conventions in CSS

When you write font-size in a CSS file but fontSize in a JavaScript style object, you are translating between two formats that describe the same visual property. CSS and JavaScript share a boundary, and kebab-case sits on one side of it. Understanding how CSS naming works, and why it differs from every other format in web development, prevents the silent bugs that happen when the wrong format crosses that boundary.

The CSS-to-JavaScript naming boundary in practice

CSS was designed in the mid-1990s with hyphens as the standard word separator, and every property in the W3C specification follows kebab-case: background-color, font-family, margin-top, border-left-width, text-decoration-line.1 Custom properties (CSS variables) require a two-hyphen prefix followed by a kebab-case name such as background-color, font-size-body, or spacing-md after the prefix. The W3C CSS Specification does not formally specify class name casing, but the universal community practice is kebab-case for class names. Keyframe names (@keyframes slide-in, @keyframes fade-out) also follow kebab-case. The content property, font-family names with spaces, and counter-reset identifiers are additional contexts where kebab-case appears in CSS. Even CSS-wide keywords like inherit, initial, revert, and unset are lowercase, reinforcing the convention that CSS values and identifiers trend toward lowercase with hyphen separation.

BEM, SMACSS, and naming methodologies

BEM (Block Element Modifier), the most widely used CSS class naming methodology, uses kebab-case throughout.2 Block names: "navigation-bar", "product-card". Element names use a double underscore delimiter: "navigation-bar__menu-item", "product-card__image". Modifier names use a double hyphen delimiter: "product-card-featured", "button-primary". SMACSS and OOCSS follow the same convention. Building on this, CSS frameworks like Tailwind CSS use kebab-case utility class names: "text-lg", "bg-blue-500", "flex-col". Bootstrap, Foundation, and Bulma all use kebab-case for class names. ITCSS (Inverted Triangle CSS) uses kebab-case for its layer names: "settings", "tools", "generic", "elements", "objects", "components", "utilities". Every major CSS methodology converges on kebab-case because it matches the CSS specification's own naming style, creating a visual harmony between author code and the platform APIs they build on.

CSS-in-JavaScript: the boundary between kebab-case and camelCase

Because hyphens are subtraction operators in JavaScript, the DOM style API converts CSS property names to camelCase: element.style.backgroundColor, not element.style['background-color']. React's inline style prop requires camelCase property names for the same reason. CSS-in-JS libraries (styled-components, Emotion) accept both camelCase and kebab-case depending on the API: template literals use kebab-case, object syntax uses camelCase. Consequently, knowing which side of the JavaScript boundary you are on determines which format to use. The CSSOM (CSS Object Model) API provides a third option: CSSStyleDeclaration.setProperty() and getPropertyValue() accept the original kebab-case name,3 so you can work with CSS property names in their native format without converting to camelCase. This is particularly useful when setting custom properties dynamically: element.style.setProperty('--font-size-body', '1rem') uses the kebab-case custom property name directly.

CSS custom properties and design token naming with kebab-case

CSS custom properties (variables) use kebab-case because they are CSS values, not JavaScript identifiers. Design token systems built on CSS custom properties inherit this requirement from the CSS specification itself, which means that every token name in your design system must follow kebab-case if it is going to be consumed as a CSS custom property without renaming. CamelCase or snake_case token names require a transformation step before they can become valid CSS custom property references, adding a potential source of inconsistency when the same token is used across CSS and JavaScript contexts.

Token-based design systems like Style Dictionary and Tokens Studio define tokens in JSON or YAML, then export them to platform-specific formats. The CSS output always uses kebab-case custom properties with the two-hyphen prefix, such as "token-name-here" after the prefix.4 Token names in the source file may use camelCase or PascalCase for the JS and TypeScript output targets, but the CSS export generates kebab-case automatically.

Theming consistency from declaration to usage

Theming with CSS custom properties requires the same kebab-case name from the :root declaration through every usage in component styles and JavaScript setProperty calls. If your :root declares a variable called button-primary-color but a component references buttonPrimaryColor, the variable does not resolve and the fallback value applies silently. Kebab-case must be consistent from the declaration to every reference. Running your variable names through this converter before writing both the declaration block and the component styles ensures they match exactly.

A practical workflow is to define your design tokens in a single source file (JSON, YAML, or Tokens Studio) and use a build-time transform like Style Dictionary to generate both the CSS custom property declarations and the TypeScript/JavaScript constants. The transform handles the kebab-case conversion for CSS output while producing camelCase constants for your JavaScript code, eliminating the manual translation step that causes mismatches. This approach also makes it trivial to rename a token across the entire system by changing it in one place.

Stylelint rules for enforcing consistent kebab-case naming

Stylelint provides dedicated rules for enforcing kebab-case naming in CSS files. Configuring both the class selector rule and the custom property rule gives your project automated enforcement for the most common naming violations, catching inconsistencies at lint time rather than relying on code reviewers to spot casing mistakes by eye. When these rules run in CI, any deviation from kebab-case fails the pipeline before it reaches the main branch, which keeps the naming convention consistent even as new contributors join the project.

selector-class-pattern for kebab-case class names

The selector-class-pattern rule in Stylelint accepts a regex that class names must match.5 Setting it to a pattern like ^[a-z][a-z0-9-]*$ enforces lowercase kebab-case: no underscores, no uppercase letters. Violations fail the lint step in CI. For BEM-aware pattern matching that also permits double underscores in element segments and double hyphens in modifier segments, use a more complex regex that accounts for the BEM delimiter conventions. Add the rule to your .stylelintrc to enforce kebab-case in every CSS file across the project.

custom-property-pattern for CSS variable naming

The custom-property-pattern rule enforces naming of CSS custom properties (the segment after the two-hyphen prefix). Setting it to ^[a-z][a-z0-9-]*$ ensures that names like font-size-body pass while fontSizeBody and font_size_body fail. This rule is especially valuable in design token systems where custom property names come from multiple contributors or are generated by multiple tools. Running Stylelint in CI with both selector-class-pattern and custom-property-pattern configured ensures no naming inconsistency slips into the stylesheet before merge.

When to use this

Use kebab-case for all CSS property names, custom properties, class names, keyframe identifiers, and BEM component names. Switch to camelCase only when writing CSS properties inside JavaScript objects (DOM style API, React inline styles).

Notes

Stylelint enforces kebab-case class names and custom property naming via the "selector-class-pattern" and "custom-property-pattern" rules. BEM linting is available through stylelint-selector-bem-pattern.

Examples

CSS custom properties and class names

:root {
  --color-primary: #00ff00;
  --font-size-body: 1rem;
  --spacing-md: 1rem;
}

.navigation-bar {
  background-color: var(--color-primary);
  font-size: var(--font-size-body);
}

.navigation-bar__menu-item {
  padding: var(--spacing-md);
}

.navigation-bar__menu-item--active {
  color: var(--color-primary);
}

CSS property in JavaScript (camelCase conversion)

/* CSS stylesheet (kebab-case) */
.button { background-color: blue; }

/* DOM style API (camelCase) */
element.style.backgroundColor = "blue";

/* React inline style (camelCase) */
<button style={{ backgroundColor: "blue" }} />

Verify with the Text Case Format Converter tool.

CSS custom properties and class names

:root {
  --color-primary: #00ff00;
  --font-size-body: 1rem;
  --spacing-md: 1rem;
}

.navigation-bar {
  background-color: var(--color-primary);
  font-size: var(--font-size-body);
}

.navigation-bar__menu-item {
  padding: var(--spacing-md);
}

.navigation-bar__menu-item--active {
  color: var(--color-primary);
}
Sources
  1. 1.

    W3C, "CSS 2.2 – Full property table," w3.org, accessed June 2026. https://www.w3.org/TR/CSS22/propidx.html

  2. 2.

    BEM, "Naming," getbem.com, accessed June 2026. https://getbem.com/naming/

  3. 3.

    Mozilla Developer Network, "CSSStyleDeclaration: setProperty()," developer.mozilla.org, October 2025. https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleDeclaration/setProperty

  4. 4.

    Style Dictionary, "Built-in transforms," styledictionary.com, accessed June 2026. https://styledictionary.com/reference/hooks/transforms/predefined/

  5. 5.

    Stylelint, "selector-class-pattern," stylelint.io, accessed June 2026. https://stylelint.io/user-guide/rules/selector-class-pattern/

FAQ