CSS3 & Responsive Design

Simple Selectors: Type, Class & ID

25 min Lesson 3 of 60

Understanding CSS Selectors

Selectors are the targeting mechanism of CSS. Every ruleset you write begins with a selector that tells the browser exactly which HTML elements should receive the styles defined in the declaration block. Without selectors, CSS would have no way to know where to apply your styles. Think of selectors as addresses on envelopes -- they direct your styling instructions to the correct destination on the page.

CSS offers a rich variety of selector types, from simple tag-name selectors to highly sophisticated combinators and pseudo-classes. In this lesson, we focus on the simple selectors -- the foundational building blocks you will use in virtually every stylesheet you write. Mastering these gives you the ability to target any element on a page with precision and clarity.

The simple selectors we will cover are: type selectors, class selectors, ID selectors, the universal selector, attribute selectors, and grouping selectors. Each has a distinct purpose, syntax, and set of best practices. By the end of this lesson, you will know when to use each one and how to combine them effectively.

Type Selectors (Element Selectors)

The type selector, also called an element selector or tag selector, targets every instance of a specific HTML element on the page. You simply write the tag name -- no special characters, no prefixes -- and every element of that type receives the declared styles.

Type Selector Syntax

/* Targets ALL <h1> elements on the page */
h1 {
    color: #1a1a2e;
    font-size: 2.5rem;
    font-weight: 700;
    margin-bottom: 16px;
}

/* Targets ALL <p> elements on the page */
p {
    color: #444444;
    font-size: 1rem;
    line-height: 1.8;
    margin-bottom: 12px;
}

/* Targets ALL <div> elements on the page */
div {
    padding: 10px;
    box-sizing: border-box;
}

Type selectors are broad by nature. When you write p { color: #444; }, you are telling the browser to apply that color to every single paragraph on the page -- there are no exceptions. This makes type selectors ideal for setting base styles that establish a consistent foundation across your entire website. For example, you might use type selectors to define default font sizes for headings, line heights for paragraphs, and border behavior for images.

Setting Base Styles with Type Selectors

/* Base typography styles */
body {
    font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
    color: #333333;
    line-height: 1.6;
    margin: 0;
    padding: 0;
}

h1 { font-size: 2.5rem; margin-bottom: 20px; }
h2 { font-size: 2rem; margin-bottom: 16px; }
h3 { font-size: 1.5rem; margin-bottom: 12px; }
h4 { font-size: 1.25rem; margin-bottom: 10px; }

p { margin-bottom: 1em; }

a {
    color: #0066cc;
    text-decoration: none;
}

img {
    max-width: 100%;
    height: auto;
    display: block;
}

ul, ol {
    padding-left: 1.5em;
    margin-bottom: 1em;
}
Tip: Type selectors are perfect for creating a CSS "reset" or "normalize" baseline at the top of your stylesheet. By establishing consistent default styles for common HTML elements, you prevent browser inconsistencies from affecting your design. Many professional stylesheets begin with type-selector rules for body, h1-h6, p, a, img, ul, and ol before moving on to class-based component styles.
Warning: Because type selectors target every instance of an element, they can produce unintended side effects in large projects. If you write div { border: 1px solid red; }, every <div> on the page -- including those inside third-party components, modals, and navigation bars -- will get a red border. Use type selectors deliberately for global defaults, and rely on classes for component-specific styles.

Class Selectors

The class selector is the workhorse of modern CSS. It targets elements that have a specific value in their class attribute. You write a class selector by prefixing the class name with a period (.). Unlike type selectors, class selectors only affect elements that explicitly opt in by including that class in their HTML.

Class Selector Syntax

/* CSS */
.card {
    background-color: #ffffff;
    border: 1px solid #e0e0e0;
    border-radius: 8px;
    padding: 24px;
    margin-bottom: 20px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
}

.highlight {
    background-color: #fff3cd;
    border-left: 4px solid #ffc107;
    padding: 12px 16px;
}

.text-center {
    text-align: center;
}

Using Classes in HTML

<!-- This div receives the .card styles -->
<div class="card">
    <h3>Article Title</h3>
    <p>Some article content here.</p>
</div>

<!-- This paragraph receives the .highlight styles -->
<p class="highlight">This is an important notice.</p>

<!-- This div has NO class, so it gets no class-based styles -->
<div>
    <p>This is unstyled by the above rules.</p>
</div>

Multiple Classes on a Single Element

One of the most powerful features of class selectors is that a single HTML element can have multiple classes. You simply separate each class name with a space inside the class attribute. The element receives styles from all of the listed classes simultaneously. This promotes composition -- building complex appearances by combining small, focused utility classes.

Multiple Classes Example

/* CSS - small, focused classes */
.card {
    background: #ffffff;
    border: 1px solid #ddd;
    border-radius: 8px;
    padding: 20px;
}

.shadow {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.rounded-lg {
    border-radius: 16px;
}

.mb-4 {
    margin-bottom: 2rem;
}

.text-primary {
    color: #0066cc;
}

Applying Multiple Classes in HTML

<!-- This element receives styles from ALL four classes -->
<div class="card shadow rounded-lg mb-4">
    <h3 class="text-primary">Premium Feature</h3>
    <p>This card has rounded corners, a shadow, and bottom margin.</p>
</div>

<!-- Same card component, different combination -->
<div class="card mb-4">
    <h3>Basic Feature</h3>
    <p>This card has no shadow or extra rounding.</p>
</div>
Note: The order of class names in the HTML class attribute does not determine which styles take priority. If two classes set the same property, the class that appears later in the CSS stylesheet wins (assuming equal specificity). The HTML order is irrelevant -- only the CSS source order matters.

Chaining Classes for Precision

You can chain multiple class selectors together in your CSS (without spaces) to target only elements that have all of the specified classes. This is a powerful technique for creating modifier patterns and conditional styles.

Chaining Class Selectors

/* Targets elements with BOTH .btn AND .btn-primary classes */
.btn.btn-primary {
    background-color: #0066cc;
    color: #ffffff;
    border: none;
}

/* Targets elements with BOTH .btn AND .btn-danger classes */
.btn.btn-danger {
    background-color: #dc3545;
    color: #ffffff;
    border: none;
}

/* Targets elements with .card AND .featured AND .large */
.card.featured.large {
    border: 2px solid gold;
    padding: 40px;
    font-size: 1.2em;
}

Chaining in HTML

<!-- Matches .btn.btn-primary -->
<button class="btn btn-primary">Submit</button>

<!-- Matches .btn.btn-danger -->
<button class="btn btn-danger">Delete</button>

<!-- Matches .card.featured.large -->
<div class="card featured large">
    <h3>Special Offer</h3>
</div>

<!-- Does NOT match .card.featured.large (missing .large) -->
<div class="card featured">
    <h3>Regular Offer</h3>
</div>

ID Selectors

The ID selector targets a single, unique element on the page. You write it by prefixing the ID name with a hash symbol (#). In valid HTML, every id attribute value must be unique within a document -- no two elements may share the same ID. This makes ID selectors the most specific of the simple selectors.

ID Selector Syntax

/* CSS */
#main-header {
    background-color: #1a1a2e;
    color: #ffffff;
    padding: 20px 40px;
    position: sticky;
    top: 0;
    z-index: 1000;
}

#hero-section {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    min-height: 80vh;
    display: flex;
    align-items: center;
    justify-content: center;
}

#footer {
    background-color: #2d2d2d;
    color: #cccccc;
    padding: 40px;
    text-align: center;
}

Using IDs in HTML

<header id="main-header">
    <nav>...</nav>
</header>

<section id="hero-section">
    <h1>Welcome to My Website</h1>
</section>

