CSS - Basics

Learn the Essentials of CSS – From Syntax and Selectors to Text Styling and Selector Precedence.

CSS - Basics

Introduction to CSS and Why it is Important

Cascading Style Sheets (CSS) is a styling language used to describe the presentation of HTML documents. CSS separates content (HTML) from presentation, allowing developers to control layout, colors, fonts, and visual effects across multiple web pages simultaneously.

CSS is essential because it:

  • Improves website maintainability by centralizing style rules

  • Enhances user experience through consistent visual presentation

  • Reduces page load times by eliminating redundant styling code

  • Enables responsive design for different screen sizes and devices

Before CSS, styling was done directly in HTML using presentational elements and attributes, resulting in bloated, difficult-to-maintain code. Consider these examples:

Example 1: Styling without CSS (Old approach)

<font face="Arial" color="blue" size="4">
  <p align="center"><b>Welcome to my website!</b></p>
</font>

Example 2: Styling with CSS (Modern approach)

<p class="welcome-message">Welcome to my website!</p>
.welcome-message {
  font-family: Arial;
  color: blue;
  font-size: 18px;
  text-align: center;
  font-weight: bold;
}

Tips and Tricks:

  1. Start learning CSS by understanding the box model (margin, padding, border, content).

  2. Use CSS resets or normalizers to ensure consistent rendering across browsers.

  3. Leverage CSS frameworks like Bootstrap or Tailwind CSS to speed up development while learning the fundamentals.

Understanding Syntax, Selectors and Comments in CSS

CSS Syntax

CSS rules consist of selectors and declarations. The selector points to the HTML element you want to style, while declarations define the property and its value.

Basic syntax: selector { property: value; }

Example 1: Basic CSS Rule

p {
  color: navy;
  font-size: 16px;
}

This applies navy text color and 16px font size to all paragraph elements.

Example 2: Multiple Selectors

h1, h2, h3 {
  font-family: 'Georgia', serif;
  margin-top: 20px;
}

This applies the same styling to h1, h2, and h3 elements.

CSS Selectors

Selectors are patterns that match HTML elements to apply styles. Different types of selectors offer varying levels of specificity.

Common Selector Types:

  • Element selectors: p, div, h1

  • Class selectors: .classname

  • ID selectors: #idname

  • Attribute selectors: input[type="text"]

  • Pseudo-classes: :hover, :active, :nth-child()

  • Pseudo-elements: ::before, ::after

Example 1: Using Different Selectors

/* Element selector */
p {
  line-height: 1.6;
}

/* Class selector */
.highlight {
  background-color: yellow;
}

/* ID selector */
#header {
  position: sticky;
  top: 0;
}

Example 2: Advanced Selectors

/* Descendant selector */
article p {
  font-style: italic;
}

/* Child selector */
ul > li {
  list-style-type: square;
}

/* Attribute selector */
a[target="_blank"] {
  background: url('external-link.png') no-repeat right top;
  padding-right: 20px;
}

CSS Comments

Comments in CSS are used to document your code or temporarily disable styles. They're ignored by browsers.

Syntax: /* Comment goes here */

Example 1: Documenting Sections

/* Header Styles */
header {
  background-color: #333;
  color: white;
}

/* Navigation Menu */
nav {
  display: flex;
  justify-content: space-between;
}

Example 2: Commenting Out Code

.container {
  width: 80%;
  margin: 0 auto;
  /* Temporarily disabled:
  max-width: 1200px;
  border: 1px solid #ddd;
  */
}

Tips and Tricks:

  1. Use meaningful names for classes and IDs that describe purpose rather than appearance.

  2. Group related selectors and properties for better readability.

  3. Comment your CSS, especially for complex layouts or when using non-standard techniques.

Adding CSS to HTML Page - Inline, Internal, External

There are three methods to incorporate CSS into HTML documents, each with its own use cases.

1. Inline CSS

Inline CSS applies styles directly to individual HTML elements using the style attribute. This method has the highest specificity and overrides other styles.

Example 1: Styling a Paragraph Inline

<p style="color: red; font-size: 18px; margin-left: 20px;">
  This paragraph has inline styling applied.
</p>

Example 2: Inline CSS for a One-off Element

<div style="display: flex; justify-content: center; background-color: #f0f0f0; padding: 15px;">
  <img src="logo.png" alt="Company Logo" style="max-width: 200px; height: auto;">
</div>

Output: Both examples produce elements with styles applied directly to them, overriding any external or internal CSS rules for those specific elements.

2. Internal (Embedded) CSS

Internal CSS is defined within a <style> element in the <head> section of an HTML document. It applies to that specific page only.

Example 1: Basic Internal Stylesheet

