CSS Case Sensitivity: What You Need to Know

CSS Case Sensitivity: What You Need to Know

You rename a class from Card to card in the HTML, refresh, and nothing happens. The styles are still there in the stylesheet, the element is still there in the markup, and the browser reports no error at all. The styling simply does not apply.

That is CSS case sensitivity in action, and it is one of the most confusing things to debug because the failure is completely silent. Worse, the rule is not a simple “CSS is case-sensitive” or “CSS is case-insensitive” — the answer depends on which part of the CSS you are talking about.

Property names are case-insensitive. Class names are not. Element selectors are case-insensitive in HTML but not in XHTML. Custom properties are case-sensitive, and so are keyframe names. Quirks mode changes one of the rules entirely.

This guide sorts all of it out, with live examples so you can see each rule in action rather than take it on faith.

In one sentence: CSS is case-insensitive for the parts of the language itself — property names, keywords, at-rules, pseudo-classes — and case-sensitive for anything you or the HTML author named, such as classes, IDs, custom properties, and keyframe names.

The Short Answer

The pattern behind every rule is simple once you see it. Case matters for names that come from your own code, and it does not matter for names defined by the CSS specification.

The specification does not care whether you type COLOR or color, because there is only one property with that name and it is defined in the standard. But it does care whether you type .Card or .card, because those are two different names that you invented, and the browser has no way to know you meant the same one.

Case sensitivity at a glance — the whole answer in one table
Thing Case-sensitive? Example
Property names No color = COLOR = Color
Keyword values No display: BLOCK = block
At-rule names No @MEDIA = @media
Pseudo-classes No :HOVER = :hover
Function names No RGB() = rgb()
Hex colors No #FFF = #fff
The !important flag No !IMPORTANT = !important
Element selectors (HTML) HTML only H1 = h1 in HTML
Attribute names (HTML) HTML only [TYPE] = [type] in HTML
Class names Yes .Card ≠ .card
ID names Yes #Header ≠ #header
Custom properties Yes --Brand ≠ --brand
@keyframes names Yes Fade ≠ fade
Attribute values Yes [data-state="open"] ≠ "Open"
URLs Usually Hero.jpg ≠ hero.jpg
The rule of thumb

If the name is defined by the CSS specification, case does not matter. If the name was invented by you or by the HTML author, case matters. That single sentence covers almost every situation you will meet.

What Is Case-Insensitive in CSS

Everything the CSS specification itself defines is case-insensitive. The standard notes this explicitly: property names, keywords, and most identifiers in the language are matched without regard to case.

Property names