<footer id="footer">
    <p>Copyright 2025</p>
</footer>

Class vs ID: Best Practices

One of the most common questions beginners ask is: "When should I use a class and when should I use an ID?" Here is a clear decision framework:

  • Use classes for styling. Classes are reusable, composable, and have moderate specificity. They are the standard tool for all visual styling in modern CSS.
  • Use IDs for JavaScript hooks and anchor links. IDs are ideal for document.getElementById() in JavaScript and for creating anchor links (<a href="#section-name">). They are also used by the HTML <label for="..."> attribute to connect labels to form inputs.
  • Avoid IDs for styling whenever possible. ID selectors have very high specificity (we will cover specificity in a later lesson), which makes them difficult to override without resorting to other high-specificity selectors or the !important flag. This can lead to "specificity wars" that make your CSS harder to maintain.
  • IDs cannot be reused. If you style something with an ID and later need the same style on another element, you will have to refactor. Classes avoid this problem entirely because they are designed for reuse.

Class vs ID Comparison

/* BAD: Using IDs for styling (hard to reuse and override) */
#submit-button {
    background-color: #0066cc;
    color: white;
    padding: 10px 24px;
    border: none;
    border-radius: 4px;
}

/* GOOD: Using a class for styling (reusable) */
.btn-primary {
    background-color: #0066cc;
    color: white;
    padding: 10px 24px;
    border: none;
    border-radius: 4px;
}

/* Now ANY button can use this style: */
/* <button class="btn-primary">Submit</button> */
/* <button class="btn-primary">Save</button> */
/* <a class="btn-primary" href="#">Learn More</a> */
Warning: Using the same ID on multiple elements is invalid HTML. While browsers may still render the page, JavaScript methods like document.getElementById() will only find the first occurrence, and CSS behavior becomes unpredictable. Always keep IDs unique within a page.

The Universal Selector

The universal selector (*) matches every single element on the page, regardless of its type, class, or ID. It is the broadest possible selector. While it has limited use in production styling, it serves several important purposes in development and base-level resets.

Universal Selector Syntax

/* Applies to EVERY element on the page */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

/* This is one of the most common uses:
   the "box-sizing reset" ensures all elements
   include padding and border in their total width/height */

The most famous use of the universal selector is the box-sizing reset. By default, the CSS box model calculates an element's total width as width + padding + border, which leads to confusing sizing calculations. Setting box-sizing: border-box on all elements via the universal selector changes this so that width is the total width including padding and border. Nearly every modern CSS framework and professional stylesheet includes this reset.

The Modern Box-Sizing Reset

/* The recommended approach: inherit from html */
html {
    box-sizing: border-box;
}

*, *::before, *::after {
    box-sizing: inherit;
}

/* This pattern lets individual components opt out if needed
   by setting box-sizing: content-box on a parent element */
Tip: The universal selector has very low specificity (essentially zero), so any other selector will easily override it. This makes it safe for global resets -- your component-specific styles will always take priority without any specificity conflicts.

Attribute Selectors

Attribute selectors target elements based on the presence or value of their HTML attributes. They are written inside square brackets [ ] and offer remarkable flexibility for targeting elements without needing to add extra classes or IDs. Attribute selectors are particularly useful for styling form elements, links, and any HTML that uses custom data-* attributes.

Basic Attribute Presence: [attr]

The simplest form selects elements that have a specific attribute, regardless of the attribute's value.

Attribute Presence Selector

/* Targets any element that has a "title" attribute */
[title] {
    cursor: help;
    border-bottom: 1px dotted #999;
}

/* Targets any element with a "required" attribute */
[required] {
    border-color: #cc0000;
}

/* Targets any element with a "disabled" attribute */
[disabled] {
    opacity: 0.5;
    cursor: not-allowed;
}

HTML for Attribute Presence

<!-- Matched by [title] -->
<abbr title="HyperText Markup Language">HTML</abbr>