<!DOCTYPE html>
<html>
<head>
  <title>Internal CSS Example</title>
  <style>
    body {
      font-family: 'Helvetica', sans-serif;
      line-height: 1.6;
      color: #333;
    }
    .container {
      width: 80%;
      margin: 0 auto;
    }
    h1 {
      color: #0066cc;
      border-bottom: 2px solid #eee;
    }
  </style>
</head>
<body>
  <div class="container">
    <h1>Welcome to My Website</h1>
    <p>This page uses internal CSS styling.</p>
  </div>
</body>
</html>

Example 2: Using Media Queries in Internal CSS

<!DOCTYPE html>
<html>
<head>
  <title>Responsive Internal CSS</title>
  <style>
    .flex-container {
      display: flex;
      flex-wrap: wrap;
    }
    .box {
      flex: 1;
      padding: 20px;
      background-color: #e0e0e0;
      margin: 10px;
    }

    /* Responsive styles */
    @media (max-width: 768px) {
      .box {
        flex: 100%;
      }
    }
  </style>
</head>
<body>
  <div class="flex-container">
    <div class="box">Box 1</div>
    <div class="box">Box 2</div>
    <div class="box">Box 3</div>
  </div>
</body>
</html>

Output: Internal CSS applies to all matching elements on the page, creating consistent styling throughout that specific document.

3. External CSS

External CSS places styles in a separate .css file that's linked to HTML documents using the <link> element. This is the most maintainable approach for multi-page websites.

Example 1: Basic External CSS Setup

HTML file (index.html):

<!DOCTYPE html>
<html>
<head>
  <title>External CSS Example</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <header>
    <h1>My Website</h1>
    <nav>
      <ul>
        <li><a href="#">Home</a></li>
        <li><a href="#">About</a></li>
        <li><a href="#">Contact</a></li>
      </ul>
    </nav>
  </header>
  <main>
    <article>
      <h2>Welcome to my site</h2>
      <p>This site uses external CSS for styling.</p>
    </article>
  </main>
</body>
</html>

CSS file (styles.css):

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

/* Typography */
body {
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  line-height: 1.6;
  color: #333;
}

/* Layout */
header {
  background-color: #2c3e50;
  color: white;
  padding: 1rem;
}

nav ul {
  display: flex;
  list-style: none;
}

nav li {
  margin-right: 1rem;
}

nav a {
  color: white;
  text-decoration: none;
}

main {
  max-width: 1200px;
  margin: 0 auto;
  padding: 2rem;
}

Example 2: Multiple Stylesheets

HTML file:

<!DOCTYPE html>
<html>
<head>
  <title>Multiple External Stylesheets</title>
  <!-- Base styles -->
  <link rel="stylesheet" href="normalize.css">
  <link rel="stylesheet" href="base.css">
  <!-- Component-specific styles -->
  <link rel="stylesheet" href="components/navigation.css">
  <link rel="stylesheet" href="components/forms.css">
  <!-- Page-specific styles -->
  <link rel="stylesheet" href="pages/contact.css">
</head>
<body>
  <!-- Page content -->
</body>
</html>

Output: External CSS provides consistent styling across multiple HTML pages, with changes to the stylesheet reflected everywhere it's linked.

Tips and Tricks:

  1. Use external CSS for most projects, especially multi-page websites.

  2. Reserve inline CSS for testing or cases where styles must be applied dynamically with JavaScript.

  3. When loading multiple stylesheets, be mindful of the order—later sheets override earlier ones.

Understanding Difference Between Selectors - Class, ID, Element

CSS offers various selector types, each with different purposes and levels of specificity.

Element Selectors

Element selectors target HTML elements by their tag name. They apply styles to all instances of that element type.

Example 1: Basic Element Selectors

p {
  line-height: 1.5;
  margin-bottom: 1em;
}

h2 {
  font-size: 1.8em;
  color: #2c3e50;
}

Example 2: Styling Form Elements

input {
  padding: 8px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

button {
  background-color: #4CAF50;
  color: white;
  padding: 10px 15px;
  border: none;
  cursor: pointer;
}

Output: All instances of the targeted elements receive the specified styles, creating base-level styling across the document.

Class Selectors

Class selectors target elements with a specific class attribute. Multiple elements can share the same class, and elements can have multiple classes.

Example 1: Using Classes for Component Styling

<div class="card">
  <h3 class="card-title">Article Title</h3>
  <p class="card-text">Article content goes here...</p>
  <button class="btn primary">Read More</button>
</div>
.card {
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  padding: 16px;
  margin-bottom: 20px;
}

.card-title {
  color: #333;
  margin-top: 0;
}

.card-text {
  color: #666;
}

.btn {
  padding: 8px 16px;
  border-radius: 4px;
  border: none;
  cursor: pointer;
}

.primary {
  background-color: #3498db;
  color: white;
}

Example 2: Multiple Classes on One Element

<p class="text-large text-bold text-center">
  This paragraph uses multiple classes.
</p>
.text-large {
  font-size: 20px;
}

.text-bold {
  font-weight: bold;
}

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

Output: Classes provide flexible, reusable styling patterns that can be combined for more complex styling needs.

ID Selectors

ID selectors target a single element with a specific ID attribute. Each ID must be unique within a document.

Example 1: Styling a Unique Page Section

<header id="main-header">
  <h1>Website Title</h1>
  <p>Tagline goes here</p>
</header>
#main-header {
  background-color: #34495e;
  color: white;
  padding: 2em;
  text-align: center;
  box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}

