Getting to grips with CSS: A Beginner’s Tutorial (Part 1)

11 minute read

Cascading Style Sheets (CSS) is a fundamental technology for web development, allowing you to control the presentation and layout of your HTML documents. This tutorial is designed for beginners who want to get started with CSS. We’ll cover the basics, common styling properties, and provide practical examples to help you understand and apply CSS to your web projects.

Prerequisites

  • Basic knowledge of HTML (you should be familiar with HTML tags and their structure).

1. Understanding CSS Basics

1.1 What is CSS?

CSS (Cascading Style Sheets) is a stylesheet language used to describe the presentation of a document written in HTML. It controls how HTML elements are displayed on a webpage, allowing you to define styles such as colors, fonts, spacing, and layout.

1.2 CSS Syntax

CSS consists of selectors and declaration blocks. A selector is used to target HTML elements, and a declaration block contains one or more declarations separated by semicolons. Each declaration includes a property and a value.

Example:

/* Selector */
h1 {
  /* Declaration Block */
  color: blue;
  font-size: 24px;
}

2. Selectors and Properties

2.1 Selectors

Selectors target HTML elements to apply styles. Common selectors include element selectors (h1, p), class selectors (.my-class), and ID selectors (#my-id).

Element selectors

An element selector targets HTML elements based on their names. It applies styles to all instances of that element on the page.

Example:

/* Targeting all paragraphs */
p {
  color: red;
}

Classes

Classes allow you to define custom names for styling purposes. They provide a way to apply styles to multiple elements without having to target specific HTML element names. Classes can be given any name and are defined using the dot (.) notation.

Example:

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

In the HTML, you can apply a class to an element using the class attribute.

<p class="highlight">This paragraph has a custom style.</p>

It is also possible to select a particular type of element which has a particular class assigned using this syntax:

/* Select all paragraphs with the "highlight" class */
p.highlight {
  background-color: yellow;
}

IDs

IDs are used to uniquely identify a specific element on a page. While IDs can be used for styling, they should generally be reserved for unique elements due to their specificity. ID selectors target HTML elements with a specific id attribute. IDs must be unique within a page and are defined using the hash (#) notation. IDs can be useful for linking to specific elements within a page (although this has nothing to do with CSS).

Example:

/* Styling the element with the "header" ID */
#header {
  font-size: 24px;
}

In the HTML, you can assign an ID to an element using the id attribute.

<div id="header">This is the header</div>

Attribute Selectors

Attribute selectors allow you to target elements based on the presence or value of their attributes.

Example:

/* Styling links with a specific class attribute */
a[class="external"] {
  color: green;
}

Pseudo Classes

Pseudo-classes are used to select and style elements based on their state or position in the document. They are denoted by a colon (:) followed by the pseudo-class name.

Common Pseudo-classes:

  • :hover: Selects an element when the user hovers over it.
  • :active: Selects an element when it is being activated (clicked or pressed).
  • :focus: Selects an element when it has focus.
  • :first-child: Selects the first child of a parent element.
  • :nth-child(n): Selects the nth child of a parent element.

Example:

/* Selects and styles all <a> elements when hovered */
a:hover {
  text-decoration: underline;
  color: #ff0000;
}

One particularly interesting pseudo class is :not(), which you can use to inverse selections.

For example:

/* Selects and styles all <a> elements which DO NOT have the selected class */
a:not(.selected) {
  text-decoration: none;
  color: #0000ff;
}

The same can be achieved using specificity, which is the recommended approach; set a base style rule and override with positive selections.

/* Selects and styles all <a> elements */
a {
  text-decoration: none;
  color: #0000ff;
}
/* Selects and styles all <a> elements which have the selected class */
a.selected {
  text-decoration: underline;
  color: #ff0000;
}

Pseudo Elements

Pseudo-elements are similar to pseudo-classes but allow you to style specific parts of an element rather than the element itself. They are denoted by a double colon (::) followed by the pseudo-element name.

Common Pseudo-elements:

  • ::before: Inserts content before the selected element’s content.
  • ::after: Inserts content after the selected element’s content.
  • ::first-line: Selects the first line of text within an element.
  • ::first-letter: Selects the first letter of text within an element.
  • ::selection: Selects the portion of an element that is selected by the user.

Example:

/* Adds an exclamation mark after the content of each <p> element */
p::after {
  content: '!';
}

2.2 Grouping Rules

If you have 2 CSS rules with matching properties, you can combine the rules by grouping the selectors.

Example matching rules:

/* Adds a double quote before the content of each <p> element */
p::before {
  content: '"';
}
/* Adds a double quote after the content of each <p> element */
p::after {
  content: '"';
}

Example grouped rules:

/* Adds a double quote before and after the content of each <p> element */
p::before,
p::after {
  content: '"';
  color: #008080;
}

2.3 Combinators

CSS combinators are used to define relationships between different elements in a document. They allow you to select specific elements based on their positions relative to one another.

Descendant Combinator (Space)

The descendant combinator selects all elements that are descendants of a specified element. It applies styles to the nested elements, regardless of how deep they are nested.

Example:

/* Selects all <p> elements inside a <div> */
div p {
  color: #333;
}

Child Combinator (>)

The child combinator selects all direct children of a specified element. It targets elements that are one level deep in the HTML hierarchy.

Example:

/* Selects all <li> elements that are direct children of <ul> */
ul > li {
  list-style-type: square;
}

Adjacent Sibling Combinator (+)

The adjacent sibling combinator selects an element that is immediately preceded by a specified element. It targets elements that share the same parent and appear immediately after the specified element.

Example:

/* Selects the <p> element immediately following an <h2> element */
h2 + p {
  font-style: italic;
}

General Sibling Combinator (~)

The general sibling combinator selects all elements that are siblings of a specified element. It targets elements that share the same parent and are at the same level in the hierarchy.

Example:

/* Selects all <span> elements that are siblings of <p> elements */
p ~ span {
  color: #ff0000;
}

Combining Combinators

Combinators can be combined to create more specific and targeted selectors. Understanding how to use these combinations allows you to style elements based on complex relationships within the document structure.

Example:

/* Selects all <a> elements that are descendants of <nav> and direct children of <li> elements */
nav li > a {
  text-decoration: none;
  color: #008080;
}

Performance considerations

Using CSS combinators with complex or overly broad selectors can potentially introduce performance issues. While modern browsers are optimised for rendering CSS efficiently, certain practices can lead to increased computation time and slower page rendering.

Combinators like descendant ( ) or general sibling (~) selectors may result in a broad match, applying styles to multiple elements across the entire document. This can lead to more extensive browser calculations and updates.

For Performance optimization use specific selectors; aim for specificity in your selectors to target only the necessary elements. Avoid overly broad selectors that may inadvertently match many elements. The universal selector (*) should be used judiciously, as it matches every element. Try to avoid using it in combination with combinators unless necessary. ID selectors (#id) and class selectors (.class) are generally faster than complex descendant or sibling selectors.

2.4 Properties

Properties define the style to be applied. Common properties include color, font-size, margin, and padding.

Example:

/* Property: Value */
h2 {
  color: #333;
  font-size: 20px;
  margin-bottom: 10px;
  padding: 15px;
}

Some properties have shorthand and long-form equivalents. The long-form properties allow you to specify values as an array of ordered arguments. For example:

Separate properties

border-width: 5px;
border-style: solid;
border-color: orange;
margin-top: 5px;
margin-right: 10px;
margin-bottom: 5px;
margin-left: 10px;

Shorthand properties

border: 5px solid orange;
margin-top: 5px 10px 5px 10px;

Each property has one of four value types:

  1. Pre-defined options: e.g. display: block;, overflow: auto;
  2. Colours: e.g. background: red;, color: #fa923f;
  3. Length, sizes and numbers: e.g. height: 100px;, width: 20%;, order: 1;
  4. Functions: e.g. background: url(...);, transform: scale(...);

Measurement Units

CSS provides various units for specifying widths and heights.

  • Pixels (px): These units are fixed and do not change based on the size of the viewport or the parent element.
    width: 200px;
    
  • Percentage (%): Represents a percentage of the parent element’s width/height.
    width: 50%;
    
  • Viewport Width (vw) / Viewport Height (vh): Represents a percentage of the viewport’s width/height.
    width: 20vw;
    height: 75vh;
    
  • Viewport Minimum (vmin) and Maximum (vmax): vmin Represents the smaller of vw or vh. vmax: Represents the larger of vw or vh.
    width: 30vmin;
    height: 40vmax;
    
  • Em (em): Represents the calculated font size of the element.
    font-size: 1.5em; /* 1.5 times the font size of the parent element or the root element */
    
  • Rem (rem): Represents the font size of the root element.
    font-size: 1.2rem; /* 1.2 times the font size of the root element */
    

CSS Reference

You can look up CSS properties on the MDN CSS Reference to find out more.

2.5 Applying Styles

Styles can be applied externally in a separate CSS file or internally within an HTML file using the <style> element.

Example (External CSS):

/* styles.css */
body {
  font-family: 'Arial', sans-serif;
}

h1 {
  color: #008080;
}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <!-- Link to CSS file -->
  <link rel="stylesheet" href="styles.css">
  <title>My Website</title>
</head>
<body>
</body>
</html>

Example (Internal CSS):

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    body {
      font-family: 'Arial', sans-serif;
    }

    h1 {
      color: #008080;
    }
  </style>
  <title>My Website</title>
</head>
<body>
  <!-- Your HTML content here -->
</body>
</html>

Using a separate CSS file has several advantages over including styles directly in the HTML document:

  1. Separation of Concerns:
    • Keeping your styles in a separate CSS file promotes the separation of concerns. HTML focuses on content structure, while CSS handles presentation. This separation enhances code readability and maintainability.
  2. Reusability:
    • A separate CSS file allows you to reuse styles across multiple HTML pages. This is particularly beneficial in larger projects where consistency in styling is crucial.
  3. Consistency:
    • Centralising styles in one location ensures a consistent look and feel throughout your website. Any updates or modifications can be applied globally by editing the external CSS file.
  4. Easier Maintenance:
    • When your styles are in a dedicated file, maintaining and organizing your code becomes more straightforward. You can use comments, sections, and meaningful class names to make the codebase more manageable.
  5. Caching:
    • Browser caching is more efficient when styles are stored in external files. Once a user has visited a page, the CSS file can be cached, resulting in faster load times for subsequent visits to other pages that reference the same file.

2.5 Specificity

CSS specificity is a set of rules that determines which style rules are applied to an element. It is crucial for understanding how browsers decide which styles to apply when there are conflicting rules. Specificity is often represented as a four-part value (e.g., 0, 0, 0, 0), where higher values indicate higher specificity.

Specificity Levels

  1. Inline Styles:

Inline styles have the highest specificity. Styles applied directly within an HTML element using the style attribute override other styles.

<p style="color: red;">This is a red paragraph.</p>
  1. ID Selectors:

ID selectors have a high specificity. They are represented as #id and target a specific element with a unique ID.

#unique-element {
  font-size: 18px;
}
  1. Class Selectors, Attribute Selectors, and Pseudo-Classes:

Class selectors (e.g., .class), attribute selectors (e.g., [attribute]), and pseudo-classes (e.g., :hover) have a moderate specificity.

.highlight {
  background-color: yellow;
}

[data-theme="dark"] {
  color: white;
}

a:hover {
  text-decoration: underline;
}
  1. Type Selectors and Pseudo-Elements:

Type selectors (e.g., element) and pseudo-elements (e.g., ::before) have the lowest specificity.

p {
  line-height: 1.5;
}

li::before {
  content: "•";
}

Combining Selectors

When multiple selectors are combined, their specificities are added together. For example, a selector with one ID, two classes, and three elements has a specificity of 1, 2, 3, 0.

Example:

#header .navbar li.active {
  color: #008080;
}

