Cascading Style Sheets
Learning Objectives
- You know what Cascading Style Sheets (CSS) are and how they work with HTML.
- You understand CSS syntax: selectors, properties, and values.
- You can apply basic typography and color styles to web pages.
- You know how the cascade and specificity determine which styles apply to elements.
- You understand the box model and how it affects element sizing and spacing.
Cascading Style Sheets (CSS) is a language for styling web content. While HTML defines the structure and content of a web page, CSS defines what that content should look like — colors, fonts, spacing, layout, and visual presentation.
Consider the following example:
In this example, we define a <style> block in the <head> section that contains CSS rules. The body rule sets a default font and text color for the entire page. As a result, both the paragraphs and the heading inherit the font from the body element. However, the heading has its own color rule that overrides the inherited color.
CSS is a living standard maintained by the W3C. You can follow the latest developments at https://www.w3.org/Style/CSS/. In this material, we focus on the core CSS concepts you need for modern web development.
CSS Syntax: Selectors, Properties, and Values
CSS consists of rules that define how to style HTML elements.
CSS rule structure
Each CSS rule consists of two main parts: a selector that identifies which HTML elements to style, and a declaration block that contains the actual style rules. Each style rule is made up of properties and their corresponding values.
The general structure of a CSS rule is:
selector {
property: value;
property: value;
}
Here’s a concrete example:
h1 {
color: red;
font-size: 2rem;
margin-bottom: 1rem;
}
This rule selects all h1 elements and sets their color to red, font size to 2rem, and bottom margin to 1rem — a rem is a relative unit based on the root element’s font size.
Selectors
There are a range of selectors you can use to target HTML elements. The most common types are type selectors, ID selectors, and class selectors.
Type Selectors
Type selectors (also called element selectors) select all elements of a given type by using the element’s tag name:
h1 {
color: red;
}
p {
color: blue;
line-height: 1.6;
}
In this example, all h1 elements are red and all p elements are blue. The h2 element has no explicitly set style.
All browsers apply default styles to HTML elements. For example, headings are bold and larger than body text, paragraphs have margins, and links are blue and underlined. You can override these defaults with your own CSS.
ID Selectors
ID selectors target a single, unique element using its id attribute. ID selectors are written with a hash symbol # followed by the ID value. Since IDs must be unique on a page, an ID selector will match at most one element:
#header {
background-color: #f0f0f0;
}
#main-content {
max-width: 800px;
}
Only the paragraph with id="awesome" receives the blue, bold styling.
Class Selectors
Class selectors select all elements with a given class attribute. Class selectors are written with a dot . followed by the class name. Multiple elements can share the same class:
.header {
font-size: 1.5rem;
font-weight: bold;
}
.highlight {
background-color: yellow;
}
Both the h1 and h2 elements with class="header" receive the green, bold styling.
Combining Selectors
You can combine selectors in various ways to target elements more precisely:
/* Multiple selectors with the same styles */
h1, h2, h3 {
font-family: Arial, sans-serif;
}
/* Descendant selector: p elements inside elements with class "article" */
.article p {
line-height: 1.8;
}
/* Child selector: direct children only */
.container > div {
margin: 10px;
}
/* Element with specific class */
p.warning {
color: red;
}
Basic Typography and Colors
Typography and color play a key role in making your content readable. By default, browsers apply basic styles, but CSS allows you to customize fonts, sizes, colors, and spacing.
Typography
Typography properties control how text appears on the page. The font-family property specifies which font to use, while font-size controls the size of the text.
Font families fall into four main categories:
- Serif: Fonts with small decorative strokes (Times New Roman, Georgia)
- Sans-serif: Clean fonts without decorative strokes (Arial, Helvetica, Verdana)
- Monospace: Fixed-width fonts (Courier New, Consolas)
- Cursive: Script-style fonts (Comic Sans MS, Brush Script)
The font-size property controls the size of text. Font size can be set using absolute units like pixels (px) or relative units like em and rem. The em unit is relative to the parent element’s font size, while rem is relative to the root element’s font size (usually the <html> element).
Using rem is generally recommended, as it respects preferences set by users in their browsers.
/* Pixels (absolute) */
.small { font-size: 14px; }
/* Relative to root element (recommended) */
.normal { font-size: 1rem; } /* Usually 16px */
.large { font-size: 1.5rem; } /* Usually 24px */
/* Relative to parent element */
.big { font-size: 1.2em; }
Colors
CSS provides several ways to define colors:
/* Named colors */
.red { color: red; }
/* Hexadecimal (most common) */
.blue { color: #0066cc; }
/* RGB */
.green { color: rgb(0, 128, 0); }
/* RGBA (with transparency) */
.transparent { color: rgba(0, 0, 0, 0.5); }
Common color properties include:
color: Text colorbackground-color: Background colorborder-color: Border color
Cascade, Specificity, and Inheritance
The term “cascade” in Cascading Style Sheets refers to the algorithm that determines which style rules apply when there are conflicts. Cascade considers three main factors in order:
- Source order: When rules have equal specificity, the last rule defined wins
- Specificity: More specific selectors override less specific ones
- Importance: Rules marked with
!importantoverride normal rules
p {
color: blue;
}
p {
color: red;
}
/* Paragraphs will be red due to source order */
Specificity is a weight given to CSS selectors that determines which rule applies when multiple rules could match the same element. Specificity is calculated based on the types of selectors used:
- Type selectors (e.g.,
h1,p,div): 1 point - Class selectors (e.g.,
.header): 10 points - ID selectors (e.g.,
#main): 100 points - Inline styles (e.g.,
style="color: red"): 1000 points
If an element does not have a specific style defined, it may inherit styles from its parent elements. For example, if the body element has a text color defined, all child elements will inherit that color unless they have their own color specified. Here’s a simple example:
Box Model
Every HTML element is rendered as a rectangular box. The CSS box model describes the structure of these boxes and how their size and spacing are calculated.
The box model consists of four areas, from inside to outside:
- Content: The actual content of the element (text, images, etc.)
- Padding: Space between the content and the border
- Border: A line surrounding the padding (can be invisible)
- Margin: Space outside the border, separating the element from other elements
+--------------------------------+
| Margin |
| +------------------------+ |
| | Border | |
| | +----------------+ | |
| | | Padding | | |
| | | +--------+ | | |
| | | | Content| | | |
| | | +--------+ | | |
| | +----------------+ | |
| +------------------------+ |
+--------------------------------+
You can control each part of the box model with CSS:
.box {
/* Content size */
width: 200px;
height: 100px;
/* Padding */
padding: 20px;
/* Border */
border: 2px solid black;
/* Margin */
margin: 10px;
}
Each property in box-model also allows setting individual sides:
.box {
padding-top: 10px;
padding-right: 15px;
padding-bottom: 10px;
padding-left: 15px;
}
By default, some HTML elements are inline (e.g., <span>, <a>) and do not respect box model properties like width, height, margin, and padding in the same way as block elements (e.g., <div>, <p>). You can change an element’s display behavior using the display property (e.g., display: block; or display: inline-block;).
CSS in Svelte
When working with Svelte, you have several options for applying CSS styles.
Scoped Styles
Svelte has component-scoped styles. To use component-scoped styles, you add a <style> element to your component. For example, the styles defined in the following component apply only to elements within that component:
<script>
let name = "World";
</script>
<h1>Hello {name}!</h1>
<p>This is a Svelte component.</p>
<style>
h1 {
color: #0066cc;
font-size: 2rem;
}
p {
color: #333333;
line-height: 1.6;
}
</style>
These styles won’t affect h1 or p elements in other components. Svelte automatically scopes the styles by adding unique classes to elements.
Global Styles
For styles that should apply across your entire application, create a CSS file (e.g., src/app.css) and import it in your root layout:
/* src/app.css */
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: Arial, sans-serif;
line-height: 1.6;
}
Then import it in src/routes/+layout.svelte:
<script>
import "../app.css";
let { children } = $props();
</script>
{@render children()}
Instead of writing all CSS from scratch, developers typically use CSS frameworks like Tailwind CSS, which we’ll explore in the next chapter. Frameworks provide pre-built utility classes and components that speed up development and help with consistent styling.
Summary
In summary:
- CSS (Cascading Style Sheets) is the language for styling web content. It works alongside HTML to control visual presentation.
- CSS syntax consists of selectors that target elements and declarations that define styles. Selectors include type selectors (element names), class selectors (
.classname), and ID selectors (#idname). - Typography and color properties control the appearance of text and backgrounds. Use
remunits for sizes to respect user preferences and make your design more accessible. - The cascade determines which styles apply when multiple rules target the same element, based on source order, specificity, and importance.
- Inheritance allows child elements to inherit styles from their parent elements unless overridden.
- The box model describes how elements are rendered with four components: content, padding, border, and margin.
- In Svelte, you can use scoped styles within components, global styles in a shared CSS file, or CSS frameworks for rapid development.