#main-header h1 {
  margin: 0;
  font-size: 2.5em;
}

Example 2: Using IDs for Targeted JavaScript

<form>
  <div class="form-group">
    <label for="username">Username:</label>
    <input type="text" id="username" name="username">
    <span id="username-error" class="error-message"></span>
  </div>
</form>
#username {
  width: 100%;
  padding: 10px;
  border: 1px solid #ddd;
}

#username-error {
  color: #e74c3c;
  font-size: 0.85em;
  display: none;
}

Output: ID selectors create highly specific styles for unique elements on a page, often used for page landmarks or JavaScript targets.

Key Differences:

Selector TypeSyntaxSpecificityPurpose
ElementelementLowBase styling for all instances of an element
Class.classnameMediumReusable styles that can be applied to multiple elements
ID#idnameHighUnique styling for a single element

Tips and Tricks:

  1. Use element selectors for basic styling, classes for reusable components, and IDs sparingly for truly unique elements.

  2. Prefer class selectors for most styling needs to maintain flexibility and reusability.

  3. Avoid overusing ID selectors as they create high specificity that can be difficult to override later.

Understanding Precedence of Selectors

CSS specificity determines which styles are applied when multiple rules target the same element. Understanding this hierarchy is crucial for predictable styling.

Specificity Hierarchy (from lowest to highest):

  1. Element selectors (p, div, h1)

  2. Class selectors (.classname), attribute selectors ([type="text"]), and pseudo-classes (:hover)

  3. ID selectors (#idname)

  4. Inline styles (style attribute)

  5. !important declaration

Example 1: Specificity in Action

<p id="special-paragraph" class="text-block important">
  This paragraph has multiple styles targeting it.
</p>
/* Specificity: 0-0-1 */
p {
  color: black;
  font-size: 16px;
}

/* Specificity: 0-1-0 */
.text-block {
  color: blue;
  font-size: 18px;
}

/* Specificity: 0-1-1 */
p.important {
  color: red;
  font-weight: bold;
}

/* Specificity: 1-0-0 */
#special-paragraph {
  color: purple;
  font-style: italic;
}

Output: The paragraph will be purple (from the ID selector), italic (from the ID selector), bold (from the class+element selector), and 18px (from the class selector).

Example 2: Using !important

.regular-text {
  color: blue;
}

.highlighted {
  color: orange !important;
}

#specific-text {
  color: green;
}
<p class="regular-text" id="specific-text">This will be green.</p>
<p class="regular-text highlighted" id="specific-text">This will be orange due to !important.</p>

Output: Despite the ID selector having higher specificity, the !important declaration in the .highlighted class overrides it.

Cascade and Source Order

When specificity is equal, the last rule defined wins (the cascade).

Example:

p {
  color: red;
}

/* This will win due to source order */
p {
  color: blue;
}

Inheritance

Some CSS properties are inherited from parent elements to children.

Example:

body {
  font-family: Arial, sans-serif;
  color: #333;
}

/* No need to repeat font-family for paragraphs - it's inherited */
p {
  line-height: 1.6;
}

Calculating Specificity

Specificity is calculated as a four-part value: (Inline, IDs, Classes, Elements)

Example:

/* Specificity: 0-1-2-1 */
#content .featured p.intro {
  color: red;
}

This breaks down as:

  • 0: No inline style

  • 1: One ID (#content)

  • 2: Two classes (.featured and .intro)

  • 1: One element (p)

Tips and Tricks:

  1. Avoid using !important except as a last resort—it breaks the natural cascade.

  2. Keep selector specificity as low as possible to maintain flexibility.

  3. Use consistent naming conventions and structure to avoid specificity conflicts.

How to Style Text Using CSS

Typography is fundamental to web design. CSS offers extensive control over text presentation through various properties.

Font Family

The font-family property specifies the typeface used for text. Multiple values provide fallbacks if fonts aren't available.

Syntax: font-family: primary-font, fallback-font, generic-family;

Example 1: Basic Font Stack

body {
  font-family: 'Helvetica Neue', Arial, sans-serif;
}

Example 2: Using Web Fonts

@font-face {
  font-family: 'OpenSans';
  src: url('fonts/OpenSans-Regular.woff2') format('woff2'),
       url('fonts/OpenSans-Regular.woff') format('woff');
  font-weight: normal;
  font-style: normal;
}

h1, h2, h3 {
  font-family: 'OpenSans', Helvetica, sans-serif;
}

Output: Text renders in the first available font from the specified list, falling back to generic system fonts if needed.

Font Style

The font-style property primarily controls italic text.

Syntax: font-style: normal | italic | oblique;

Example 1: Basic Italic

em {
  font-style: italic;
}

Example 2: Overriding Italic

em.no-emphasis {
  font-style: normal;
}

Output: Elements with these styles applied will display with or without italic styling as specified.

Font Weight

The font-weight property controls text thickness.

Syntax: font-weight: normal | bold | bolder | lighter | number;

Example 1: Using Keywords

h1 {
  font-weight: bold;
}

p {
  font-weight: normal;
}

Example 2: Using Numeric Values

.light {
  font-weight: 300;
}

.regular {
  font-weight: 400;
}

.medium {
  font-weight: 500;
}

.bold {
  font-weight: 700;
}

Output: Text appears with varying degrees of boldness, depending on the specified weight and available font variants.

Line Height

The line-height property controls vertical spacing between lines of text.

Syntax: line-height: normal | number | length | percentage;

Example 1: Using a Unitless Number (Recommended)

body {
  line-height: 1.5;
}

Example 2: Different Line Heights for Different Elements

h1 {
  line-height: 1.2;  /* Tighter for headings */
}

p {
  line-height: 1.6;  /* More spacing for readability */
}

.small-text {
  font-size: 14px;
  line-height: 1.8;  /* Even more spacing for small text */
}

Output: Text with appropriate spacing between lines, improving readability based on context.

Text Decoration

The text-decoration property adds lines to text.

Syntax: text-decoration: none | underline | overline | line-through;

Example 1: Links Styling

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

a:hover {
  text-decoration: underline;
}

Example 2: Strikethrough for Deleted Text

.deleted {
  text-decoration: line-through;
  color: #999;
}

Output: Text with various decorative lines applied or removed, commonly used for links and special text treatments.

Text Align

The text-align property controls horizontal text alignment.

Syntax: text-align: left | right | center | justify;

Example 1: Basic Alignment

h1 {
  text-align: center;
}

p {
  text-align: justify;
}

.right-aligned {
  text-align: right;
}

Example 2: Responsive Text Alignment

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

@media (max-width: 768px) {
  .article-header {
    text-align: left;
  }
}

Output: Text aligned according to the specified direction, adjusting for different contexts or screen sizes.

Text Transform

The text-transform property controls text capitalization.

Syntax: text-transform: none | capitalize | uppercase | lowercase;

Example 1: Uppercase Headers

h1, h2 {
  text-transform: uppercase;
  letter-spacing: 1px;
}

Example 2: Capitalize Names

.person-name {
  text-transform: capitalize;
}

Output: Text with modified capitalization regardless of the original input text.

Letter Spacing

The letter-spacing property adjusts spacing between characters.

Syntax: letter-spacing: normal | length;

Example 1: Expanded Headings

h1 {
  text-transform: uppercase;
  letter-spacing: 2px;
}

Example 2: Condensed Text

.condensed-title {
  letter-spacing: -0.5px;
  font-weight: bold;
}

Output: Text with increased or decreased space between characters, affecting the visual density and style.

Word Spacing

The word-spacing property adjusts spacing between words.

Syntax: word-spacing: normal | length;

Example 1: Expanded Quote

blockquote {
  word-spacing: 2px;
  font-style: italic;
}

Example 2: Headline Spacing

.newspaper-headline {
  font-size: 32px;
  word-spacing: -1px;
  font-weight: bold;
}

Output: Text with modified spacing between words, providing different rhythm and density to text blocks.

Text Shadow

The text-shadow property adds shadow effects to text.

Syntax: text-shadow: h-offset v-offset blur color;

Example 1: Subtle Text Shadow

h1 {
  text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}

Example 2: Multiple Text Shadows

.glow-text {
  color: white;
  text-shadow: 
    0 0 5px #fff,
    0 0 10px #fff,
    0 0 15px #0073e6,
    0 0 20px #0073e6;
}

Output: Text with dimensional shadows that create depth or special effects, enhancing visibility or adding visual interest.

Tips and Tricks for Text Styling:

  1. Limit your font families to 2-3 per design for consistency and better performance.

  2. Use relative units (em, rem) for font sizes to support accessibility and responsive design.

  3. Set a base line-height on the body element (1.4-1.6) for improved readability.

  4. Be cautious with text-transform: uppercase—it can reduce readability for longer text.

  5. Test your typography across different devices to ensure consistency and readability.