<!-- Matched by [required] -->
<input type="email" required>

<!-- Matched by [disabled] -->
<button disabled>Cannot Click</button>

<!-- NOT matched by any of the above (no title, required, or disabled) -->
<p>Regular paragraph</p>

Exact Value Match: [attr=val]

This form selects elements where the attribute equals a specific value exactly.

Exact Value Attribute Selector

/* Targets <input> elements with type="email" */
[type="email"] {
    background-image: url("email-icon.svg");
    background-repeat: no-repeat;
    background-position: right 10px center;
    padding-right: 36px;
}

/* Targets <input> elements with type="password" */
[type="password"] {
    letter-spacing: 0.3em;
}

/* Targets elements with a specific data attribute value */
[data-theme="dark"] {
    background-color: #1a1a2e;
    color: #e0e0e0;
}

[data-theme="light"] {
    background-color: #ffffff;
    color: #333333;
}

Whitespace-Separated Value: [attr~=val]

This selector matches elements where the attribute value is a whitespace-separated list of words, and one of those words is exactly the specified value. This is different from exact match because it works with multi-word attribute values.

Whitespace-Separated Attribute Selector

/* Targets elements whose "class" attribute contains the word "featured" */
[class~="featured"] {
    border: 2px solid gold;
}

/* Targets elements whose "rel" attribute contains the word "noopener" */
[rel~="noopener"] {
    /* Style external links */
    color: #cc6600;
}

HTML for ~= Selector

<!-- Matched: "featured" is one of the space-separated words -->
<div class="card featured large">Special</div>

<!-- NOT matched: "featured-item" is not the exact word "featured" -->
<div class="card featured-item">Not matched</div>

<!-- Matched: "noopener" is in the rel list -->
<a href="#" rel="noopener noreferrer">External Link</a>

Prefix Match: [attr^=val]

The caret-equals selector matches elements whose attribute value starts with the specified string. This is extremely useful for targeting links based on their protocol or targeting elements with systematic naming conventions.

Prefix Attribute Selector

/* Targets links that start with "https" */
[href^="https"] {
    color: green;
}

/* Targets links that start with "http" (not secure) */
[href^="http:"] {
    color: red;
}

/* Targets links that start with "mailto:" */
[href^="mailto:"] {
    background-image: url("mail-icon.svg");
    padding-left: 20px;
}

/* Targets links that start with "tel:" */
[href^="tel:"] {
    background-image: url("phone-icon.svg");
    padding-left: 20px;
}

/* Targets elements whose class starts with "col-" */
[class^="col-"] {
    float: left;
    padding: 0 15px;
}

Suffix Match: [attr$=val]

The dollar-equals selector matches elements whose attribute value ends with the specified string. This is particularly useful for styling links based on their file extension.

Suffix Attribute Selector

/* Targets links to PDF files */
[href$=".pdf"] {
    background-image: url("pdf-icon.svg");
    padding-right: 20px;
    color: #cc0000;
}

/* Targets links to image files */
[href$=".jpg"],
[href$=".png"],
[href$=".gif"] {
    border-bottom: 2px solid #0066cc;
}

/* Targets links to external documents */
[href$=".doc"],
[href$=".docx"] {
    background-image: url("word-icon.svg");
    padding-right: 20px;
}

Substring Match: [attr*=val]

The asterisk-equals selector matches elements whose attribute value contains the specified string anywhere within it. This is the most flexible attribute selector, but use it carefully to avoid overly broad matches.

Substring Attribute Selector

/* Targets any link containing "youtube" in the href */
[href*="youtube"] {
    color: #ff0000;
}

/* Targets any link containing "github" in the href */
[href*="github"] {
    color: #333;
    font-family: monospace;
}

