Day 2 : CSS - Selectors & Elements

Introduction

Welcome back to your journey in CSS! In this tutorial, we will delve into one of the most powerful concepts in CSS: Selectors! 

Think of CSS selectors as a GPS system for styling. Just like GPS helps you find specific locations, selectors help you target exactly which HTML elements you want to style. Want to style ALL paragraphs? There’s a selector for that. Want to style just ONE specific element? There’s a selector for that too! Want to style elements based on their state (like when you hover over them)? Yep, selectors can do that as well!

Why Are CSS Selectors Important?

  • Precision: You can target exactly what you want without affecting other elements in the process
  • Efficiency: You can write less code by grouping similar elements with just one selector
  • Interactivity: You can have a dynamic effect that can respond to a user interacting with the webpage
  • Professional Skills: Understanding selectors is foundational to any CSS type of work
  • Power: Selectors give CSS power and allow for more complex styling

In this tutorial, you will learn, master, and practice different selector types, when to use each selector type, and apply your knowledge to a mini project that stylizes buttons and links! By the end of this tutorial, you will have the ability to target anything on any webpage with surgical precision!

Understanding CSS Selectors: Your Targeting Toolkit

What is a Selector?

A selector is the section of a CSS rule that identifies the HTML element(s) you are styling. It asks the question “who gets this style?”

🎨
selector {
  property: value;
}

CSS has many different types of selectors which target in a variety of ways. Let’s dive into each!

Step-by-Step Tutorial

Step 1: Element Selectors (Type Selectors)

Element selectors identify all HTML elements of a specified type.

🎨
h2 {
  color: #2c3e50;
  font-size: 28px;
  font-weight: bold;
  margin-bottom: 20px;
}

