Skip to content

CSS Basics

Learn the fundamentals of CSS including selectors, properties, and values.

Introduction

Before diving into CSS selectors, let's understand why they're so important. Selectors are the "targeting system" of CSS - they tell the browser exactly which HTML elements should receive your styles. Mastering selectors is the foundation of writing efficient, maintainable CSS.

Why Selectors Matter

Imagine trying to give directions without being able to name streets or landmarks. Selectors are how you "point" at specific elements on your page. The more precise your selectors, the more control you have over your design.

CSS Selectors

Selectors are patterns used to select the HTML elements you want to style. Think of them as a way to "find" elements in your HTML document.

Element Selector

What it does: Selects ALL elements of a given type (tag name).

When to use: When you want consistent styling across all instances of an element.

css
/* Every paragraph on the page will be blue */
p {
    color: blue;
}

/* Every h1 heading will be 32px */
h1 {
    font-size: 32px;
}
ElementWhat It Selects
pAll <p> paragraphs
h1All <h1> headings
divAll <div> containers
aAll <a> links
imgAll <img> images

Be Careful

Element selectors are very broad. Using div { color: red; } will affect EVERY div on your page. For more targeted styling, use class or ID selectors.

Class Selector

What it does: Selects elements that have a specific class attribute. Classes are prefixed with a dot (.).

When to use: When you want to apply the same styles to multiple elements, or when you need reusable style "packages."

The Analogy: Think of classes like labels or tags. Just like you might tag a photo with "vacation" and "beach", you can tag HTML elements with multiple classes.

html
<!-- HTML: Adding classes to elements -->
<p class="highlight">This is highlighted</p>
<p class="highlight important">This has two classes</p>
<span class="highlight">This span is also highlighted</span>
css
/* CSS: Styling classes */
.highlight {
    background-color: yellow;
}

.important {
    font-weight: bold;
}

/* An element with both classes gets BOTH styles */

Key Points About Classes:

FeatureDescription
ReusableOne class can be used on unlimited elements
MultipleOne element can have multiple classes
NamingUse lowercase, hyphens for multi-word (my-class)
SpecificityClasses have medium specificity (higher than elements)

Best Practice

Classes are the workhorses of CSS. Professional developers use classes for almost all styling because they're reusable and have manageable specificity.

ID Selector

What it does: Selects a single, unique element with a specific ID. IDs are prefixed with a hash (#).

When to use: For unique elements that appear only once per page (like a main navigation, header, or footer).

html
<!-- HTML: Each ID must be unique on the page -->
<div id="header">Site Header</div>
<div id="main-content">Main Content</div>
<div id="footer">Site Footer</div>
css
/* CSS: Selecting by ID */
#header {
    background-color: #333;
    color: white;
}

#main-content {
    padding: 20px;
}

Classes vs IDs:

FeatureClass (.)ID (#)
UniquenessCan repeatMust be unique
UsageMultiple elementsSingle element
SpecificityMedium (10)High (100)
RecommendationPreferred for stylingUse sparingly

Important

IDs should be unique on a page - never use the same ID twice! While browsers may still work with duplicate IDs, it's invalid HTML and causes problems with JavaScript and accessibility.

Professional Advice

Many developers avoid using IDs for styling altogether. IDs have very high specificity, making them hard to override. Save IDs for JavaScript targeting or anchor links, and use classes for CSS styling.

Universal Selector

What it does: Selects EVERY element on the page. Use the asterisk (*).

When to use: For CSS resets or applying box-sizing to all elements.

css
/* Common CSS Reset Pattern */
* {
    margin: 0;           /* Remove default margins */
    padding: 0;          /* Remove default padding */
    box-sizing: border-box;  /* Include padding in width calculations */
}

Performance Warning

The universal selector affects every single element. Use it sparingly and only for global resets. Avoid using it with expensive properties or in combination with other selectors like * > *.

Combining Selectors

One of CSS's superpowers is the ability to combine selectors. This lets you target elements with surgical precision.

Selector Combination Quick Reference

SyntaxNameWhat It Selects
A, BGroupingElements matching A OR B
A BDescendantB elements inside A (any level)
A > BChildB elements directly inside A
A + BAdjacent SiblingB element immediately after A
A ~ BGeneral SiblingAll B elements after A

Grouping Selector

What it does: Applies the same styles to multiple selectors at once. Use commas (,) to separate selectors.

When to use: To avoid repeating the same styles for different elements.

css
/* Without grouping - repetitive! */
h1 {
    font-family: Georgia, serif;
    color: #333;
}
h2 {
    font-family: Georgia, serif;
    color: #333;
}
h3 {
    font-family: Georgia, serif;
    color: #333;
}

/* With grouping - much cleaner! */
h1, h2, h3 {
    font-family: Georgia, serif;
    color: #333;
}

Descendant Selector

What it does: Selects elements that are INSIDE other elements (at any nesting level). Use a space between selectors.

The Analogy: Like saying "find all the books in the library" - it doesn't matter which shelf or room they're on.

css
/* All paragraphs inside article - any level deep */
article p {
    line-height: 1.6;
}

/* Links inside navigation */
nav a {
    text-decoration: none;
}
html
<!-- Example HTML -->
<article>
    <p>This paragraph is selected</p>
    <div>
        <p>This paragraph is ALSO selected (nested deeper)</p>
    </div>
</article>

Child Selector

What it does: Selects elements that are DIRECT children only (not grandchildren). Use > between selectors.

The Analogy: Like saying "find books on THIS shelf" - not books on shelves inside cabinets.

css
/* Only direct paragraph children of article */
article > p {
    margin-bottom: 1em;
}
html
<article>
    <p>✅ This IS selected (direct child)</p>
    <div>
        <p>❌ This is NOT selected (grandchild)</p>
    </div>
</article>

Adjacent Sibling Selector

What it does: Selects an element that comes IMMEDIATELY after another element. Use + between selectors.

When to use: For styling elements based on what comes before them.

css
/* Paragraph immediately after h2 */
h2 + p {
    font-size: 1.2em;
    font-weight: 500;
}
html
<h2>Heading</h2>
<p>✅ This paragraph IS selected (immediately after h2)</p>
<p>❌ This paragraph is NOT selected (not immediately after)</p>

General Sibling Selector

What it does: Selects ALL siblings that come after an element. Use ~ between selectors.

css
/* All paragraphs that come after h2 (at the same level) */
h2 ~ p {
    color: #666;
}
html
<h2>Heading</h2>
<p>✅ Selected</p>
<div>Not a paragraph</div>
<p>✅ Also selected</p>

Attribute Selectors

What they do: Select elements based on their HTML attributes (like href, type, title, etc.).

When to use: For styling form inputs, links, or any element where the attribute value matters.

Attribute Selector Types

SelectorMeaningExample
[attr]Has attribute[title] - has title attribute
[attr="value"]Exact match[type="text"] - type is exactly "text"
[attr*="value"]Contains[class*="btn"] - class contains "btn"
[attr^="value"]Starts with[href^="https"] - href starts with "https"
[attr$="value"]Ends with[src$=".png"] - src ends with ".png"
[attr~="value"]Word in list[class~="active"] - class contains word "active"
css
/* Has attribute - any element with a title attribute */
[title] {
    cursor: help;
    border-bottom: 1px dotted;
}

/* Exact match - input type is exactly "text" */
[type="text"] {
    border: 1px solid #ccc;
    padding: 8px;
}

/* Contains - class contains "btn" anywhere */
[class*="btn"] {
    cursor: pointer;
}

/* Starts with - links to external sites (https) */
[href^="https"] {
    color: green;
}

/* Ends with - PNG images */
[src$=".png"] {
    border: 1px solid #ddd;
}

Practical Examples

css
/* Style all required form fields */
input[required] {
    border-left: 3px solid red;
}

/* Style all PDF download links */
a[href$=".pdf"]::after {
    content: " (PDF)";
    font-size: 0.8em;
}

/* Style external links */
a[href^="http"]:not([href*="yourdomain.com"]) {
    background: url('external-icon.svg') right center no-repeat;
    padding-right: 20px;
}

Pseudo-classes

What they are: Pseudo-classes select elements based on their STATE or POSITION - things that aren't in the HTML itself.

Syntax: Pseudo-classes start with a single colon (:).

The Analogy: Think of pseudo-classes like describing someone's current activity: "the person who is walking" or "the first person in line."

Interactive Pseudo-classes

These respond to user actions:

css
/* Link states - in LVHA order! */
a:link {
    color: blue;      /* Unvisited link */
}

a:visited {
    color: purple;    /* Visited link */
}

a:hover {
    color: red;       /* Mouse over */
    text-decoration: underline;
}

a:active {
    color: orange;    /* Being clicked */
}

/* Form focus state */
input:focus {
    outline: 2px solid blue;
    border-color: blue;
}

/* Button states */
button:hover {
    background-color: darkblue;
}

button:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

LVHA Order

Link pseudo-classes MUST be in this order to work correctly: Link, Visited, Hover, Active. Remember: "LoVe HAte"

Form State Pseudo-classes

css
/* Valid and invalid inputs */
input:valid {
    border-color: green;
}

input:invalid {
    border-color: red;
}

/* Checked checkboxes/radio buttons */
input:checked + label {
    font-weight: bold;
}

/* Placeholder shown */
input:placeholder-shown {
    border-style: dashed;
}

Structural Pseudo-classes

Select elements based on their position in the DOM:

Pseudo-classSelects
:first-childFirst child of its parent
:last-childLast child of its parent
:nth-child(n)The nth child
:nth-child(even)Even children (2, 4, 6...)
:nth-child(odd)Odd children (1, 3, 5...)
:nth-child(3n)Every 3rd child
:only-childOnly child (no siblings)
:first-of-typeFirst of its element type
:last-of-typeLast of its element type
css
/* First item in a list */
li:first-child {
    font-weight: bold;
}

/* Last item - no bottom border */
li:last-child {
    border-bottom: none;
}

/* Zebra stripe table rows */
tr:nth-child(even) {
    background-color: #f2f2f2;
}

/* Every 3rd item */
li:nth-child(3n) {
    color: red;
}

/* First 3 items */
li:nth-child(-n+3) {
    background: yellow;
}

Understanding nth-child Formulas

css
/* Formula: an + b
   a = cycle size
   b = offset
*/

:nth-child(3n)     /* Every 3rd: 3, 6, 9, 12... */
:nth-child(3n+1)   /* 3n, starting at 1: 1, 4, 7, 10... */
:nth-child(2n)     /* Every 2nd (even): 2, 4, 6, 8... */
:nth-child(2n+1)   /* Every 2nd, starting at 1 (odd): 1, 3, 5... */
:nth-child(-n+3)   /* First 3 items: 3, 2, 1 (counts down) */
:nth-child(n+4)    /* From 4th onward: 4, 5, 6, 7... */

Pseudo-elements

What they are: Pseudo-elements let you style PARTS of an element or INSERT content that doesn't exist in HTML.

Syntax: Pseudo-elements use double colons (::).

Key difference: Pseudo-classes select whole elements in a state. Pseudo-elements select PART of an element or create virtual elements.

Common Pseudo-elements

Pseudo-elementWhat It Styles
::first-lineFirst line of text
::first-letterFirst letter
::beforeInserted content before
::afterInserted content after
::selectionHighlighted/selected text
::placeholderInput placeholder text
css
/* First line of paragraph - great for articles */
p::first-line {
    font-weight: bold;
    font-variant: small-caps;
}

/* Drop cap effect - first letter */
p::first-letter {
    font-size: 3em;
    float: left;
    line-height: 1;
    margin-right: 0.1em;
    color: #333;
}

/* Custom text selection colors */
::selection {
    background-color: #007bff;
    color: white;
}

/* Style placeholder text */
input::placeholder {
    color: #999;
    font-style: italic;
}

::before and ::after

These pseudo-elements INSERT content before or after an element's actual content. They require the content property.

css
/* Add quotation marks around quotes */
.quote::before {
    content: '"';
    font-size: 1.5em;
    color: #666;
}

.quote::after {
    content: '"';
    font-size: 1.5em;
    color: #666;
}

/* Add icon before external links */
a[href^="http"]::before {
    content: '🔗 ';
}

/* Required field asterisk */
.required::after {
    content: ' *';
    color: red;
}

/* Clearfix using ::after */
.clearfix::after {
    content: '';
    display: table;
    clear: both;
}

Content Property Required

::before and ::after will NOT appear without the content property. Even if you want no visible content, use content: ''.

Creative Uses of Pseudo-elements

css
/* Decorative line under heading */
h2::after {
    content: '';
    display: block;
    width: 50px;
    height: 3px;
    background: #007bff;
    margin-top: 10px;
}

/* Custom bullet points */
li::before {
    content: '✓';
    color: green;
    margin-right: 10px;
}

/* Tooltip using ::after */
.tooltip:hover::after {
    content: attr(data-tooltip);
    position: absolute;
    background: #333;
    color: white;
    padding: 5px 10px;
    border-radius: 4px;
}

CSS Properties and Values

Now that you know how to SELECT elements, let's learn about WHAT you can change - properties and values.

Understanding the Property: Value Pattern

Every CSS declaration follows this pattern:

css
property: value;
  • Property: What aspect you want to change (color, size, spacing, etc.)
  • Value: What you want to change it to (blue, 16px, 10%, etc.)

Common Properties

PropertyDescriptionExample Values
colorText colorred, #ff0000, rgb(255,0,0)
background-colorBackground colorblue, #0000ff
font-sizeText size16px, 1.5em, 1rem
widthElement width100px, 50%, auto
heightElement height200px, 100vh
marginOutside spacing10px, 1em auto
paddingInside spacing15px, 10px 20px
borderElement border1px solid black

Value Types Explained

CSS has different types of values. Understanding these helps you know what values are valid for each property.

css
.example {
    /* KEYWORDS - Predefined words with special meaning */
    display: block;         /* block, inline, flex, grid, none */
    position: relative;     /* static, relative, absolute, fixed */
    text-align: center;     /* left, center, right, justify */

    /* LENGTH UNITS - Sizes with units */
    width: 100px;           /* pixels - fixed size */
    font-size: 1.5em;       /* em - relative to parent font-size */
    padding: 1rem;          /* rem - relative to root font-size */
    height: 100vh;          /* vh - viewport height percentage */

    /* PERCENTAGES - Relative to parent */
    width: 50%;             /* 50% of parent's width */

    /* COLORS - Multiple formats available */
    color: red;                    /* Named color keyword */
    color: #ff0000;                /* Hex code (6 digits) */
    color: #f00;                   /* Hex code (3 digit shorthand) */
    color: rgb(255, 0, 0);         /* RGB function */
    color: rgba(255, 0, 0, 0.5);   /* RGBA with alpha/opacity */
    color: hsl(0, 100%, 50%);      /* HSL (hue, saturation, lightness) */

    /* URLS - For external resources */
    background-image: url('image.jpg');
    background-image: url('../images/photo.png');
}

CSS Units Quick Reference

UnitTypeRelative ToBest For
pxAbsoluteNothing (fixed)Borders, small details
emRelativeParent element's font-sizePadding, margins
remRelativeRoot (html) font-sizeFont sizes, spacing
%RelativeParent elementWidths, responsive sizing
vwRelativeViewport widthFull-width sections
vhRelativeViewport heightFull-height sections

Modern Best Practice

Use rem for font sizes and spacing. This makes your site more accessible because users can adjust base font size in their browser settings.

Specificity

What it is: Specificity is CSS's conflict resolution system. When multiple rules target the same element, specificity determines which rule wins.

The Analogy: Think of specificity like a voting system. Different selectors have different "voting power." The selector with the most votes wins.

Specificity Hierarchy

Think of specificity as a 4-digit number: inline, ID, class, element

Selector TypeSpecificity ValueExample
Inline styles1-0-0-0 (1000)style="color: red"
ID selector0-1-0-0 (100)#header
Class, attribute, pseudo-class0-0-1-0 (10).button, [type="text"], :hover
Element, pseudo-element0-0-0-1 (1)p, div, ::before

Calculating Specificity

Count each type of selector:

css
/* Specificity: 0-0-0-1 (just one element) */
p { color: blue; }

/* Specificity: 0-0-1-0 (one class) */
.text { color: green; }

/* Specificity: 0-0-1-1 (one class + one element) */
p.text { color: red; }

/* Specificity: 0-1-0-0 (one ID) */
#main { color: purple; }

/* Specificity: 0-1-0-1 (one ID + one element) */
#main p { color: orange; }

/* Specificity: 0-1-1-1 (one ID + one class + one element) */
#main p.text { color: pink; }

Visual Specificity Examples

Selector                    | Specificity    | Who Wins?
----------------------------|----------------|----------
p                           | 0-0-0-1        |
.intro                      | 0-0-1-0        | ← Wins vs p
p.intro                     | 0-0-1-1        | ← Wins vs .intro
#content                    | 0-1-0-0        | ← Wins vs p.intro
#content p.intro            | 0-1-1-1        | ← Wins vs #content
style="color: red"          | 1-0-0-0        | ← Wins vs everything

Common Specificity Mistakes

css
/* Problem: ID specificity is hard to override */
#navigation a { color: blue; }

/* This WON'T work - class is lower specificity than ID */
.active { color: red; } /* Won't override! */

/* Solution: Match or exceed the specificity */
#navigation a.active { color: red; } /* Works! */

The !important Escape Hatch

css
p { color: red !important; }  /* Overrides everything */

!important wins over everything, but it makes your CSS very hard to maintain. It's like breaking the rules of the game - avoid it when possible!

Best Practice

Keep specificity LOW and consistent. Use classes for most styling. This makes your CSS easier to maintain and override when needed.

Inheritance

What it is: Some CSS properties automatically pass down from parent elements to their children. This is CSS inheritance.

The Analogy: Like genetic inheritance - children inherit traits from their parents. A <p> inside a <body> inherits the body's text color.

How Inheritance Works

css
body {
    font-family: Arial, sans-serif;  /* Inherited by all text */
    color: #333;                      /* Inherited by all text */
}

/* All these automatically get Arial font and #333 color! */
/* <h1>, <p>, <span>, <a>, etc. */
html
<body>                          <!-- font-family: Arial; color: #333 -->
    <article>                   <!-- Inherits both -->
        <h1>Title</h1>          <!-- Inherits both -->
        <p>                     <!-- Inherits both -->
            Some <span>text</span>  <!-- Inherits both -->
        </p>
    </article>
</body>

What Gets Inherited (and What Doesn't)

Generally inherited (text-related properties):

PropertyWhy It Makes Sense
colorAll text should match by default
font-familyConsistent fonts throughout
font-sizeText sizing
font-weightBold/normal text
line-heightText spacing
text-alignText alignment
visibilityShow/hide content
cursorMouse cursor style

NOT inherited (box/layout properties):

PropertyWhy It Doesn't Inherit
backgroundEach box should have its own
borderBorders on every element would be chaos
margin, paddingSpacing is element-specific
width, heightSize is element-specific
display, positionLayout is element-specific

Controlling Inheritance

css
/* Force inheritance - use parent's value */
.child {
    border: inherit;
}

/* Reset to default browser value */
.reset {
    color: initial;
}

/* Remove all inherited and non-inherited styles */
.clean-slate {
    all: unset;
}

Practical Use of Inheritance

Set global text styles on body and let them cascade down. This is more efficient than styling every element individually!

css
body {
    font-family: 'Segoe UI', sans-serif;
    color: #333;
    line-height: 1.6;
}
/* Now all text elements inherit these values */

Practice Exercise

Let's put everything together! Create a styled card component using what you've learned.

Challenge: Build a Card Component

html
<div class="card">
    <h2 class="card-title">Card Title</h2>
    <p class="card-content">This is the card content. It explains what this card is about.</p>
    <a href="#" class="card-link">Read More</a>
</div>
css
/* The card container */
.card {
    border: 1px solid #ddd;
    border-radius: 8px;
    padding: 20px;
    max-width: 300px;
    background-color: white;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

/* Card title - using descendant selector would also work */
.card-title {
    color: #333;
    margin-top: 0;
    margin-bottom: 10px;
    font-size: 1.25rem;
}

/* Card content */
.card-content {
    color: #666;
    line-height: 1.5;
    margin-bottom: 15px;
}

/* Card link with hover state */
.card-link {
    color: #007bff;
    text-decoration: none;
    font-weight: 500;
}

/* Pseudo-class for hover effect */
.card-link:hover {
    text-decoration: underline;
    color: #0056b3;
}

What You Practiced

  • Class selectors (.card, .card-title)
  • Multiple properties (border, padding, color)
  • Pseudo-classes (:hover)
  • Value types (colors, units, keywords)

Extra Challenges

Try these modifications to practice more:

  1. Add a :first-child selector to make the first card different
  2. Use attribute selector to style links that go to external sites
  3. Add ::before to add an icon before the "Read More" link
  4. Create a .card:hover effect that lifts the card slightly

Summary

Congratulations! You've learned the fundamentals of CSS:

ConceptWhat You Learned
SelectorsHow to target elements (element, class, ID, attribute, pseudo)
CombiningGrouping, descendant, child, sibling selectors
PropertiesWhat you can style (color, size, spacing, etc.)
ValuesDifferent value types (keywords, lengths, colors)
SpecificityHow CSS resolves conflicts
InheritanceHow properties pass to children

Next Steps

Now that you understand the basics, continue to Colors & Backgrounds to learn about working with colors, gradients, and background images!