/* Targets elements with "btn" anywhere in their class */
[class*="btn"] {
    cursor: pointer;
    display: inline-block;
    text-align: center;
}
Note: Attribute selectors are case-sensitive by default for attribute values. If you need case-insensitive matching, add the i flag before the closing bracket: [href$=".PDF" i] will match both .pdf and .PDF. This is a CSS Selectors Level 4 feature supported in all modern browsers.

Case-Insensitive Attribute Selector

/* Matches .pdf, .PDF, .Pdf, etc. */
[href$=".pdf" i] {
    color: #cc0000;
}

/* Matches type="TEXT", type="text", type="Text", etc. */
[type="text" i] {
    border: 1px solid #ccc;
}

Grouping Selectors with Commas

When multiple selectors need the same set of styles, you can group them together by separating them with commas. This avoids duplicating identical declaration blocks and keeps your CSS concise. Grouping works with any type of selector -- type selectors, class selectors, ID selectors, attribute selectors, or any combination.

Grouping Selectors

/* WITHOUT grouping: repetitive and wasteful */
h1 {
    font-family: Georgia, serif;
    color: #1a1a2e;
}
h2 {
    font-family: Georgia, serif;
    color: #1a1a2e;
}
h3 {
    font-family: Georgia, serif;
    color: #1a1a2e;
}

/* WITH grouping: clean and maintainable */
h1, h2, h3 {
    font-family: Georgia, serif;
    color: #1a1a2e;
}

/* Grouping different selector types */
h1, .page-title, #main-heading {
    font-size: 2rem;
    font-weight: 700;
    line-height: 1.2;
}

/* Grouping with attribute selectors */
[type="text"],
[type="email"],
[type="password"],
[type="tel"],
[type="url"] {
    width: 100%;
    padding: 10px 14px;
    border: 1px solid #ccc;
    border-radius: 4px;
    font-size: 1rem;
}
Tip: When grouping selectors, place each selector on its own line for readability. This makes it easy to add or remove selectors later and helps with version control (each change shows as a clear line addition or removal in git diffs).
Warning: If any selector in a grouped list is invalid, the entire rule is discarded in standard CSS. For example, h1, h2:unknown-pseudo, h3 { color: red; } would not apply to any of the three selectors because h2:unknown-pseudo is invalid. This is a common source of bugs, so always double-check your grouped selectors.

Naming Conventions

Choosing good class names and ID names is a critical skill that directly impacts the readability and maintainability of your code. Poor naming leads to confusion, while thoughtful naming makes your stylesheets self-documenting.

Rules for Valid CSS Names

  • Class and ID names can contain letters, digits, hyphens (-), and underscores (_).
  • They must not start with a digit. The name 3column is invalid, but col-3 is valid.
  • They are case-sensitive: .Card and .card are two different selectors.
  • Avoid special characters, spaces, and punctuation other than hyphens and underscores.

Popular Naming Conventions

Kebab-Case (Recommended)

/* The most common convention in CSS */
.nav-bar { }
.hero-section { }
.card-title { }
.btn-primary { }
.form-input-group { }
.footer-social-links { }

BEM (Block Element Modifier)

/* A popular methodology for large projects */
/* Block: the component name */
.card { }

/* Element: a part of the block, separated by __ */
.card__title { }
.card__image { }
.card__body { }

/* Modifier: a variation, separated by -- */
.card--featured { }
.card--compact { }
.card__title--large { }

CamelCase (Less Common in CSS)

/* More common in JavaScript, occasionally used in CSS */
.navBar { }
.heroSection { }
.cardTitle { }

The kebab-case convention (words separated by hyphens) is the most widely used in CSS because it is easy to read, consistent with CSS property names (which are all kebab-case, like font-size, background-color), and supported by every CSS tooling ecosystem. The BEM methodology (Block Element Modifier) is popular on larger projects because it creates a clear relationship between components and their parts.

Semantic vs Presentational Names

Always prefer semantic names (what the element is or does) over presentational names (what it looks like). Presentational names break down when designs change.

Semantic vs Presentational Naming

/* BAD: Presentational names (describe appearance) */
.red-text { color: red; }
.big-font { font-size: 2rem; }
.left-box { float: left; width: 50%; }
.blue-button { background: blue; }

/* What happens when the designer changes the button to green?
   You either rename the class everywhere (painful) or have a
   class called .blue-button that is actually green (confusing). */

/* GOOD: Semantic names (describe purpose) */
.error-message { color: red; }
.page-title { font-size: 2rem; }
.sidebar { float: left; width: 50%; }
.btn-primary { background: blue; }

/* When the primary color changes to green, the class name
   still makes perfect sense. */

Combining Selector Types

You can combine different types of simple selectors to create more targeted rules. When you write selectors together without a space, you are specifying multiple conditions that an element must meet simultaneously.

Combining Type and Class Selectors

/* Only <p> elements with class "intro" */
p.intro {
    font-size: 1.25rem;
    font-style: italic;
    color: #555;
}

/* Only <a> elements with class "nav-link" */
a.nav-link {
    text-decoration: none;
    padding: 8px 16px;
    color: #333;
}

/* Only <input> elements with class "large" */
input.large {
    font-size: 1.25rem;
    padding: 14px 18px;
}

/* Only <div> elements with class "container" */
div.container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 20px;
}

Combining Type and Attribute Selectors

/* Only <input> elements with type="text" */
input[type="text"] {
    border: 2px solid #ccc;
    border-radius: 4px;
}

/* Only <a> elements with href starting with "https" */
a[href^="https"] {
    color: green;
    font-weight: bold;
}

/* Only <img> elements with an alt attribute */
img[alt] {
    border: 2px solid transparent;
}

/* Only <img> elements WITHOUT an alt attribute (accessibility check) */
img:not([alt]) {
    border: 4px solid red;
    outline: 2px dashed red;
}

Combining Multiple Conditions

/* <input> with type="email" AND class="large" AND required attribute */
input[type="email"].large[required] {
    border: 2px solid #0066cc;
    font-size: 1.25rem;
    padding: 12px;
}

/* <a> elements with class "btn" and href ending in ".pdf" */
a.btn[href$=".pdf"] {
    background-color: #cc0000;
    color: white;
    padding: 8px 16px;
}
Note: When combining type selectors with class or attribute selectors, the type selector always comes first: p.intro is correct, while .intro p means something entirely different (it is a descendant combinator targeting <p> elements inside an element with class .intro). We will cover combinators in a later lesson.

Selector Specificity Overview

Different selector types have different specificity weights, which determine which styles win when multiple rules target the same element. Here is a quick overview of specificity for the selectors we have covered (we will explore specificity in full detail in a dedicated lesson):

  • Universal selector (*) -- Specificity: 0-0-0 (no weight)
  • Type selectors (h1, p, div) -- Specificity: 0-0-1
  • Class selectors (.card) -- Specificity: 0-1-0
  • Attribute selectors ([type="text"]) -- Specificity: 0-1-0 (same as classes)
  • ID selectors (#header) -- Specificity: 1-0-0

A class selector is 10 times more specific than a type selector, and an ID selector is 10 times more specific than a class selector. When two rules conflict, the one with higher specificity wins, regardless of source order.

Specificity in Action

/* Specificity: 0-0-1 (type selector) */
p {
    color: black;
}

/* Specificity: 0-1-0 (class selector -- WINS over type) */
.highlight {
    color: orange;
}

/* Specificity: 1-0-0 (ID selector -- WINS over class) */
#special-text {
    color: red;
}

/* For <p class="highlight" id="special-text">
   The text will be RED because #special-text has highest specificity */

Practical Patterns and Real-World Examples

Let us put everything together with a comprehensive example that uses all the selector types we have covered in a realistic webpage scenario.

Complete Real-World Example

/* === GLOBAL RESET (Universal Selector) === */
*, *::before, *::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