/* Targets ALL <body> elements (usually just one) */
body {
  font-family: 'Arial', sans-serif;
  padding: 40px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

What does it mean?

  • The selector is just the name of the element (there are no special characters)
  • h2 targets every  heading element on the page
  • body used to style the entirety of the page background and used to set default font 
  • Element selectors have low specificity (they’re the weakest) 


Pro Tip:
Use element selectors when you want to establish a baseline style that affects each instance of the element (i.e. the body font, default link color, etc.). 

Common Mistake: Element selectors will affect ALL instances of that element type. If you just want to style one specific paragraph, you need another type of selector! 

Step 2: Class Selectors - Reusable Styles

Class selectors target elements with a class attribute associated with that element. Class selectors begin with a period (.).

HTML:

🌐
<a href="#" class="styled-link" target="_blank">Visit Site</a>
<button class="styled-button">Click Me</button>

CSS:

🎨
.styled-link {
  display: inline-block;
  padding: 12px 24px;
  background-color: #3498db;
  color: white;
  text-decoration: none;
  border-radius: 8px;
  font-weight: bold;
  font-size: 16px;
  transition: all 0.3s ease;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

/* Targets elements with class="styled-button" */
.styled-button {
  padding: 12px 30px;
  background-color: #e74c3c;
  color: white;
  border: none;
  border-radius: 25px;
  font-size: 16px;
  font-weight: bold;
  cursor: pointer;
  transition: all 0.3s ease;
  box-shadow: 0 4px 15px rgba(231, 76, 60, 0.4);
}

Understanding Class Selectors:

  • HTML Side: Add class=”className” to any element 
  • CSS Side: Use .className to target it 
  • Reusability: Multiple elements can have the same class 
  • Specificity: More powerful than element selectors 

Note: You can specify multiple classes with one element: class=”styled-link important featured” 

Pro Tip: Use class names that describe the intention or purpose, and not the styles (blue-button vs. btn-primary). Your button could be a different color later!

Step 3: ID Selectors - Unique Identifiers

ID selectors identify a specific and unique element. They begin with a hash (#).

HTML:

🌐
<div id="main-container">Content here</div>

CSS:

🎨
#main-container {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
  background-color: white;
  border-radius: 12px;
}

Key Differences Between Classes and IDs:

Feature

Class (.className)

ID (#idName)

HTML Syntax

class=”name”

id=”name”

CSS Syntax

.name

#name

Reusability

Multiple elements can have it

Only ONE element should have it

Specificity

Medium

Very High

Best Use

Styling multiple similar elements

Unique sections or JavaScript hooks

The Most Important Rule: An ID should only be used ONCE per page. You can not use IDs to style several elements, instead use classes!

Pro Tip: A modern best practice is to use classes for all styling—ID’s should be reserved for JS functionality and page anchors.

Step 4: Universal Selector - Style Everything

The universal selector (*) targets ALL elements in the page.

🎨
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

When to Use:

  • Resetting default browser styling (known as “CSS Reset”)
  • Adding box-sizing universally
  • Adding properties to everything in the DOM


Warning:
Use sparingly, the universal can cause performance to degrade on a larger page because it targets every single element 

Note: box-sizing: border-box will allow width calculations easier by taking into account the padding and border in regards to total width.

Step 5: Grouping Selectors - DRY Principle

Grouping selectors is the methodology of using multiple selectors to get the same styles on a selector class. This follows the DRY guidelines (do not repeat yourself).

🎨
h1 {
  color: #2c3e50;
  font-family: 'Georgia', serif;
}

h2 {
  color: #2c3e50;
  font-family: 'Georgia', serif;
}
h3 {
  color: #2c3e50;
  font-family: 'Georgia', serif;
}
/* WITH Grouping (efficient) */
h1, h2, h3 {
  color: #2c3e50;
  font-family: 'Georgia', serif;
}
/* You can group any selectors */
.styled-link, .styled-button {
  transition: all 0.3s ease;  
font-weight: bold;
}

Grouping Rules:

  • Separate your selectors by commas
  • All the selectors are assigned the same style
  • You can still use each selector in CSS and add individual styles
  • Improves organization and reduces file size in your CSS.


Pro Tip:
Grouped selectors should use as many common properties as they can—and pull separate css afterwards (so you have a well organized manageable file).

Step 6: Attribute Selectors - Advanced Targeting

Attribute selectors are used to target elements by their attributes and their values.

HTML:

🌐
<input type="text" placeholder="Type here..."> <a href="https://example.com" target="_blank">External Link</a>

CSS:

🎨
input[type="text"] {
  padding: 12px 15px;
  border: 2px solid #bdc3c7;
  border-radius: 8px;
  font-size: 16px;
  width: 300px;
  transition: border-color 0.3s ease;
}
/* Targets links with target="_blank" (external links) */
a[target="_blank"] {
  color: #e67e22;
}
/* Targets links whose href starts with "https" */
a[href^="https"] {
  color: green;
}
/* Targets links whose href ends with ".pdf" */
a[href$=".pdf"] {
  color: red;
}
/* Targets elements whose class contains "button" */
[class*="button"] {
  cursor: pointer;
}

Attribute Selector Patterns:

Selector

Meaning

Example

[attr]

Has the attribute

[disabled]

[attr=”value”]

Exact match

[type=”text”]

[attr^=”value”]

Starts with

[href^=”https”]

[attr$=”value”]

Ends with

[href$=”.pdf”]

[attr*=”value”]

Contains anywhere

[class*=”btn”]

[attr~=”value”]

Contains word in space-separated list

[class~=”active”]

Note: Attribute selectors are very powerful for targeting form elements or links by their attributes!

Step 7: Pseudo-Classes - Interactive States

Pseudo-classes are used to select elements by their state or position. Pseudo-classes use a colon (:) to start off.

7a. The :hover Pseudo-Class

Applies styles when the pointer is hovering over an element.

🎨
.styled-link:hover {
  background-color: #2980b9;
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15);
}
.styled-button:hover {
  background-color: #c0392b;
  transform: scale(1.05);
  box-shadow: 0 6px 25px rgba(231, 76, 60, 0.6);
}

The hover effect applies:

  • Darker background color (a visual cue)
  • Slight increase in position or scaling (makes it feel alive)
  • Shadow increases (adds depth)
  • Smooth transition (This is due to the transition property we added earlier)


Pro Tip:
be sure to add hover states to interactive elements (links, buttons, etc.) because it enhances user experience by showing what they click on!

7b. The :active Pseudo-Class

:active has styles applied when an element is being clicked (the moment of activation).

🎨
.styled-button:active {
  transform: scale(0.98);
  box-shadow: 0 2px 10px rgba(231, 76, 60, 0.3);
}
.styled-link:active {
  transform: translateY(0);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

The active state happens:

  • A slight shrinkage of the button (makes it feel press down)
  • Shadow decreases (makes it feel pressed into the page)
  • Links reset their position
  • Makes the button feel like it has tactile feedback


Note:
:active only applies for the brief moment you are clicking. The moment you release, you will return to the normal state or possibly :hover state.

7c. The :focus Pseudo-Class

:focus applies styles when an element is receiving focus (important for form inputs).

🎨
input[type="text"]:focus {
  outline: none;
  border-color: #3498db;
  box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.2);
  background-color: #ecf9ff;
}

Focus Styling Provides:

  • Visual clue to signify which input field is active
  • Assists the user in understanding where they are typing
  • Very important for keyboard navigation
  • Enhances accessibility for all users


Accessibility Alert: If you remove the default outline, outline: none is used, you MUST provide an alternative focus (as we provided with border and shadow)!

7d. Other Useful Pseudo-Classes

🎨
a:visited {
  color: #9b59b6;
}
/* First child in a container */
li:first-child {
  font-weight: bold;
}
/* Last child in a container */
li:last-child {
  border-bottom: none;
}
/* Every nth element (useful for zebra striping) */
li:nth-child(odd) {
  background-color: #f8f9fa;
}
li:nth-child(even) {
  background-color: #e9ecef;
}
/* Elements that are disabled */
input:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
/* Elements that are checked (checkboxes/radio buttons) */
input:checked {
  background-color: #27ae60;
}

Pro Tip: Pseudo-classes are great for creating interactive experiences without using JavaScript!

Complete Code Example: Mini Project

Now, let’s put together a mini project that ties together all of the concepts!

HTML (Save as index.html)

🌐
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>CSS Selectors Mini Project</title>
  <link rel="stylesheet" href="CSS_Selectors.css">
</head>
<body>
  <div id="container">
    <h2>Mini Project: Buttons and Links</h2>
    <p class="intro-text">Explore different CSS selectors and interactive states!</p>
    
    <div class="demo-section">
      <h3>Styled Link</h3>
      <a href="#" class="styled-link" target="_blank">Visit Site</a>
    </div>
    
    <div class="demo-section">
      <h3>Styled Button</h3>
      <button class="styled-button">Click Me</button>
    </div>    
    <div class="demo-section">
      <h3>Text Input</h3>
      <input type="text" placeholder="Type here...">
    </div>
  </div>
</body>
</html>

CSS (Save as CSS_Selectors.css):

🎨
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

/* Element Selector - Body */
body {
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  padding: 40px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

/* ID Selector - Main Container */
#container {
  background-color: white;
  padding: 40px;
  border-radius: 20px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
  max-width: 600px;
  width: 100%;
}

/* Element Selector - Headings */
h2 {
  color: #2c3e50;
  font-size: 32px;
  margin-bottom: 10px;
  text-align: center;
}

h3 {
  color: #34495e;
  font-size: 18px;
  margin-bottom: 12px;
  font-weight: 600;
}
/* Class Selector - Intro Text */
.intro-text {
  text-align: center;
  color: #7f8c8d;
  margin-bottom: 30px;
  font-size: 16px;
}

/* Class Selector - Demo Sections */
.demo-section {
  margin-bottom: 30px;
  padding: 20px;
  background-color: #f8f9fa;
  border-radius: 12px;
  border-left: 4px solid #3498db;
}
/* Class Selector - Styled Link (Default State) */

.styled-link {
  display: inline-block;
  padding: 12px 24px;
  background-color: #3498db;
  color: white;
  text-decoration: none;
  border-radius: 8px;
  font-weight: bold;
  font-size: 16px;
  transition: all 0.3s ease;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

* Pseudo-class - Link Hover State */

.styled-link:hover {
  background-color: #2980b9;
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(52, 152, 219, 0.4);
}
/* Pseudo-class - Link Active State */
.styled-link:active {
  transform: translateY(0);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
/* Class Selector - Styled Button (Default State) */
.styled-button {
  padding: 12px 30px;
  background-color: #e74c3c;
  color: white;
  border: none;
  border-radius: 25px;
  font-size: 16px;
  font-weight: bold;
  cursor: pointer;
  transition: all 0.3s ease;
  box-shadow: 0 4px 15px rgba(231, 76, 60, 0.4);
}
/* Pseudo-class - Button Hover State */
.styled-button:hover {
  background-color: #c0392b;
  transform: scale(1.05);
  box-shadow: 0 6px 25px rgba(231, 76, 60, 0.6);
}
/* Pseudo-class - Button Active State */
.styled-button:active {
  transform: scale(0.98);
  box-shadow: 0 2px 10px rgba(231, 76, 60, 0.3);
}
/* Attribute Selector - Text Input (Default State) */
input[type="text"] {
  padding: 12px 15px;
  border: 2px solid #bdc3c7;
  border-radius: 8px;
  font-size: 16px;
  width: 100%;
  transition: all 0.3s ease;
  font-family: inherit;
}
/* Pseudo-class - Input Focus State */
input[type="text"]:focus {
  outline: none;
  border-color: #3498db;
  box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.2);
  background-color: #ecf9ff;
}
/* Pseudo-class - Input Placeholder */
input[type="text"]::placeholder {
  color: #95a5a6;
  font-style: italic;
}
/* Grouping Selector - Common Styles for Interactive Elements */
.styled-link, .styled-button {
  font-family: inherit;
  letter-spacing: 0.5px;
}
/* Responsive Design - Mobile Optimization */
@media (max-width: 600px) {
  body {
    padding: 20px;
 }  
  #container {“
    padding: 25px;
  }  
  h2 {
    font-size: 24px;
  }  
  .styled-link, .styled-button {
    width: 100%;
    text-align: center;
 }
}

Mini Project Output:

Code Explanation: How Everything Connects

The Selector Specificity Hierarchy

CSS relies on specificity to determine which styles should apply to an element with multiple rules targeting the same element class. Specificity is ranked from highest to lowest as follows:

Specificity Ranking: Highest to Lowest

  • Inline styles (style=”…”): Specificity is 1000
  • ID selectors (#id): Specificity is 100
  • Class selectors (.class), attribute selectors, pseudo-classes: Specificity is 10
  • Element selectors (div, p, a): Specificity is 1
  • Universal selector (*): Specificity is 0


Example:

🎨
/* Specificity: 1 */
a {
  color: black;
}

/* Specificity: 10 */
.styled-link {
  color: blue;
}

/* Specificity: 100 */
#special-link {
  color: red;
}

/* Specificity: 11 (class + pseudo-class) */
.styled-link:hover {
  color: green;
}

In the example of an <a> element with class=”styled-link and id=”special-link, if the styles for both provide a color definition, the <a> element will be red because the ID provides higher specificity.

Pro Tip: Don’t use IDs when they can be avoided – classes are much more manageable and flexible and allow for easier changes later!

Understanding the Cascade

When you have multiple rules that are ranked the same for specificity, CSS offers the following tiebreakers:

  1. Source Order: Because CSS is read top-down, a rule that is lower in the stylesheet overrides a rule higher up in the style sheet.
  2. !important: Forces a style to override everything! Use only when necessary!
🎨
/* First rule */
.styled-button {
  background-color: blue;
}

/* Second rule - this wins! */
.styled-button {
  background-color: red;
}

In the example of the button, the button is red because the second rule comes later in the style sheet.

Why Transitions Work Across States

Notice we added transition to the default state, not the hover state:

🎨
.styled-link {
  transition: all 0.3s ease; /* Defined here */
}

.styled-link:hover {
  background-color: #2980b9;
  transform: translateY(-2px);
  /* No transition needed here! */
}

Why?

  • Because transition will apply to all property changes
  • It doesn’t just work on entering changes but also exiting the :hover state
  • This creates smooth animations for moving both directions 

If we only put transition in :hover it would animate while hovering, but snap back instantly!

Attribute Selectors vs. Classes

When to use attribute selectors:

🎨
input[type="text"] { }  /* For form inputs */

a[target="_blank"] { }  /* For external links */

img[alt] { }            /* Images with alt text */

When to use classes:

🎨
.styled-button { }      /* Reusable component */

.error-message { }      /* Specific styling purpose */

.active { }             /* State indicator */

Tables of Key Concepts

1. Components / Keywords Used

Name

Description

*

Universal selector targeting all elements

element

Element/type selector targeting specific HTML tags

.className

Class selector targeting elements with specific class

#idName

ID selector targeting element with unique ID

[attribute]

Attribute selector targeting elements with specific attributes

[attribute=”value”]

Attribute selector with exact value match

[attribute^=”value”]

Attribute selector for values starting with string

[attribute$=”value”]

Attribute selector for values ending with string

[attribute*=”value”]

Attribute selector for values containing string

:hover

Pseudo-class for mouse hover state

:active

Pseudo-class for click/activation moment

:focus

Pseudo-class for focused/selected state

:visited

Pseudo-class for visited links

:first-child

Pseudo-class for first child element

:last-child

Pseudo-class for last child element

:nth-child()

Pseudo-class for nth child element

::placeholder

Pseudo-element for input placeholder text

, (comma)

Grouping operator for applying same styles to multiple selectors

transition

Property for smooth animations between states

transform

Property for moving, scaling, or rotating elements

box-shadow

Property for creating shadow effects

@media

At-rule for responsive design queries

2. Key Properties / Parameters / Features

Name

Description

display

Controls how element is rendered (block, inline, inline-block, flex)

inline-block

Display value allowing width/height on inline elements

padding

Space inside element between content and border

margin

Space outside element creating gaps between elements

border

Edge of element with width, style, and color

border-radius

Rounds corners of elements

border-left

Styles only left border (also: top, right, bottom)

background-color

Sets background color of element

color

Sets text color

font-size

Controls text size

font-weight

Controls text thickness (normal, bold, 100-900)

font-family

Specifies typeface/font to use

text-align

Aligns text (left, center, right, justify)

text-decoration

Controls text underlines, overlines, strikethroughs

cursor

Changes cursor appearance (pointer, not-allowed, etc.)

outline

Border-like outline that doesn’t affect layout

box-shadow

Creates shadow with x-offset, y-offset, blur, spread, and color

transition

Defines smooth animations: property duration timing-function

transform

Applies 2D/3D transformations (translate, scale, rotate)

translateY()

Transform function moving elements vertically

scale()

Transform function resizing elements

letter-spacing

Space between characters

max-width

Maximum width constraint

width

Element width (can use %, px, em, rem)

min-height

Minimum height constraint

justify-content

Flexbox property for horizontal alignment

align-items

Flexbox property for vertical alignment

ease

Timing function for natural-feeling transitions

inherit

Value that inherits property from parent element

rgba()

Color format with red, green, blue, alpha (transparency)

Your CSS Selector Arsenal 

You have everything you’ll need now to target any element:

Need

Use This Selector

Style all paragraphs

p { }

Style specific elements

.myClass { }

Style unique element

#myId { }

Style all text inputs

input[type=”text”] { }

Style external links

a[target=”_blank”] { }

Add hover effect

.element:hover { }

Style when clicked

.element:active { }

Style when focused

.element:focus { }

Style multiple elements

.class1, .class2 { }

Reset all elements

* { }

Useful References

Official Documentation & Standards


Learning Platforms & Tutorials


Selector Tools & Games


Interactive & Visual Guides


Pseudo-Classes & Advanced Selectors


Specificity & Cascade


Attribute Selectors


Best Practices & Methodology


Browser Compatibility


Practice & Challenges


Advanced Topics


Video Tutorials


Books


Communities


Design Inspiration

Source Code:

https://github.com/niotechoneSoftware/dotnet-developer-roadmap/tree/main/CSS-Fundamentals/Day%202%20-%20CSS%20-%20Selectors%20%26%20Elements

Summary – What You Learned

You will be learning how CSS Selectors and Elements work together to style a web page! CSS selectors are patterns that are used to find HTML elements that are specific for which you will input colors, spacing, fonts, and layout. The most common selectors are the element selectors which are the basic tag like h1 or p, class selectors which are styles that can be reused by multiple elements, and ID selectors which are unique to one element only. 

Output

Frequently Asked Questions FAQs

A CSS selector is a pattern used to select the HTML elements you want to style. It tells the browser which element(s) the CSS rules should apply to.

The most common selectors include:

  • Element Selector (p, h1, div)

  • Class Selector (.container, .btn)

  • ID Selector (#header, #main-title)

  • Universal Selector (*)

  • Group Selector (h1, h2, p)

Selectors allow you to precisely target elements and apply styles efficiently. Mastering them ensures clean, scalable, and maintainable CSS code.

Specificity determines which CSS rule wins when multiple rules target the same element.
Specificity order (highest → lowest):

  1. Inline styles

  2. IDs

  3. Classes, attributes, pseudo-classes

  4. Elements, pseudo-elements

You can continue with:

  • CSS Box Model

  • CSS Display & Positioning

  • Flexbox & Grid

  • Responsive CSS

  • CSS Animations

These concepts help you build modern, responsive, and visually appealing layouts.