We are still cooking the magic in the way!
Simple Selectors: Type, Class & ID
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;
}
body, h1-h6, p, a, img, ul, and ol before moving on to class-based component styles.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>
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
!importantflag. 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> */
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 */
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;
}
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;
}
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
3columnis invalid, butcol-3is valid. - They are case-sensitive:
.Cardand.cardare 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;
}
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
.notificationbase class with padding, border-radius, and margin. - Three modifier classes:
.notification--success(green),.notification--warning(yellow), and.notification--error(red). - A
.notification__titleclass for the heading inside each notification. - A
.notification__messageclass 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
altattribute differently from those that do not. - Style form inputs based on their
typeattribute (text, email, password, checkbox). - Style elements with a
data-statusattribute containing the word "active".