/* === BASE STYLES (Type Selectors) === */
body {
    font-family: "Inter", -apple-system, sans-serif;
    color: #333;
    line-height: 1.6;
}

h1, h2, h3 {
    line-height: 1.3;
    margin-bottom: 0.75em;
}

a { color: #0066cc; text-decoration: none; }
a:hover { text-decoration: underline; }

img { max-width: 100%; height: auto; }

/* === COMPONENT STYLES (Class Selectors) === */
.container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 20px;
}

.nav-link {
    display: inline-block;
    padding: 8px 16px;
    color: #555;
    font-weight: 500;
}

.card {
    background: #fff;
    border: 1px solid #e5e5e5;
    border-radius: 8px;
    padding: 24px;
    margin-bottom: 20px;
}

.card.featured {
    border-color: gold;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
}

.btn {
    display: inline-block;
    padding: 10px 24px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 1rem;
}

.btn.btn-primary { background: #0066cc; color: #fff; }
.btn.btn-secondary { background: #6c757d; color: #fff; }

/* === LANDMARK STYLES (ID Selectors) === */
#site-header {
    position: sticky;
    top: 0;
    background: #fff;
    border-bottom: 1px solid #eee;
    z-index: 100;
}

/* === FORM STYLES (Attribute Selectors) === */
[type="text"],
[type="email"],
[type="password"] {
    width: 100%;
    padding: 10px;
    border: 1px solid #ccc;
    border-radius: 4px;
}

[required] {
    border-left: 3px solid #0066cc;
}

/* External links get an icon */
a[href^="http"]:not([href*="mysite.com"]) {
    padding-right: 16px;
    background: url("external-icon.svg") no-repeat right center;
    background-size: 12px;
}

Practice Exercise 1: Selector Identification

Look at the following CSS rules and identify the type of each selector. Then determine which HTML elements each rule would match:

/* 1 */ article { border-bottom: 1px solid #eee; }
/* 2 */ .sidebar { width: 300px; float: right; }
/* 3 */ #main-content { flex: 1; }
/* 4 */ * { font-family: sans-serif; }
/* 5 */ [data-visible="true"] { display: block; }
/* 6 */ h1, h2, .section-title { color: navy; }
/* 7 */ input.search-box[type="text"] { border-radius: 20px; }
/* 8 */ a[href$=".pdf"] { color: red; }

Answers: (1) Type selector -- all <article> elements. (2) Class selector -- elements with class="sidebar". (3) ID selector -- the element with id="main-content". (4) Universal selector -- every element. (5) Attribute selector (exact match) -- elements with data-visible="true". (6) Grouped selectors -- all <h1>, <h2>, and .section-title elements. (7) Combined type + class + attribute -- an <input> with class search-box and type="text". (8) Attribute suffix selector -- links whose href ends with .pdf.

Practice Exercise 2: Build a Styled Component

Create a notification component using the selector techniques from this lesson. Write both the HTML and CSS for the following requirements:

  • A .notification base class with padding, border-radius, and margin.
  • Three modifier classes: .notification--success (green), .notification--warning (yellow), and .notification--error (red).
  • A .notification__title class for the heading inside each notification.
  • A .notification__message class for the body text.
  • Use the [data-dismissible="true"] attribute selector to add a close button style.

Try writing this yourself before looking at any solution. This exercise reinforces class naming with BEM convention, attribute selectors, and combining selector types.

Practice Exercise 3: Attribute Selector Challenge

Write CSS rules using only attribute selectors for the following scenarios:

  • Style all links that point to external sites (hint: they start with http).
  • Style all links that point to email addresses (hint: they start with mailto:).
  • Style all images that have an alt attribute differently from those that do not.
  • Style form inputs based on their type attribute (text, email, password, checkbox).
  • Style elements with a data-status attribute containing the word "active".

ES
Edrees Salih
9 hours ago

We are still cooking the magic in the way!