Property names are ASCII case-insensitive. All three of these declarations are identical to the browser:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Case-Insensitive Properties</title>
    <style>
        body { font-family: system-ui, sans-serif; padding: 28px; background: #f8fafc; }

        /* All three declarations do exactly the same thing */
        .a { COLOR: #0891b2; FONT-WEIGHT: 700; PADDING: 16px; }
        .b { Color: #0891b2; Font-Weight: 700; Padding: 16px; }
        .c { color: #0891b2; font-weight: 700; padding: 16px; }

        .a, .b, .c {
            border-radius: 10px;
            background: #fff;
            margin-bottom: 10px;
        }
    </style>
</head>
<body>
    <div class="a">Uppercase property names</div>
    <div class="b">Mixed case property names</div>
    <div class="c">Lowercase property names</div>
</body>
</html>

All three boxes render identically. The browser normalizes the property name to lowercase internally before matching it against its list of known properties.

But do not actually write uppercase

It works, but it is not the convention. Every CSS style guide, the specification itself, and every code formatter uses lowercase property names. Uppercase property names in a stylesheet look like a mistake, and they make a file harder to scan for a team.

Keyword values

Most keyword values are also case-insensitive. This includes layout keywords, color names, and unit suffixes:

/* All identical to the browser */
display: BLOCK;
display: Block;
display: block;

position: ABSOLUTE;
position: absolute;

color: RED;
color: red;
color: ReD;

text-align: CENTER;
text-align: center;

The same applies to units. 16PX, 16Px, and 16px are all sixteen pixels. And hex colors are case-insensitive, so #FFFFFF, #ffffff, and #FfFfFf are the same color.

At-rule names and function names

/* At-rules — all identical */
@MEDIA (min-width: 600px) { }
@media (min-width: 600px) { }

@KEYFRAMES fade { }
@keyframes fade { }

/* Functions — all identical */
color: RGB(8 145 178);
color: rgb(8 145 178);

width: CALC(100% - 32px);
width: calc(100% - 32px);

Pseudo-classes and pseudo-elements

/* All identical */
a:HOVER { color: red; }
a:hover { color: red; }

li:FIRST-CHILD { font-weight: 700; }
li:first-child { font-weight: 700; }

The !important flag

/* All identical — but lowercase is the convention */
color: red !IMPORTANT;
color: red !Important;
color: red !important;
🔤

Property names

color, COLOR, Color — all the same property.

🏷️

Keyword values

block, BLOCK — the browser matches without regard to case.

🎨

Hex colors

#fff and #FFF are the same color.

📐

Units

16px and 16PX are the same length.

⚙️

Functions

rgb() and RGB() are the same function.

📋

At-rules

@media and @MEDIA are the same rule.

Why the spec allows this

The CSS specification normalizes these names to lowercase during parsing, so by the time the browser is matching a declaration to a property, the case is already gone. It is a deliberate choice for authoring convenience — the language is forgiving about things that have exactly one correct spelling anyway.

What IS Case-Sensitive in CSS

Everything you or the HTML author invented is case-sensitive. The browser has no way to know that .Card and .card were meant to be the same class, because they are simply two different strings.

Class names

This is the one that catches everyone. In standards mode, a class selector must match the class attribute exactly, character for character:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Class Case Sensitivity</title>
    <style>
        body { font-family: system-ui, sans-serif; padding: 28px; background: #f8fafc; }
        .card {
            background: #0891b2;
            color: #fff;
            padding: 16px;
            border-radius: 10px;
            margin-bottom: 10px;
            font-weight: 600;
        }
    </style>
</head>
<body>
    <!-- Matches: class is exactly "card" -->
    <div class="card">class="card" — styled</div>

    <!-- Does NOT match: "Card" is a different name -->
    <div class="Card">class="Card" — not styled</div>

    <!-- Does NOT match either -->
    <div class="CARD">class="CARD" — not styled</div>
</body>
</html>

Only the first box gets the teal background. The other two match nothing, and no error is reported anywhere.

ID names

IDs behave the same way. #Header does not match id="header":

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ID Case Sensitivity</title>
    <style>
        body { font-family: system-ui, sans-serif; padding: 28px; background: #f8fafc; }
        #main-title {
            color: #7c3aed;
            border-left: 5px solid #7c3aed;
            padding-left: 12px;
        }
    </style>
</head>
<body>
    <h1 id="main-title">id="main-title" — styled</h1>
    <h1 id="Main-Title">id="Main-Title" — not styled</h1>
    <h1 id="MAIN-TITLE">id="MAIN-TITLE" — not styled</h1>
</body>
</html>

Custom properties

Custom properties — CSS variables — are case-sensitive, and this is one of the most dangerous cases because a typo produces no error. The variable simply resolves to nothing, and the declaration using it is discarded.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Custom Property Case</title>
    <style>
        :root {
            --brand: #0891b2;
            --Brand: #e11d48;   /* a different property entirely */
        }

        body { font-family: system-ui, sans-serif; padding: 28px; background: #f8fafc; }

        .one {
            background: var(--brand);   /* teal */
            color: #fff;
            padding: 16px;
            border-radius: 10px;
            margin-bottom: 10px;
            font-weight: 600;
        }

        .two {
            background: var(--Brand);   /* a completely different value */
            color: #fff;
            padding: 16px;
            border-radius: 10px;
            margin-bottom: 10px;
            font-weight: 600;
        }

        .three {
            /* --BRAND was never defined, so this declaration is dropped */
            background: var(--BRAND, #cbd5e1);
            color: #0f172a;
            padding: 16px;
            border-radius: 10px;
            font-weight: 600;
        }
    </style>
</head>
<body>
    <div class="one">var(--brand) — teal</div>
    <div class="two">var(--Brand) — red, a different property</div>
    <div class="three">var(--BRAND) — undefined, falls back to grey</div>
</body>
</html>

Two variables, one letter apart, producing two completely different colors — and a third reference that does not exist at all, quietly falling back to the default because the declaration had no value to use.

@keyframes names

Animation names are custom identifiers, which makes them case-sensitive. @keyframes Fade does not define the animation referenced by animation-name: fade:

/* Defines an animation called "Fade" */
@keyframes Fade {
    from { opacity: 1; }
    to   { opacity: 0; }
}

/* Correct — matches the name exactly */
.box-a {
    animation: Fade 1s ease;
}

/* Broken — "fade" is a different name, so nothing animates */
.box-b {
    animation: fade 1s ease;
}

The second rule is not flagged as an error. The browser simply cannot find an animation called fade, so it does nothing at all.

Attribute values

Attribute selectors match the value exactly as written, including case. This is a common problem when the attribute value comes from JavaScript or a content management system:

/* Matches data-state="open" */
[data-state="open"] { display: block; }

/* Does NOT match data-state="Open" or data-state="OPEN" */
[data-state="Open"] { display: block; }

The exception is a small set of HTML attributes that are defined as case-insensitive at the markup level, such as type on an input. For those, matching is normalized before the selector runs.

Font family names

Font names are matched case-insensitively by most operating systems in practice, but the CSS specification treats them as case-sensitive identifiers. Because of that mismatch, a font declared in one case may or may not match a font installed under another — it depends on the platform and the font itself.

/* Write the name exactly as the font family is named */
font-family: "Space Grotesk", system-ui, sans-serif;

/* This usually works, but "usually" is the problem */
font-family: "space grotesk", system-ui, sans-serif;

The safest approach is to copy the font’s name from its own metadata or the provider’s documentation and use that spelling every time.

URLs

The path portion of a URL is case-sensitive on almost every web server, because Linux and macOS file systems are case-sensitive by default. The scheme and hostname are not.

/* Different files on a case-sensitive server */
background-image: url("images/Hero.jpg");
background-image: url("images/hero.jpg");

/* The scheme and host are case-insensitive */
background-image: url("HTTPS://EXAMPLE.COM/hero.jpg");

This is why an image that works on a Windows development machine can 404 in production — Windows file systems are case-insensitive, so Hero.jpg and hero.jpg resolve to the same file locally, but not on a Linux server.

The case that costs the most time

Of all the case-sensitive items here, class names are the ones that cause the most debugging. A renamed class in the HTML does not throw an error, does not appear in the console, and does not show up as a broken rule in DevTools — the rule simply has nothing to match.

HTML vs CSS: Where the Rules Change

CSS is not always used with HTML. It styles XML documents, SVG, and XHTML as well, and the case rules for element and attribute selectors depend entirely on the document type the CSS is applied to.

HTML

Element selectors are case-insensitive

HTML tag names are case-insensitive at the markup level, so a selector written as H1 matches an element written as <h1>.

Attribute names behave the same way — [TYPE] matches type.

XML / XHTML

Element selectors are case-sensitive

XML is case-sensitive by definition, so H1 and h1 are two different elements and a selector must match exactly.

XHTML served as application/xhtml+xml follows the XML rules, not the HTML ones.

Case rules for selectors, by document type
Selector In HTML In XML / XHTML
Element — h1 Insensitive Sensitive
Attribute name — [type] Insensitive Sensitive
Attribute value — [type="text"] Depends on attribute Sensitive
Class — .card Sensitive Sensitive
ID — #header Sensitive Sensitive

HTML itself is forgiving about its own tags

It is worth separating two things that are often confused. The HTML parser is case-insensitive about tag and attribute names — <DIV> and <div> produce the same element. But the values of class and ID attributes are not normalized, which is exactly why they end up case-sensitive when CSS matches against them.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>HTML Parser vs CSS Matching</title>
    <style>
        body { font-family: system-ui, sans-serif; padding: 28px; background: #f8fafc; }

        /* Uppercase element selector — works in HTML */
        H2 {
            color: #0891b2;
            margin: 0 0 10px;
        }

        /* Lowercase class selector */
        .note {
            background: #fff;
            border-left: 4px solid #7c3aed;
            border-radius: 8px;
            padding: 14px 18px;
            color: #334155;
        }
    </style>
</head>
<body>
    <!-- Uppercase tag in the markup — still matched -->
    <H2>Uppercase tag, uppercase selector</H2>

    <!-- Lowercase tag, matched by the same uppercase selector -->
    <h2>Lowercase tag, same rule</h2>

    <!-- Class must match exactly -->
    <p class="note">class="note" — styled</p>
    <p class="Note">class="Note" — not styled</p>
</body>
</html>

Both headings are styled by the single uppercase H2 rule, because HTML normalizes tag names. But only the first paragraph is styled, because the class value is compared exactly as written.

Write lowercase anyway

Even though <DIV> works in HTML, writing tags in lowercase is the convention and is required for XHTML compatibility. It also avoids the trap of moving a template to an XML-based system and having every selector silently stop matching.

The Quirks Mode Exception

There is one situation where class and ID matching becomes case-insensitive in an HTML document: quirks mode. This is a legacy rendering mode the browser falls back to when a document has no valid DOCTYPE.

In quirks mode, the browser reproduces the behaviour of 1990s browsers, and one of those behaviours was matching class and ID selectors without regard to case.

How class and ID matching changes between modes
Document state Class & ID matching Example
Standards mode — valid DOCTYPE Case-sensitive .Card does not match class="card"
Quirks mode — no DOCTYPE Case-insensitive in HTML .Card matches class="card"

This means the same stylesheet can behave differently on two pages that look otherwise identical — which is exactly the kind of bug that is nearly impossible to find without knowing the rule.

/*
   In quirks mode, this rule matches class="card",
   class="Card", and class="CARD" — all of them.

   In standards mode, it matches only class="card".
*/

.Card {
    padding: 24px;
}
Always include a DOCTYPE

Starting every file with <!DOCTYPE html> keeps the page in standards mode, which means the case rules are consistent and predictable. This is one more reason the DOCTYPE line matters — see HTML DOCTYPE for the full picture.

You can confirm which mode a page is in from the console. In standards mode document.compatMode returns "CSS1Compat"; in quirks mode it returns "BackCompat".

/* Run this in the browser console */
document.compatMode
// "CSS1Compat"  → standards mode, class matching is case-sensitive
// "BackCompat"  → quirks mode, class matching is case-insensitive

Side-by-Side: Same Stylesheet, Different Case

The clearest way to see every rule at once is to write one stylesheet that uses a mix of cases and watch which parts apply. Each box below is labelled with what it demonstrates.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Case Sensitivity, Demonstrated</title>
    <style>
        /* Uppercase property names — work fine */
        body {
            FONT-FAMILY: system-ui, sans-serif;
            PADDING: 28px;
            BACKGROUND: #f8fafc;
        }

        /* Shared box styling */
        .box {
            padding: 14px 18px;
            border-radius: 10px;
            margin-bottom: 10px;
            font-weight: 600;
            font-size: 0.9rem;
        }

        /* 1. Lowercase property names — identical to uppercase above */
        .p-lower { color: #0891b2; background: #e0f7fa; }

        /* 2. Uppercase keyword values — work fine */
        .v-upper { DISPLAY: BLOCK; COLOR: WHITE; BACKGROUND: #0891b2; }

        /* 3. Class selector in lowercase */
        .exact { background: #7c3aed; color: #fff; }

        /* 4. Class selector in TitleCase — only matches TitleCase */
        .Exact { background: #16a34a; color: #fff; }

        /* 5. Custom property in lowercase */
        :root { --accent: #d97706; }
        .var-lower { background: var(--accent); color: #fff; }

        /* 6. Custom property in TitleCase — a different property */
        .var-upper { background: var(--Accent, #e11d48); color: #fff; }

        /* 7. Uppercase hex color — identical to lowercase */
        .hex-upper { background: #0891B2; color: #FFFFFF; }
    </style>
</head>
<body>

    <div class="box p-lower">
        Property names: uppercase and lowercase are the same
    </div>

    <div class="box v-upper">
        Keyword values: BLOCK and WHITE work as written
    </div>

    <div class="box exact">
        class="exact" matched by .exact — styled
    </div>

    <div class="box exact">
        .Exact does NOT match class="exact" — this box keeps .exact styling
    </div>

    <div class="box var-lower">
        var(--accent) resolved — orange
    </div>

    <div class="box var-upper">
        var(--Accent) undefined — falls back to red
    </div>

    <div class="box hex-upper">
        Hex #0891B2 and #FFFFFF are the same as lowercase
    </div>

</body>
</html>

Notice that the property names and keyword values behave exactly the same regardless of case, while the class and custom property rules do not. That is the whole distinction in one page.

Common Mistakes

Every one of these produces styling that silently does not apply. None of them raises an error, and none of them appears in the console.

1. Renaming a class in the HTML but not the CSS

Incorrect — names differ
<div class="Card">...</div> .card { padding: 24px; }
Correct — exact match
<div class="card">...</div> .card { padding: 24px; }

2. A typo in a custom property name

Incorrect — –Brand is undefined
:root { --brand: #0891b2; } .panel { background: var(--Brand); /* no value, declaration dropped */ }
Correct
:root { --brand: #0891b2; } .panel { background: var(--brand); }

3. A keyframe name that does not match

Incorrect — nothing animates
@keyframes Fade { to { opacity: 0; } } .box { animation: fade 1s ease; }
Correct
@keyframes fade { to { opacity: 0; } } .box { animation: fade 1s ease; }

4. An attribute value matched with the wrong case

Incorrect
<div data-state="Open">...</div> [data-state="open"] { display: block; }
Correct
<div data-state="open">...</div> [data-state="open"] { display: block; }

5. A file path with the wrong case

Incorrect on a Linux server
.hero { background-image: url("Images/Hero.jpg"); }
Correct — matches the file exactly
.hero { background-image: url("images/hero.jpg"); }

6. Mixing class case between files

Incorrect — inconsistent naming
<!-- header.html --> <div class="Card__Title">...</div> <!-- card.html --> <div class="card__title">...</div> /* styles.css */ .card__title { color: #0891b2; }
Correct — one convention everywhere
<!-- header.html --> <div class="card__title">...</div> <!-- card.html --> <div class="card__title">...</div> /* styles.css */ .card__title { color: #0891b2; }

7. Relying on quirks mode without knowing it

Inconsistent across pages
<!-- page-a.html — no DOCTYPE --> <!-- Quirks mode: .Card matches class="card" --> <!-- page-b.html — valid DOCTYPE --> <!-- Standards: .Card does not match -->
Consistent everywhere
<!-- every page --> <!DOCTYPE html> <html lang="en"> <!-- Standards mode on every page --> <!-- Class names match exactly, always -->

8. Assuming an element selector is case-sensitive in HTML

Mistaken belief
/* Expecting these to be different rules */ H1 { color: red; } h1 { color: blue; } /* In HTML, both target the same elements. The later rule wins, so headings are blue. */
Correct understanding
/* Element selectors are case-insensitive in HTML, so write one rule */ h1 { color: blue; }
Validate and check the Styles panel

When a rule is not applying, inspect the element in DevTools and look at the Styles panel. If the rule does not appear at all, the selector matched nothing — which in most cases means a name mismatch. If it appears with a strikethrough, the rule matched but something else won the cascade.

Best Practices

You can avoid every case-sensitivity problem by writing everything lowercase and never relying on the exceptions. It is a simple discipline that removes a whole category of bugs.

🔡

Write everything lowercase

Property names, values, selectors, class names, IDs, at-rules — all of it.

🔗

Match class names exactly

Copy and paste between HTML and CSS rather than retyping. It avoids silent mismatches.

🎛️

Keep custom property names lowercase

--brand-color, not --BrandColor. Dashes, all lowercase, every time.

🎬

Keep keyframe names lowercase

@keyframes fade-in and animation: fade-in should always match character for character.

📁

Lowercase every file name

hero.jpg, not Hero.JPG. It prevents the cross-platform path problem entirely.

📄

Always include a DOCTYPE

It keeps the page in standards mode, so class matching is consistent everywhere.

🧹

Use a linter or formatter

A formatter will not fix a class mismatch, but it will normalize everything it can.

🔍

Inspect when a rule does not apply

If the rule is missing from the Styles panel entirely, the selector matched nothing.

📝

Pick one naming convention

Whatever you choose — lowercase, kebab-case, BEM — apply it identically in HTML and CSS.

The one-line summary

Write everything lowercase, treat every class, ID, custom property, and keyframe name as case-sensitive, and the question never comes up again.

Frequently Asked Questions

1. Is CSS case-sensitive?

Partly. CSS is case-insensitive for property names, most values, at-rule names, pseudo-classes, and element selectors in HTML documents. It is case-sensitive for class names, IDs, custom properties, keyframe names, and attribute values.

2. Are CSS property names case-sensitive?

No. Property names are ASCII case-insensitive. color, COLOR, and Color all work identically. The same applies to function names and at-rule names.

3. Are class names case-sensitive in CSS?

Yes, in standards mode. A class selector .Card does not match an element with class="card". The only exception is quirks mode, where class matching in HTML documents becomes case-insensitive.

4. Are CSS values case-sensitive?

Most keyword values are case-insensitive, so display: BLOCK and display: block are equivalent. But custom identifiers such as keyframe names, font family names, and custom property names are case-sensitive.

5. Are CSS custom properties case-sensitive?

Yes. Custom property names are case-sensitive, so --brand and --Brand are two entirely different properties. This is one of the few places in CSS where case genuinely matters, and a common source of silent bugs.

6. Are CSS selectors case-sensitive?

Class and ID selectors are case-sensitive in standards mode. Element selectors are case-insensitive in HTML documents but case-sensitive in XML and XHTML. Attribute values are generally case-sensitive.

7. Does quirks mode change case sensitivity?

Yes. In quirks mode, class and ID matching in HTML documents becomes case-insensitive. This is one more reason to always include a valid DOCTYPE, which keeps the page in standards mode.

8. Are hex colors case-sensitive?

No. Hex color values are case-insensitive, so #FFFFFF, #ffffff, and #FfFfFf are all the same color. The same applies to rgb(), hsl(), and named colors.

9. Are @keyframes names case-sensitive?

Yes. Keyframe animation names are custom identifiers and are case-sensitive, so @keyframes Fade does not match animation-name: fade. This is easy to miss because the declaration itself is not flagged as an error.

10. Is the !important flag case-sensitive?

No. The !important flag is case-insensitive, so !IMPORTANT, !Important, and !important all work the same way. Lowercase is the convention.

11. Are URLs in CSS case-sensitive?

The path portion of a URL is case-sensitive on most servers, because Linux and macOS file systems are case-sensitive by default. The scheme and hostname are not. This means url(Hero.jpg) and url(hero.jpg) can behave differently.

12. Should I write CSS in uppercase or lowercase?

Always lowercase for property names, values, selectors, at-rules, and the !important flag. It is the universal convention, it matches the specification’s own formatting, and it avoids the case-sensitivity traps entirely.

Key Takeaways

  • CSS is partly case-sensitive — the answer depends on which part you mean.
  • Property names are case-insensitive: COLOR and color are identical.
  • Keyword values, units, hex colors, functions, and at-rule names are also case-insensitive.
  • Class names and ID names are case-sensitive in standards mode.
  • Custom properties are case-sensitive — --brand and --Brand are different.
  • Keyframe names are case-sensitive, which makes a mismatched animation silently do nothing.
  • Attribute values are matched exactly, including case.
  • URL paths are case-sensitive on most servers, even though the hostname is not.
  • Element selectors are case-insensitive in HTML but case-sensitive in XHTML.
  • Quirks mode makes class and ID matching case-insensitive in HTML — another reason to include a DOCTYPE.
  • The pattern is simple: case matters for names you invented, not for names the spec defines.
  • Write everything lowercase and the problem never arises.

What to Learn Next

Now that the case rules are clear, the next step is to strengthen the foundations around them. Start with CSS Selectors Explained and CSS Syntax Explained.

From there, explore CSS Rules: Selectors, Properties and Values, CSS Comments, and CSS Custom Properties. When you are ready to build layouts, read CSS Flexbox Guide and CSS Grid Guide, then move on to Responsive Web Design.

If you are still connecting the pieces, read HTML DOCTYPE for the quirks mode background, and How to Add CSS to HTML for where the stylesheet goes in the first place.

Practice Challenge

The only way to trust these rules is to break them and watch what happens. This exercise takes about fifteen minutes.

  1. Create index.html and styles.css, and link them with <link rel="stylesheet" href="styles.css">.
  2. In the HTML, add three paragraphs: one with class="card", one with class="Card", and one with class="CARD".
  3. In the CSS, write a rule for .card with a background and padding. Refresh and confirm that only the first paragraph is styled.
  4. Now write a second rule for .Card. Confirm that the second paragraph is styled by it, and that the first is unaffected.
  5. Add a rule using an uppercase property name, such as BACKGROUND-COLOR. Confirm that it works exactly like the lowercase version.
  6. Add a rule using an uppercase keyword value, such as display: BLOCK. Confirm that it works.
  7. Write an uppercase element selector, such as P, and confirm it matches the lowercase <p> elements.
  8. Define a custom property as --brand and use it. Then use var(--Brand) in another rule and confirm it falls back to nothing.
  9. Define @keyframes Fade and reference it with animation: fade 1s. Confirm nothing animates, then fix the name and confirm it does.
  10. Add [data-state="open"] in the CSS and set data-state="Open" in the HTML. Confirm the rule does not apply.
  11. Open DevTools, inspect the unstyled paragraph, and confirm the rule is entirely absent from the Styles panel — proving the selector matched nothing.
  12. Finally, normalize everything: lowercase property names, lowercase class names throughout, lowercase custom properties. Confirm the page looks the same and the ambiguity is gone.

If you complete those steps, you have tested every rule in this guide against a real browser rather than taking it on faith. More importantly, you have seen the failure mode firsthand — a rule that is present in your stylesheet, correct in its syntax, and completely invisible to the browser because one character was the wrong case. Once you have watched that happen, you will check the spelling before you check anything else.

Inar Learn
Inar Learnhttps://inarlearn.com
Inar Learn is an innovative online learning platform offering high-quality courses, tutorials, and resources to help learners gain practical skills and grow their knowledge.

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here