Question
What characters and symbols are allowed in CSS class selectors?
I know that the following characters are not normally used directly, but I want to understand which characters are actually valid in CSS class names and selectors:
~ ! @ $ % ^ & * ( ) + = , . / ' ; : " ? > < [ ] \ { } | ` #
In other words, what are the valid characters for CSS class names, and when do special characters need to be escaped?
Short Answer
By the end of this page, you will understand what makes a CSS class name valid, which characters are safe to use, which ones require escaping, and why most developers stick to simple naming patterns like letters, numbers, hyphens, and underscores.
Concept
CSS selectors follow a formal syntax. A class selector is written with a dot followed by a class name:
.button {
color: blue;
}
Here, .button is the selector, and button is the class name.
The important detail is that CSS class names are identifiers, and identifiers have rules.
The practical rule
In normal day-to-day CSS, class names are safest when they use:
- letters:
a-z,A-Z - digits:
0-9 - hyphens:
- - underscores:
_
Example:
.main-nav {}
.card_2 {}
.btnPrimary {}
What is allowed more broadly?
CSS is more flexible than many beginners expect:
- class names can include escaped characters
- Unicode characters are allowed
- some special characters can appear if escaped properly
For example, this is valid CSS if escaped correctly:
.hello\! {}
That selector matches an element whose class literally contains !, such as:
<div class="hello!"></div>
Why this matters
In real projects, this matters because:
- you may read generated CSS from frameworks or tools
- you may need to target classes coming from external systems
- you may see escaped selectors in browser dev tools
- writing simple, valid names avoids bugs and hard-to-read code
Important naming constraints
Even though CSS identifiers are flexible, there are practical restrictions:
- a class name should not start with an unescaped digit in normal selector syntax
- special characters often need escaping
- some characters have meaning in selectors, like
.#:[>+and must be escaped if they are part of the actual class name
For example, this is not the same:
.item.active {}
This means “an element with both item and active classes”, not a single class name containing a dot.
To target a class literally named item.active, you would need escaping:
.item\.active {}
Best practice
Although many characters can be used with escaping, most codebases avoid that complexity and use a simple convention:
letters, numbers, hyphens, underscores
A common recommendation is:
- start with a letter
- then use letters, numbers, hyphens, or underscores
Example:
.product-card {}
.user_profile {}
.navItem2 {}
Mental Model
Think of a CSS class name like a file name on your computer.
Technically, many file names are possible, but some characters are awkward because the system gives them special meanings. CSS works similarly.
- Simple names like
card,main-nav, anduser_1are easy to read and use. - Special characters are like unusual file name symbols: possible in some cases, but they often need extra handling.
- Escaping is like telling CSS, “Treat this character as normal text, not as syntax.”
So if CSS sees:
.warning:hover
it reads :hover as a pseudo-class.
But if you really want the class name to contain a colon, you must escape it:
.warning\:hover
That tells CSS to treat the colon as part of the class name.
Syntax and Examples
Basic syntax
A class selector uses a dot followed by the class name:
.class-name {
color: red;
}
Example HTML:
<div class="class-name">Hello</div>
Safe character set for everyday use
These are the easiest characters to use in class names:
a-z A-Z 0-9 - _
Examples:
.header {}
.main-content {}
.card_1 {}
.NavItem {}
Example: normal class names
<div class="profile-card"></div>
<div class="user_name"></div>
<div =>
Step by Step Execution
Traceable example
HTML:
<div class="note!">Important</div>
CSS:
.note\! {
color: red;
}
What happens step by step?
- The HTML element has a class value of
note!. - In CSS, a class selector begins with
.. - CSS sees
!as a special character, not a normal identifier character in this context. - To match a literal
!inside the class name, you escape it with\!. - The selector
.note\!now means “match an element whose class name is exactlynote!.” - The browser applies
color: redto that element.
Another example
HTML:
<div =>One class
Two classes
Real World Use Cases
Utility CSS frameworks
Some frameworks generate class names that contain special characters, especially colons or slashes in naming conventions.
Example:
<div class="sm:hover"></div>
To target it manually in CSS, you must escape the colon:
.sm\:hover {}
CMS or third-party HTML
You may inherit markup from a CMS, plugin, or external tool that outputs unusual class names.
If you cannot change the HTML, knowing how to escape selectors helps you still style the element.
JavaScript-generated class names
Frontend code may dynamically create class names. If the naming logic includes punctuation, your CSS and JavaScript selectors may need escaping.
Debugging in browser dev tools
Dev tools often display escaped selectors when classes contain special characters. Understanding this makes debugging much easier.
Team conventions and maintainability
In large codebases, teams usually define naming rules like:
- lowercase letters
- hyphens between words
- no special punctuation
This keeps selectors readable and avoids escaping issues.
Real Codebase Usage
Common team pattern: keep class names simple
In real projects, developers usually choose class names like:
.site-header {}
.product-card {}
.is-active {}
.error_message {}
This avoids selector bugs and improves readability.
Naming conventions
Typical conventions include:
- kebab-case:
main-nav,product-card - snake_case:
form_group - BEM-style naming:
card__title,button--primary
Example:
.card {}
.card__title {}
.card--featured {}
Escaping when integrating external markup
Sometimes developers do not control the class names. In that case, escaping is used as a compatibility tool rather than a naming strategy.
.api-status\:error {
color: red;
}
JavaScript selector usage
Common Mistakes
1. Confusing selector syntax with the class name itself
Broken idea:
<div class="item.active"></div>
.item.active {
color: red;
}
Why it fails:
.item.activemeans an element with two classes:itemandactive- it does not mean one class called
item.active
Correct version:
.item\.active {
color: red;
}
2. Starting a class name with a number and expecting normal selector syntax to work
HTML:
<div class="2col"></div>
Broken CSS:
Comparisons
Safe names vs escaped names
| Approach | Example class | CSS selector | Readability | Recommended |
|---|---|---|---|---|
| Simple safe name | main-nav | .main-nav | High | Yes |
| Underscore name | main_nav | .main_nav | High | Yes |
| Starts with number | 2col | .\32 col | Low | Usually no |
| Contains dot |
Cheat Sheet
Quick rules
- A class selector looks like
.className - The safest class name characters are:
a-zA-Z0-9-_
- Many other characters can work only if escaped
- Avoid starting class names with digits unless necessary
- Characters like
.,:,#,[,],+,>and similar have selector meaning
Safe examples
.header {}
.main-nav {}
.user_1 {}
.card2 {}
Escaped examples
.item\.active {}
\ {}
\$tag {}
.\ box {}
FAQ
Which characters are allowed in CSS class names?
For practical use, letters, numbers, hyphens, and underscores are the safest characters. Other characters may be used if they are escaped correctly in the selector.
Can CSS class names contain numbers?
Yes. Numbers are allowed, but a class name starting with a digit usually needs escaping in CSS selector syntax.
Can a CSS class name contain a hyphen?
Yes. Hyphens are very common and widely recommended, such as main-nav or product-card.
Can a CSS class name contain underscores?
Yes. Underscores are valid, for example user_name.
Can CSS class names contain dots or colons?
They can exist in the class attribute value, but you must escape them in CSS selectors because . and : already have special meaning in selector syntax.
Why does .item.active not match a class named item.active?
Because CSS reads it as two class selectors together: one for item and one for active.
Should I use special characters in class names?
Usually no. Even if they can be escaped, simple names are easier to read, write, and maintain.
What is the best convention for CSS class names?
Mini Project
Description
Build a small HTML page with several elements that use both normal and unusual class names. The project demonstrates which class names work directly, which ones require escaping, and why simple naming is easier to maintain.
Goal
Create a page where multiple elements are styled correctly using safe class names and escaped selectors for special-character class names.
Requirements
- Add at least two elements with simple class names such as
cardormain-title. - Add one element whose class name contains a dot, colon, or dollar sign.
- Write CSS that correctly styles every element, using escaping where needed.
- Include one example showing the difference between a literal special character in a class name and normal CSS selector syntax.
Keep learning
Related questions
CSS Font Scaling Relative to Container Size: %, em, rem, vw, and Responsive Text
Learn how CSS font scaling really works and how to make text responsive using %, em, rem, vw, clamp(), and media queries.
CSS Parent Selector Explained: Selecting a Parent <li> from an <a>
Learn whether CSS has a parent selector, how :has() works, and practical alternatives for styling a parent li from a child anchor.
CSS Previous Sibling Selector: What Exists and How to Work Around It
Learn whether CSS has a previous sibling selector, why it does not, and practical ways to style earlier elements using CSS alternatives.