Importance (!important)

The !important declaration increases the specificity of a rule, making it override other conflicting rules. While it can solve specificity issues, it is often considered a last resort due to its potential negative impact on maintainability.

Example:

p {
  color: red !important;
}

Order of Appearance

If two rules have the same specificity, the rule that appears later in the stylesheet takes precedence. This is known as the “last declaration wins” principle.

Example:

p {
  color: blue;
}

p {
  color: green; /* This color will be applied */
}

3. Text Styling

3.1 Font Properties

Font Family

The font-family property defines the font for an element. Specify multiple fonts as a fallback in case the preferred font is unavailable.

Example:

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

Font Size and Weight

Control the size and weight of the text using font-size and font-weight properties.

Example:

h1 {
  font-size: 28px;
  font-weight: bold;
}

3.2 Text Color and Alignment

Text Color

Set the color of the text using the color property.

Example:

p {
  color: #333;
}

Text Alignment

Use the text-align property to specify the alignment of text within an element.

Example:

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

3.3 Text Decoration and Transformation

Text Decoration

Control text decoration properties like underline, overline, and line-through using text-decoration.

Example:

a {
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

Text Transformation

Change the capitalization of text with text-transform (e.g., uppercase, lowercase, capitalize).

Example:

h2 {
  text-transform: uppercase;
}

In the next part (Part 2), we’ll explore the CSS Box Model, positioning and layout, responsive design and more.

Continue to Part 2.

Updated: