Kebab case is a naming convention where every word is lowercase and words are joined with hyphens, like user-profile-page or my-awesome-post. It’s also called dash-case, hyphen-case, or lisp-case.
You see kebab case everywhere on the web: WordPress post slugs, CSS class names, HTML attributes, theme and plugin folders, and most YAML config files use it as the default. If you’ve ever changed a post URL in WordPress, you’ve written kebab case.
This guide covers where kebab case actually shows up in practice, how to convert to and from it in JavaScript, Python, and PHP, how it compares to camelCase, PascalCase, and snake_case, and when you should (and shouldn’t) use it.
What kebab case looks like
The two rules are simple: everything lowercase, hyphens instead of spaces. A few examples:
My String » my-string
Reasons to Build a Blog » reasons-to-build-a-blog
SCRIPTLOADER » scriptloader
User Profile Page » user-profile-page
Single-word names stay as one lowercase word (no hyphens needed). Acronyms lose their capital letters along with everything else.
Where you’ll actually see kebab case
Kebab case lives in specific parts of the web stack where hyphens are safe and lowercase is preferred:
- WordPress slugs use kebab case by default. Your post title “How to Install WordPress” becomes
how-to-install-wordpress. Google treats hyphens as word separators, sohow-to-install-wordpressreads as four words whilehowtoinstallwordpressreads as one long nothing. - CSS classes and IDs follow the same pattern:
.primary-button,.site-header,.wp-block-list. Kebab case is the CSS norm, works everywhere, and doesn’t need any escaping. - HTML custom attributes like
data-user-id,data-toggle-target, andaria-labelledbyhave to use kebab case. The HTML spec requires lowercase, and hyphens are the only separator that’s valid. - WordPress theme and plugin folders, for the same reason:
wp-content/themes/twentytwentyfour-child/,wp-content/plugins/wp-rocket/. Linux filesystems are case-sensitive, so hyphens prevent accidental mismatches. - Config file keys in YAML and JSON, especially in Docker Compose, GitHub Actions, and Kubernetes manifests. Not universal, but common enough to recognize on sight.
WordPress even ships a helper function, _wp_to_kebab_case(), for converting strings into kebab case inside plugins and themes. It’s a private function (the underscore prefix is intentional) but it’s stable and used throughout core.
How to Convert a String to Kebab Case
The general algorithm is: lowercase the whole string, then replace any sequence of non-alphanumeric characters with a single hyphen, then trim hyphens from the ends. Here it is in the three languages you’ll actually need it in.
JavaScript
function toKebabCase(str) {
return str
.replace(/([a-z])([A-Z])/g, '$1-$2') // camelCase boundaries
.replace(/[\s_]+/g, '-') // spaces and underscores
.toLowerCase()
.replace(/[^a-z0-9-]/g, '') // drop everything else
.replace(/-+/g, '-') // collapse repeats
.replace(/^-|-$/g, ''); // trim ends
}
toKebabCase('User Profile Page'); // 'user-profile-page'
toKebabCase('userProfilePage'); // 'user-profile-page'
toKebabCase('USER_PROFILE_PAGE'); // 'user-profile-page'
The first replace handles camelCase input by inserting a hyphen at every lowercase-then-uppercase boundary. Without it, 'userName' would collapse to 'username' instead of 'user-name'.
Python
import re
def to_kebab_case(s):
s = re.sub(r'([a-z])([A-Z])', r'\1-\2', s)
s = re.sub(r'[\s_]+', '-', s).lower()
s = re.sub(r'[^a-z0-9-]', '', s)
return re.sub(r'-+', '-', s).strip('-')
to_kebab_case('User Profile Page') # 'user-profile-page'
to_kebab_case('userProfilePage') # 'user-profile-page'
PHP (and WordPress)
// Generic PHP version
function to_kebab_case($s) {
$s = preg_replace('/([a-z])([A-Z])/', '$1-$2', $s);
$s = preg_replace('/[\s_]+/', '-', strtolower($s));
$s = preg_replace('/[^a-z0-9-]/', '', $s);
return trim(preg_replace('/-+/', '-', $s), '-');
}
// WordPress: use the built-ins instead
echo sanitize_title( 'User Profile Page' ); // 'user-profile-page'
echo _wp_to_kebab_case( 'User Profile Page' ); // 'user-profile-page'
Inside WordPress, prefer sanitize_title() for anything that becomes a URL slug (it’s been hardened over many years and handles unicode characters correctly). Use _wp_to_kebab_case() for converting block attribute names and other internal identifiers.
How to Convert Kebab Case to camelCase, PascalCase, or snake_case
Going the other direction is usually simpler. Split on the hyphens, then rejoin with the target convention’s rules:
// kebab → camelCase
const kebabToCamel = (s) => s.replace(/-(.)/g, (_, c) => c.toUpperCase());
kebabToCamel('user-profile-page'); // 'userProfilePage'
// kebab → PascalCase
const kebabToPascal = (s) => s
.split('-')
.map(w => w[0].toUpperCase() + w.slice(1))
.join('');
kebabToPascal('user-profile-page'); // 'UserProfilePage'
// kebab → snake_case
const kebabToSnake = (s) => s.replace(/-/g, '_');
kebabToSnake('user-profile-page'); // 'user_profile_page'
These three converters are useful when you receive data in kebab case (URL parameters, CSS custom property names, HTML data attributes) and need to use it as a variable name in JavaScript or another language.
Kebab case vs camel case, Pascal case, and snake case
Four naming conventions cover almost everything you’ll see in code:
| Convention | Example | Where it’s used |
|---|---|---|
| kebab-case | user-profile-page | URLs, CSS, HTML attributes, WordPress slugs |
| camelCase | userProfilePage | JavaScript variables, JSON keys, most JS libraries |
| PascalCase | UserProfilePage | Class names in JS, React components, C# / Java classes |
| snake_case | user_profile_page | Python, Ruby, PHP (some), SQL columns, database tables |
The quick version:
- Use kebab-case when hyphens are allowed and lowercase is expected (URLs, CSS, HTML).
- Use camelCase for JavaScript variables and function names.
- Use PascalCase for anything that acts like a class or component.
- Use snake_case in languages where hyphens aren’t valid identifiers (Python, PHP variables, SQL).
Kebab case can’t be used inside most programming languages as a variable name, because the parser reads the hyphen as a minus sign. user-name in JavaScript is interpreted as user minus name, which is a runtime error if those variables don’t exist.
That’s why you see camelCase and snake_case everywhere inside code, and kebab case in the stuff the code produces (URLs, class names, file paths).
The exception: a few languages were designed to allow hyphens in identifiers. Lisp, Clojure, Scheme, and Elixir (in atoms) all permit kebab-case names. That’s where the alternate name “lisp-case” comes from.
In those languages, get-user-by-id is a perfectly valid function name. The C-family of languages chose to reserve the hyphen for subtraction instead.
When to use kebab case (and when not to)
Reach for kebab case when:
- You’re creating a URL or a WordPress slug
- You’re naming a CSS class or ID
- You’re adding a
data-*attribute in HTML - You’re naming a theme or plugin folder
- You’re writing config keys in a YAML file
Avoid kebab case when:
- You’re naming a variable or function in JavaScript, Python, PHP, or any language where the hyphen is a subtraction operator
- You’re naming a database table or column in SQL (snake_case is the standard)
- You’re naming a class or component (PascalCase is the norm)
Why “kebab”?
The name comes from the visual: words skewered together on hyphens the way meat and vegetables get skewered on a kebab stick. Snake case looks like a snake slithering through underscores. Camel case has humps where the capital letters are. The programming community, once in a while, is delightful.
Frequently asked questions
What is kebab case?
Kebab case is a naming convention where every word is lowercase and separated by hyphens. For example, “User Name” becomes user-name and “My Page” becomes my-page. It’s commonly used in URLs, CSS classes, and HTML attributes.
What is an example of kebab case?
Common kebab case examples include my-awesome-page for a web page slug, primary-button for a CSS class, and data-user-id for an HTML custom attribute. Any multi-word phrase written in lowercase with hyphens instead of spaces is in kebab case.
What is the difference between kebab case and snake case?
Kebab case uses hyphens to separate words (user-profile-page), while snake case uses underscores (user_profile_page). Kebab case is standard for URLs and CSS, whereas snake case is standard in Python, PHP variables, and SQL databases.
Is kebab case the same as dash case?
Yes. Kebab case has a few aliases: dash-case, hyphen-case, lisp-case, train-case (when capitalized like Train-Case), and spinal-case. All of them describe the same convention of lowercase words joined by hyphens. “Kebab case” is the most common name in 2026.
Why don’t most programming languages allow kebab case?
The hyphen character is reserved as the subtraction operator in nearly every C-family language (JavaScript, Java, Python, PHP, C#, Go, Rust). A parser sees user-name and reads it as user minus name. Lisp, Clojure, Scheme, and Elixir’s atoms are notable exceptions: they use a different parsing rule that lets hyphens be part of identifiers.
Is kebab case better than snake case for URLs?
Yes, for SEO. Google explicitly recommends hyphens over underscores in URLs: hyphens are treated as word separators, underscores are not. A URL like /wordpress-staging-site/ reads to Google as three words; /wordpress_staging_site/ reads as one long string. WordPress defaults to kebab case for slugs for this exact reason.
Can I use kebab case in JavaScript at all?
Not as a variable or function name, but yes as a string value. CSS custom properties (--primary-color), DOM dataset keys (data-user-id), and any kind of identifier you’re generating (a URL slug, a className) can be kebab case strings. JavaScript itself just can’t use kebab case for things it parses as identifiers.
What’s the easiest way to convert a string to kebab case in JavaScript?
If you don’t want to write a regex by hand, both Lodash (_.kebabCase()) and Just (just-kebab-case) ship a kebab case converter. Lodash handles edge cases like all-caps input and unicode reasonably well. For a one-off, the regex shown in the JavaScript section above does the same job in 7 lines with no dependency.
Does WordPress convert post titles to kebab case automatically?
Yes. When you publish a post, WordPress runs the title through sanitize_title(), which lowercases, replaces spaces with hyphens, strips accents, and removes punctuation. The result becomes the post slug. You can override it manually in the Permalink field if you want a different slug.
Wrapping Up
Kebab case is the web’s default casing for anything a browser or server reads as a single string of characters: URLs, CSS selectors, HTML attributes, file paths. You probably write it every day without thinking about it.
If you need to convert a title to a slug quickly without writing code, this online hyphen-converter handles one-offs. Inside WordPress, sanitize_title() and _wp_to_kebab_case() are the canonical converters. Outside WordPress, the JavaScript, Python, and PHP snippets above are drop-in replacements that don’t depend on any framework.
For more on where kebab case shows up in WordPress specifically, see our guides on WordPress permalinks (which is mostly an exercise in good kebab case slug design) and code snippets (where you’ll find the functions.php patterns the converters above plug into).



2 Responses
The topic is very new to me but interesting for the Wordpress new learner.
good