What is CSS?
Definition & History
CSS (Cascading Style Sheets) is the language used to describe the presentation of a document written in HTML or XML. It defines how elements are rendered on screen, paper, or in other media.
HTML provides the structure of a webpage, while CSS controls the appearance and layout. Without CSS, websites would look plain and unstyled with only default browser formatting.
- 1994 – First CSS 1 specification released.
- 1998 – CSS 2 added positioning, media queries, and more.
- 2011 – CSS 3 split into modular “levels” (Flexbox, Grid, Animations, etc.).
- Today – Modern CSS powers responsive websites, mobile apps, dashboards, and web applications.
Why CSS is Important
CSS is one of the three core technologies of the web:
- HTML → Structure of the page
- CSS → Design and appearance
- JavaScript → Interactivity and behavior
With CSS you can:
- Change colors, fonts, spacing, and layouts
- Create responsive websites for mobile and desktop
- Add animations and transitions
- Design professional user interfaces
- Control positioning and alignment of elements
How CSS Works
CSS works by selecting HTML elements and applying style rules to them.
h1 { color: blue; font-size: 40px; }
In the example above:
h1is the selectorcolorandfont-sizeare propertiesblueand40pxare values
Types of CSS
There are three main ways to use CSS in a webpage:
1. Inline CSS
CSS is written directly inside an HTML element using the style attribute.
<h1 style="color: red;">Hello</h1>
2. Internal CSS
CSS is placed inside a <style> tag in the HTML document.
<style> h1 { color: green; } </style>
3. External CSS
CSS is stored in a separate .css file and linked to the HTML page.
<link rel="stylesheet" href="style.css">
External CSS is the most commonly used approach because it keeps styling separate from content and makes large projects easier to manage.
Hello World – Minimal HTML + CSS
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>CSS Demo</title> <style> body { font-family: Arial, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; text-align: center; padding: 2rem; } h1 { font-size: 3rem; margin-bottom: 1rem; } </style> </head> <body> <h1>Hello, CSS!</h1> <p>This paragraph inherits the body's font and background.</p> </body> </html>
Understanding the Example
font-familychanges the text fontbackgroundcreates a gradient backgroundcolorchanges text colortext-aligncenters the contentpaddingadds spacing inside the pagefont-sizecontrols text size
This small example already demonstrates how powerful CSS can be in transforming a simple HTML page into a visually appealing design.
Create a file called index.html, paste the snippet above, open it in a browser and
verify the colours and fonts. Experiment by changing the color and
background values.
Create your own styled webpage with:
- A heading
- A paragraph
- A custom background color
- Different text colors
- Centered content
Try using at least three different CSS properties.
Including CSS
Three ways to add CSS
CSS can be added to a webpage in different ways depending on the size and purpose of the project. Small examples may use inline or embedded CSS, while professional websites usually use external stylesheets.
- Inline style –
<h1 style="color:red;">...</h1> - Embedded style sheet – inside
<style>tags in the<head>. - External stylesheet – linked with
<link rel="stylesheet" href="styles.css">.
1. Inline CSS
Inline CSS is written directly inside an HTML element using the style attribute.
<h1 style="color: red; font-size: 40px;"> Welcome </h1>
Advantages
- Quick and easy for testing
- Useful for very small changes
- No separate CSS file required
Disadvantages
- Makes HTML messy and harder to read
- Cannot reuse styles easily
- Difficult to maintain large projects
2. Embedded (Internal) CSS
Embedded CSS is written inside a <style> tag within the HTML document.
<head> <style> body { background: #222; color: white; } h1 { text-align: center; } </style> </head>
Advantages
- Better organization than inline CSS
- Useful for single-page projects
- No external file needed
Disadvantages
- Styles cannot be reused across multiple pages easily
- Larger HTML files become difficult to manage
3. External CSS
External CSS stores styles in a separate .css file and connects it using the
<link> tag.
External stylesheet best practice
<head> <link rel="stylesheet" href="styles.css"> </head>
The browser downloads the CSS file separately and applies the styles to the webpage.
Advantages
- Keeps HTML clean and organized
- Reusable across multiple pages
- Easier maintenance and updates
- Better performance because browsers can cache CSS files
Disadvantages
- Requires an additional file
- Incorrect file paths may break styles
Understanding the <link> Tag
The <link> tag connects the HTML file to the CSS file.
rel="stylesheet"tells the browser this is a CSS filehref="styles.css"specifies the path to the stylesheet
If the CSS file is inside another folder, the path changes accordingly.
project/
│
├── index.html
└── css/
└── styles.css
In this case, the correct link would be:
<link rel="stylesheet" href="css/styles.css">
Example External Stylesheet
The following stylesheet demonstrates a simple global reset and basic page styling.
/* Global reset */ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: 'Open Sans', sans-serif; background: #fafafa; color: #333; line-height: 1.6; }
Understanding the CSS Code
*is the universal selector that targets all elementsbox-sizing: border-boxmakes sizing calculations easiermargin: 0removes default browser spacingpadding: 0removes default inner spacingfont-familychanges the text fontline-heightimproves readability
Best Practices for Including CSS
- Use external CSS for most projects
- Keep CSS organized and readable
- Use meaningful file names like
style.cssormain.css - Avoid repeating the same styles multiple times
- Group related styles together
Create an index.html that links to an external styles.css file. Add a few
HTML elements (headings, paragraphs, a list) and style them globally (fonts, colours, spacing).
Create three versions of the same webpage:
- One using inline CSS
- One using embedded CSS
- One using external CSS
Compare which method feels cleaner and easier to manage.
Selectors
What are CSS Selectors?
Selectors are patterns used to target HTML elements so styles can be applied to them.
Without selectors, CSS would not know which elements should receive specific styles. Selectors are one of the most important concepts in CSS because they control how styles are applied throughout a webpage.
Basic selector types
- Element selector –
p { … } - Class selector –
.card { … } - ID selector –
#main { … } - Universal selector –
* { … }
1. Element Selectors
Element selectors target all HTML elements of a specific type.
p { color: #444; font-size: 18px; }
This rule styles every <p> element on the page.
Common examples
h1buttonimgsection
2. Class Selectors
Class selectors are used to style multiple elements with the same design.
<div class="card"> Product Card </div>
.card { padding: 1rem; background: white; border-radius: 8px; }
Class selectors start with a . (dot).
3. ID Selectors
ID selectors target one unique element on a page.
<section id="hero"> Welcome Section </section>
#hero { background: #222; color: white; }
ID selectors start with a # symbol.
4. Universal Selector
The universal selector targets every element on the page.
* { margin: 0; padding: 0; }
This selector is commonly used for CSS resets and global styling.
Combining Selectors
Selectors can be combined to create more specific styling rules.
section p { line-height: 1.8; }
This selector targets all paragraphs inside a <section>.
Combinators & hierarchy
Combinators define relationships between elements.
| Combinator | Example | Meaning |
|---|---|---|
Descendant ( ) |
ul li |
any li inside a ul |
Child (>) |
nav > a |
direct children only |
Adjacent sibling (+) |
h2 + p |
the first p after an h2 |
General sibling (~) |
h2 ~ p |
any p after an h2 |
Understanding Descendant vs Child
These two selectors are commonly confused by beginners.
<nav> <a>Home</a> <div> <a>About</a> </div> </nav>
nav aselects both linksnav > aselects only the direct child link
Attribute selectors
Attribute selectors target elements based on their HTML attributes.
a[href^="https"] { text-decoration: underline; } input[type="text"] { border: 1px solid #ccc; }
Common attribute selector symbols
| Selector | Meaning |
|---|---|
[attr] |
Element contains the attribute |
[attr=value] |
Exact match |
[attr^=value] |
Starts with value |
[attr$=value] |
Ends with value |
Practical Selector Demo
/* Element + class */ nav .nav-item { display: block; padding: 0.5rem 1rem; color: #666; } /* ID selector */ #hero { background: url('hero.jpg') center/cover; color: #fff; text-align: center; padding: 4rem 0; } /* Attribute selector */ a[target="_blank"] { position: relative; } a[target="_blank"]::after { content: "↗"; font-size: 0.8rem; margin-left: 0.2rem; }
Selector Specificity
Sometimes multiple CSS rules target the same element. The browser decides which rule wins using specificity.
- ID selectors have higher priority than classes
- Class selectors have higher priority than element selectors
- More specific selectors override general ones
p { color: blue; } .text { color: green; } #main-text { color: red; }
If an element has all three selectors applied, the ID selector wins.
Write a stylesheet that styles:
- All
h2elements with a bottom border. - Any link that points to an external site (starts with
http) with a small arrow after it. - Paragraphs that are the first child of a section with a different text colour.
Create a webpage containing:
- A navigation menu
- A hero section
- Three cards with the same class
- External links using
target="_blank"
Use different selectors to style each section.
Box Model & Positioning
Understanding the CSS Box Model
Every HTML element in CSS is treated as a rectangular box. The browser calculates the size and spacing of elements using the CSS Box Model.
Understanding the box model is essential because nearly every layout in web design depends on it.
CSS Box Model
Every element is a rectangular box with four parts (from inside-out):
- Content – the actual text or image.
- Padding – space inside the border.
- Border – outlines the element.
- Margin – space outside the border.
Visualizing the Box Model
+---------------------------+ | Margin | | +-------------------+ | | | Border | | | | +-------------+ | | | | | Padding | | | | | | +---------+ | | | | | | | Content | | | | | | | +---------+ | | | | | +-------------+ | | | +-------------------+ | +---------------------------+
Example Box Model
.box { width: 200px; padding: 20px; border: 2px solid #f97316; margin: 30px; background: #fff; }
How the Total Width is Calculated
By default, CSS adds padding and borders to the element’s width.
For the previous example:
- Content width =
200px - Left + right padding =
40px - Left + right border =
4px
Total width = 244px (excluding margins).
box-sizing: border-box is used.
Padding
Padding creates space inside the element between the content and border.
.card { padding: 20px; }
You can also set padding individually:
.card { padding-top: 10px; padding-right: 20px; padding-bottom: 10px; padding-left: 20px; }
Margin
Margin creates space outside the border and separates elements from each other.
section { margin-bottom: 40px; }
Margins are commonly used to create spacing between sections, cards, and layout components.
Border
Borders surround the padding and content of an element.
button { border: 2px solid black; }
Borders can have different styles such as:
soliddasheddotteddouble
Box-sizing
Set box-sizing: border-box; so width includes padding and border – easier
layout calculations.
* { box-sizing: border-box; }
With border-box, the declared width becomes the final visible width of the element.
box-sizing: border-box globally because it simplifies layouts.
Introduction to Positioning
Positioning controls where elements appear on the page.
By default, elements follow the normal document flow, but CSS positioning allows developers to move elements precisely.
Positioning schemes
| Position | Key properties | Behaviour |
|---|---|---|
static |
— | Normal flow (default). |
relative |
top / right / bottom / left |
Shifted relative to its original spot. |
absolute |
top / right / … |
Removed from flow; positioned against nearest positioned ancestor. |
fixed |
top / … |
Anchored to the viewport. |
sticky |
top / … |
Acts like relative until scroll reaches the threshold, then becomes
fixed. |
1. Static Positioning
This is the default positioning mode.
div { position: static; }
Elements appear in normal document order.
2. Relative Positioning
Relative positioning moves an element relative to its original location.
.box { position: relative; top: 20px; left: 30px; }
3. Absolute Positioning
Absolute elements are removed from the normal flow and positioned relative to the nearest positioned parent.
.parent { position: relative; } .child { position: absolute; top: 10px; right: 10px; }
static.
4. Fixed Positioning
Fixed elements stay attached to the browser viewport even while scrolling.
header { position: fixed; top: 0; width: 100%; }
This technique is commonly used for navigation bars and floating buttons.
5. Sticky Positioning
Sticky positioning combines relative and fixed behavior.
Example – sticky header
header { position: sticky; top: 0; background: #111; color: #fff; padding: 1rem; z-index: 10; }
The header scrolls normally until it reaches the top of the viewport, then remains fixed.
Z-Index
The z-index property controls stacking order.
- Higher values appear above lower values
- Works on positioned elements
- Useful for modals, menus, and overlays
.modal { position: fixed; z-index: 999; }
Create a page with a header, a sidebar and a content area. Use position: fixed for the
header,
position: sticky for a sub-navigation inside the sidebar, and practice padding/margin
changes to see how the box model works.
Create three boxes with different colors and:
- Apply different padding and margin values
- Add borders with different styles
- Use
position: relativeon one box - Use
position: absoluteinside another box
Observe how positioning changes the layout.
Flexbox
What is Flexbox?
Flexbox (Flexible Box Layout) is a modern CSS layout system designed to arrange items in a row or column efficiently.
Before Flexbox, developers often used floats, positioning hacks, or complicated CSS techniques to create layouts. Flexbox made alignment and spacing dramatically easier.
Why Flexbox?
Flexbox provides a one-dimensional layout model (row or column) that makes aligning, spacing and reordering items trivial.
It is especially useful for:
- Navigation bars
- Cards and dashboards
- Centering elements
- Responsive layouts
- Menus and toolbars
Flex Container vs Flex Items
Flexbox works using two important concepts:
- Flex Container – the parent element with
display: flex - Flex Items – the child elements inside the container
<div class="container"> <div>Item 1</div> <div>Item 2</div> <div>Item 3</div> </div>
.container { display: flex; }
Once display: flex is applied, the child elements become flex items automatically.
Main Axis and Cross Axis
Flexbox uses two axes for alignment:
- Main axis – controlled by
flex-direction - Cross axis – perpendicular to the main axis
justify-content controls alignment on the main axis, while
align-items controls alignment on the cross axis.
Key properties
display: flex;– establishes a flex container.flex-direction–row(default) orcolumn.justify-content– alignment on the main axis (e.g.center,space-between).align-items– alignment on the cross axis.flex,flex-grow,flex-shrink,flex-basis– control item sizing.gap– space between flex items (modern browsers).
display: flex
This property converts a normal container into a flex container.
.container { display: flex; }
By default, items appear in a horizontal row.
flex-direction
This property controls the direction of flex items.
.container { display: flex; flex-direction: column; }
Common values
row→ horizontal layoutcolumn→ vertical layoutrow-reversecolumn-reverse
justify-content
This property aligns items along the main axis.
.container { display: flex; justify-content: space-between; }
Common values
flex-startcenterflex-endspace-betweenspace-aroundspace-evenly
align-items
This property aligns items along the cross axis.
.container { display: flex; align-items: center; }
This is commonly used for vertical centering.
The gap Property
The gap property creates spacing between flex items.
.container { display: flex; gap: 20px; }
Using gap is cleaner than manually adding margins to every item.
Flex Item Sizing
Flexbox includes powerful sizing controls for items.
| Property | Purpose |
|---|---|
flex-grow |
Allows items to grow |
flex-shrink |
Allows items to shrink |
flex-basis |
Initial item size |
flex |
Shorthand property |
.item { flex-grow: 1; }
Items with larger flex-grow values occupy more available space.
Practical Flexbox Example
.nav { display: flex; justify-content: space-between; align-items: center; background: #111827; padding: 1rem 2rem; gap: 1.5rem; } .nav a { color: #e2e8f0; text-decoration: none; } .nav a:hover { color: #38bdf8; }
Simple responsive navigation bar
<nav class="nav"> <a href="#">Home</a> <a href="#">About</a> <a href="#">Contact</a> </nav>
Responsive Flexbox Layout
Flexbox works extremely well with media queries for responsive design.
.container { display: flex; gap: 1rem; } @media (max-width: 600px) { .container { flex-direction: column; } }
On smaller screens, the layout changes from horizontal to vertical.
Common Flexbox Use Cases
- Navigation bars
- Card layouts
- Centering content
- Pricing tables
- Dashboard layouts
- Hero sections
Build a three-column layout using Flexbox that collapses into a single column on screens narrower
than 600 px (use a media query to change flex-direction).
Create a responsive navigation bar using Flexbox.
- Align links horizontally on desktop
- Center items vertically
- Add spacing using
gap - Change link colors on hover
Create a card layout with three cards:
- Use Flexbox for alignment
- Add padding and borders
- Center text inside each card
- Make cards stack vertically on smaller screens
CSS Grid
What is CSS Grid?
CSS Grid is a powerful two-dimensional layout system that allows developers to create complex layouts using rows and columns.
Unlike Flexbox, which mainly works in one direction (row or column), CSS Grid can control both rows and columns at the same time.
Two-dimensional layout
CSS Grid lets you define rows and columns and place items precisely in that matrix.
Grid is commonly used for:
- Website layouts
- Photo galleries
- Dashboards
- Admin panels
- Complex responsive designs
Grid Container and Grid Items
CSS Grid works using two important concepts:
- Grid Container – the parent element with
display: grid - Grid Items – the child elements inside the container
<div class="grid"> <div>1</div> <div>2</div> <div>3</div> </div>
Defining a grid container
The parent element becomes a grid container using display: grid.
.grid { display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: auto 200px auto; gap: 1rem; }
Understanding the properties
display: grid→ activates grid layoutgrid-template-columns→ defines columnsgrid-template-rows→ defines rowsgap→ spacing between grid items
fr unit means “fraction of available space.”
repeat(4, 1fr) creates 4 equal-width columns.
Creating Columns
You can define grid columns manually or using the repeat() function.
.grid { display: grid; /* Three equal columns */ grid-template-columns: 1fr 1fr 1fr; }
Using repeat() makes code cleaner:
grid-template-columns: repeat(3, 1fr);
Creating Rows
Rows are controlled using grid-template-rows.
.grid { grid-template-rows: 100px 200px 100px; }
Each value represents the height of a row.
Gap Property
The gap property creates spacing between grid items.
.grid { gap: 20px; }
This is cleaner than adding margins to every item.
Placing items
Grid items can span across multiple rows and columns.
.item-a { grid-column: 1 / 3; grid-row: 1; } .item-b { grid-column: 3 / 5; grid-row: 1 / 3; } .item-c { grid-column: 1; grid-row: 2; }
Understanding grid lines
Grid layouts use numbered lines.
grid-column: 1 / 3means start at line 1 and end at line 3span 2means occupy 2 columns
Practical Grid Example
.grid { display: grid; grid-template-columns: repeat(3, 1fr); grid-auto-rows: 150px; gap: 1rem; } .grid > div { background: #38bdf8; color: #fff; display: flex; align-items: center; justify-content: center; font-size: 1.2rem; } .item-large { grid-column: 1 / span 2; background: #f97316; }
Responsive Grid Layouts
CSS Grid makes responsive layouts much easier using media queries.
Responsive grid example
@media (max-width: 800px) { .grid { grid-template-columns: repeat(2, 1fr); } } @media (max-width: 500px) { .grid { grid-template-columns: 1fr; } }
The layout automatically adapts to different screen sizes.
Auto-fit and Minmax
CSS Grid includes advanced responsive features like auto-fit and minmax().
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1rem; }
This creates responsive columns automatically without media queries.
Common CSS Grid Use Cases
- Photo galleries
- Website layouts
- Dashboards
- Pricing tables
- Portfolio websites
- Admin interfaces
Design a simple photo-gallery using CSS Grid: a 4-column layout on desktop, 2-column on tablets, and 1-column on mobile. Add a hover overlay that shows the image caption.
Create a dashboard layout using CSS Grid:
- A sidebar on the left
- A top navigation bar
- A main content section
- Responsive behavior for smaller screens
Create a card gallery layout:
- Use
repeat()for columns - Add spacing with
gap - Make one featured card span two columns
- Add hover effects to each card
Typography & Fonts
What is Typography?
Typography is the art of styling and arranging text to make content readable, visually appealing, and user-friendly.
Good typography improves readability, user experience, accessibility, and the overall design of a website.
Font-family stacks
The font-family property defines which fonts should be used.
It is common to provide multiple fallback fonts in case the first font is unavailable.
body { font-family: 'Open Sans', Helvetica, Arial, sans-serif; }
Understanding fallback fonts
'Open Sans'→ preferred fontHelvetica→ first fallbackArial→ second fallbacksans-serif→ generic font family
Font Categories
| Category | Example Fonts | Style |
|---|---|---|
| Serif | Times New Roman, Georgia | Traditional and formal |
| Sans-serif | Arial, Roboto, Open Sans | Modern and clean |
| Monospace | Courier New, Consolas | Equal character width |
| Cursive | Brush Script | Handwriting style |
Web-safe vs Web-fonts
- Web-safe – fonts that are pre-installed on most operating systems (Arial, Times, Verdana, etc.).
- Web-fonts – fonts loaded from external sources using
@font-faceor services like Google Fonts.
Using Google Fonts
Google Fonts is one of the most popular free font libraries for web development.
Google Fonts example
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap" rel="stylesheet" >
body { font-family: 'Roboto', sans-serif; }
Using @font-face
The @font-face rule allows you to load custom fonts manually.
@font-face { font-family: 'MyFont'; src: url('fonts/myfont.woff2'); } body { font-family: 'MyFont', sans-serif; }
Text properties
CSS provides many properties to control text appearance and readability.
| Property | Values |
|---|---|
font-size |
16px, 1rem, clamp(1rem,2vw,2rem) |
font-weight |
400, 700, bold |
line-height |
1.5, 150% |
letter-spacing |
0.05em |
text-align |
left, center, justify |
font-size
The font-size property controls the size of text.
p { font-size: 18px; }
Common units
px→ fixed pixelsrem→ relative to root font sizeem→ relative to parent element%→ percentage-based sizingvw→ viewport width
font-weight
The font-weight property controls text thickness.
h1 { font-weight: 700; }
Common values:
400→ normal700→ bold900→ extra bold
line-height
The line-height property controls spacing between lines of text.
p { line-height: 1.8; }
Proper line spacing improves readability significantly.
letter-spacing
The letter-spacing property adjusts spacing between characters.
h2 { letter-spacing: 0.1em; }
text-align
The text-align property controls horizontal alignment of text.
h1 { text-align: center; }
Common values
leftcenterrightjustify
Responsive typography with clamp()
The clamp() function creates responsive font sizes that adapt automatically to screen size.
h1 { font-size: clamp(2rem, 5vw, 4rem); }
How clamp() works
- Minimum size →
2rem - Preferred scaling →
5vw - Maximum size →
4rem
Building a Typographic Scale
A typographic scale creates consistent heading sizes across a website.
h1 { font-size: 3rem; } h2 { font-size: 2.5rem; } h3 { font-size: 2rem; } h4 { font-size: 1.5rem; }
Best Practices for Typography
- Use readable font sizes
- Limit the number of font families
- Maintain proper line spacing
- Use responsive typography
- Ensure sufficient contrast between text and background
Import a Google Font, set a typographic scale (h1-h6) using clamp(), and create a
paragraph with a custom line-height and letter-spacing. Verify the result at different viewport
widths.
Create a blog article layout with:
- A large responsive heading
- Readable paragraph spacing
- Different font weights for headings and body text
- Centered article title
Create a typography showcase page:
- Display different font families
- Experiment with font sizes
- Use letter spacing and line height
- Add responsive text using
clamp()
Custom Properties (CSS Variables)
Introduction to CSS Variables
Custom properties, commonly called CSS Variables, allow you to store reusable values inside CSS. Instead of repeating the same colors, spacing, fonts, or sizes throughout your stylesheet, you can define them once and reuse them everywhere.
CSS variables make stylesheets easier to maintain, scale, and update. Modern websites heavily rely on variables for themes, design systems, responsive layouts, and dark mode support.
Why Use CSS Variables?
- Reduces repetition in large stylesheets
- Makes themes easier to create and manage
- Improves maintainability of CSS code
- Allows dynamic updates with JavaScript
- Creates consistent design systems
Defining & using variables
CSS variables are declared using two hyphens (--) followed by a custom name.
:root {
--primary: #f97316;
--bg: #fafafa;
--text: #111827;
}
body {
background: var(--bg);
color: var(--text);
}
a {
color: var(--primary);
}
The var() function retrieves the value of a custom property.
Understanding the :root Selector
The :root selector represents the highest-level element in the document, usually the
<html> element.
:root {
--main-color: blue;
}
Variables defined inside :root become globally available throughout the entire webpage.
:root.
Naming Conventions
Use meaningful variable names so your CSS stays readable and organized.
:root {
--primary-color: #2563eb;
--secondary-color: #9333ea;
--font-large: 2rem;
--card-radius: 12px;
}
Good naming conventions make large projects easier to scale and maintain.
Scope & inheritance
Variables obey the normal CSS cascade and inheritance rules. A variable defined on a parent element is accessible to all child elements unless overridden.
.card {
--text-color: darkblue;
color: var(--text-color);
}
.card p {
color: var(--text-color);
}
Both the parent and child elements can access the variable because of inheritance.
Overriding Variables
Variables can be redefined inside specific elements or classes.
:root {
--bg: white;
}
.dark-box {
--bg: black;
background: var(--bg);
}
This allows different sections of a website to have different themes or styles.
Fallback Values
You can provide fallback values in case a variable does not exist.
color: var(--main-text, black);
If --main-text is undefined, the browser will use black.
Using Variables for Spacing
CSS variables are not limited to colors. They are also useful for spacing and sizing systems.
:root {
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 32px;
}
.container {
padding: var(--spacing-lg);
}
This creates a consistent spacing system across your website.
Using Variables with Fonts
:root {
--heading-size: 3rem;
--body-size: 1rem;
}
h1 {
font-size: var(--heading-size);
}
p {
font-size: var(--body-size);
}
Variables simplify typography management for large websites.
Theme switching (simple JavaScript example)
CSS variables are extremely useful for implementing light and dark themes.
/* CSS */
:root {
--bg: #fafafa;
--text: #111;
}
.dark {
--bg: #111;
--text: #fafafa;
}
/* JS */
document.getElementById('theme-btn')
.addEventListener('click', () => document.body.classList.toggle('dark'));
When the dark class is added to the body, the variable values change automatically across the
page.
Real-World Theme Example
:root {
--bg: white;
--card: #f3f4f6;
--text: black;
}
.dark {
--bg: #111827;
--card: #1f2937;
--text: white;
}
body {
background: var(--bg);
color: var(--text);
}
.card {
background: var(--card);
}
Changing only the variable values updates the entire interface instantly.
Variables and Responsive Design
Variables can also change based on screen size using media queries.
:root {
--container-width: 1200px;
}
@media (max-width: 768px) {
:root {
--container-width: 100%;
}
}
This technique improves responsive design flexibility.
Common Use Cases
- Dark mode / light mode themes
- Design systems
- Responsive layouts
- Reusable spacing systems
- Animation timing control
- Brand color management
Common Beginner Mistakes
- Forgetting to use
var()when accessing variables - Using unclear variable names
- Defining too many unnecessary variables
- Overriding variables accidentally
- Using variables without fallback values in critical areas
Build a colour-scheme switcher: define a light and a dark theme using custom properties, add a button that toggles the theme, and ensure all elements (background, text, links, borders) adapt correctly.
Create a reusable spacing system using CSS variables for padding and margins.
Build a card component that uses CSS variables for colors, border radius, shadows, and typography.
Transitions & Animations
Introduction to CSS Motion
Modern websites use motion to improve user experience, provide feedback, guide attention, and create more interactive interfaces. CSS transitions and animations allow developers to create smooth visual effects without JavaScript.
Transitions are typically used for simple state changes like hover effects, while animations provide more advanced multi-step motion using keyframes.
Why Animations Matter
- Improve user experience and interactivity
- Provide visual feedback for actions
- Guide user attention to important elements
- Create modern and polished interfaces
- Enhance navigation and usability
CSS Transitions
Transitions allow CSS properties to change smoothly over time instead of updating instantly.
.btn {
background: var(--primary);
color: #fff;
padding: 0.75rem 1.5rem;
border: none;
cursor: pointer;
transition: background 0.3s ease, transform 0.2s;
}
.btn:hover {
background: #fb923c;
transform: translateY(-2px);
}
When the button is hovered, the background color and transform properties animate smoothly.
Understanding the transition Property
The transition property is shorthand for multiple transition settings.
transition: property duration timing-function delay;
| Part | Description |
|---|---|
| property | The CSS property to animate |
| duration | How long the animation lasts |
| timing-function | Controls animation speed curve |
| delay | Wait time before animation starts |
Transition Timing Functions
Timing functions control how an animation accelerates or decelerates.
.box {
transition: transform 0.5s ease-in-out;
}
Common timing functions include:
linear→ constant speedease→ smooth start and endease-in→ slow startease-out→ slow endingease-in-out→ smooth both ways
Hover Effects
Hover effects are one of the most common uses of transitions.
.card {
transition: transform 0.3s ease;
}
.card:hover {
transform: scale(1.05);
}
This creates a smooth zoom effect when hovering over the card.
Animating Colors
.link {
color: black;
transition: color 0.3s ease;
}
.link:hover {
color: blue;
}
Color transitions make interfaces feel more responsive and polished.
Transform Functions
The transform property is heavily used in animations because it performs efficiently.
transform: translateX(20px);
transform: rotate(45deg);
transform: scale(1.2);
transform: skew(10deg);
Transforms can move, rotate, resize, or distort elements.
transform and opacity is generally smoother and more performant than
animating width, height, or position properties.
Keyframe animations
Keyframes allow developers to define multiple stages of an animation sequence.
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.icon {
animation: spin 2s linear infinite;
}
The element rotates continuously because of the infinite keyword.
Understanding the animation Property
animation: name duration timing-function delay iteration-count;
| Property | Purpose |
|---|---|
| name | Name of the keyframe animation |
| duration | Animation length |
| timing-function | Speed behavior |
| delay | Start delay |
| iteration-count | How many times it repeats |
Using Percentage Keyframes
Animations can define multiple stages using percentages.
@keyframes slide {
0% {
transform: translateX(0);
}
50% {
transform: translateX(100px);
}
100% {
transform: translateX(0);
}
}
This moves the element forward and then back to its original position.
Animating multiple properties
.pulse {
animation: pulse 1.5s ease-in-out infinite;
}
@keyframes pulse {
0% {
transform: scale(1);
opacity: 1;
}
50% {
transform: scale(1.1);
opacity: .7;
}
100% {
transform: scale(1);
opacity: 1;
}
}
This animation changes both size and opacity simultaneously.
Animation Iteration Count
The animation-iteration-count property controls how many times an animation repeats.
.loader {
animation: spin 1s linear infinite;
}
1→ plays once3→ plays three timesinfinite→ loops forever
Animation Direction
Animations can reverse direction automatically.
.box {
animation: move 2s alternate infinite;
}
The alternate value makes the animation move forward and backward repeatedly.
Combining Transitions & Animations
Professional interfaces often combine both techniques together.
.notification {
animation: fadeIn 0.5s ease;
transition: transform 0.2s ease;
}
.notification:hover {
transform: scale(1.03);
}
The notification fades in initially and scales slightly on hover.
Common Use Cases
- Button hover effects
- Loading spinners
- Navigation animations
- Card hover interactions
- Page transitions
- Notification popups
Accessibility Considerations
Some users are sensitive to excessive motion and animations.
@media (prefers-reduced-motion: reduce) {
* {
animation: none;
transition: none;
}
}
This media query disables animations for users who prefer reduced motion.
Common Beginner Mistakes
- Animating too many properties at once
- Using extremely long animation durations
- Overusing infinite animations
- Forgetting transition timing functions
- Using animations that distract from content
Create a button that on hover fades its background colour, slides upwards, and adds a subtle box-shadow. Also make an SVG icon that continuously rotates using a keyframe animation.
Create a loading spinner using only CSS animations and transforms.
Build a card component that fades in and slightly scales when hovered.
Responsive Design
Responsive design is the process of building websites that automatically adapt to different screen sizes and devices. A responsive website looks good and works properly on desktops, tablets, laptops, and mobile phones.
Modern users visit websites using many different devices. Responsive design ensures that layouts, images, typography, and navigation adjust smoothly for every screen size.
Why Responsive Design Matters
- Improves user experience on all devices
- Makes websites mobile-friendly
- Improves accessibility and readability
- Helps with SEO rankings on search engines
- Reduces the need for separate mobile websites
Media Queries
Media queries allow developers to apply different CSS styles depending on the screen size, device width, orientation, or resolution.
@media (max-width: 992px) {
.grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 600px) {
.grid {
grid-template-columns: 1fr;
}
}
- When the screen width becomes smaller than 992px, the layout changes to 2 columns
- When the width becomes smaller than 600px, the layout changes to a single column
- This helps content fit smaller screens properly
Common Breakpoints
| Device Type | Typical Width |
|---|---|
| Mobile | 0px – 600px |
| Tablet | 601px – 992px |
| Desktop | 993px and above |
Mobile-first approach
The mobile-first approach means designing for small screens first, then gradually adding styles for larger devices.
This approach is widely recommended because:
- Mobile traffic is extremely high today
- It improves performance
- It forces cleaner and simpler layouts
- It creates scalable designs
Start with the default (mobile) styles, then use min-width breakpoints
to add features for larger screens.
/* Base (mobile) */
.container {
padding: 1rem;
}
/* Tablet */
@media (min-width: 600px) {
.container {
padding: 2rem;
}
}
/* Desktop */
@media (min-width: 992px) {
.container {
padding: 3rem;
}
}
Always test your layouts on multiple screen sizes using browser developer tools. Chrome DevTools provides built-in mobile device simulation.
Fluid typography with clamp()
The clamp() function allows text sizes to scale smoothly between
minimum and maximum values.
html {
font-size: clamp(14px, 1vw, 18px);
}
The syntax is:
clamp(minimum, preferred, maximum)
- Minimum: Smallest allowed size
- Preferred: Flexible scaling value
- Maximum: Largest allowed size
Responsive images
Responsive images automatically adjust based on screen size and device resolution. This improves performance and prevents oversized images from loading on small devices.
<img src="small.jpg"
srcset="small.jpg 480w, medium.jpg 768w, large.jpg 1200w"
sizes="(max-width: 600px) 480px,
(max-width: 900px) 768px,
1200px"
alt="Responsive example">
- Faster page loading
- Reduced bandwidth usage
- Better mobile performance
- Sharper images on high-resolution screens
Responsive Layout Tips
- Use flexible units like
%,vw, andrem - Avoid fixed widths whenever possible
- Use CSS Grid and Flexbox for layouts
- Test navigation menus on small screens
- Keep touch targets large enough for mobile users
Turn the three-column layout from Lecture 5 into a fully responsive layout that collapses to two columns at 800 px and to a single column at 500 px.
Add a responsive navigation bar that switches to a hamburger menu. You can reuse the existing sidebar toggle logic.
Bonus Challenge:
- Add responsive typography using
clamp() - Make all images responsive using
max-width: 100% - Test your layout on mobile and tablet screen sizes
SCSS & Pre-processors
SCSS is a more powerful version of CSS that adds programming-like features such as variables, nesting, mixins, functions, and reusable code structures. SCSS belongs to a group of tools called CSS pre-processors.
Browsers cannot directly understand SCSS files. SCSS code must first be compiled into normal CSS before the browser can use it.
What is a CSS Pre-processor?
A CSS pre-processor is a tool that extends normal CSS with advanced features. It helps developers write cleaner, faster, and more maintainable stylesheets.
Popular CSS pre-processors include:
- SCSS / Sass
- LESS
- Stylus
- Reduces repeated code
- Makes large projects easier to manage
- Improves readability
- Supports reusable styling systems
- Speeds up development
Why preprocess?
- Variables (
$primary: #f97316;) - Nesting for clearer hierarchy
- Mixins for reusable blocks of CSS
- Functions for computing values
- Partial files and imports for modular code
Variables in SCSS
Variables allow developers to store reusable values such as colors, spacing, fonts, shadows, and sizes.
Instead of rewriting the same value multiple times, you can store it once and reuse it throughout the project.
$primary: #f97316;
$spacing: 1rem;
body {
font-family: 'Open Sans', sans-serif;
color: #111;
a {
color: $primary;
&:hover {
color: darken($primary, 10%);
}
}
.section {
padding: $spacing * 2;
}
}
$primarystores the main brand color$spacingstores reusable spacing- Nesting keeps related styles together
&:hovertargets the hover statedarken()automatically creates a darker color
Nesting in SCSS
SCSS allows CSS selectors to be nested inside each other. This creates a cleaner hierarchy that matches HTML structure.
.card {
padding: 1rem;
h2 {
color: blue;
}
p {
line-height: 1.6;
}
}
.card {
padding: 1rem;
}
.card h2 {
color: blue;
}
.card p {
line-height: 1.6;
}
Mixins
Mixins are reusable groups of CSS rules. They help avoid duplication and improve maintainability.
Mixin for clearfix
@mixin clearfix {
&::after {
content: "";
display: table;
clear: both;
}
}
.container {
@include clearfix;
}
@mixincreates a reusable style block@includeinserts the mixin into a selector- The clearfix technique fixes floating layout issues
Functions in SCSS
SCSS provides built-in functions for colors, calculations, strings, and more.
$mainColor: #3498db;
.button {
background: lighten($mainColor, 15%);
}
The lighten() function automatically creates a lighter version
of the selected color.
Using partials
Partials allow developers to split styles into smaller organized files. This is extremely useful for large projects.
// _variables.scss
$primary: #f97316;
// main.scss
@import 'variables';
@import 'components/buttons';
- Improves project organization
- Keeps code modular
- Makes styles easier to maintain
- Supports teamwork in large projects
SCSS File Structure Example
scss/
│
├── main.scss
├── _variables.scss
├── _buttons.scss
├── _navbar.scss
└── _cards.scss
SCSS vs Normal CSS
| Feature | CSS | SCSS |
|---|---|---|
| Variables | No | Yes |
| Nesting | Limited | Yes |
| Mixins | No | Yes |
| Functions | Basic | Advanced |
Set up a simple SCSS project using an online compiler like SassMeister.
Create a _buttons.scss partial with a mixin that generates:
- Primary button styles
- Secondary button styles
- Disabled button styles
Import the partial into a main stylesheet and demonstrate the three button variants in HTML.
Bonus Challenge:
- Create color variables
- Add hover effects using nesting
- Use a mixin for border radius
CSS Architecture (BEM & ITCSS)
In large projects, CSS can become difficult to manage. CSS Architecture helps organize styles into reusable, scalable, and maintainable structures. In this lecture, you will learn BEM naming methodology and ITCSS architecture.
What is CSS Architecture?
CSS Architecture is a way to organize CSS code so that projects stay clean, readable, and easy to maintain.
- Avoids duplicate styles
- Makes teamwork easier
- Improves scalability
- Reduces CSS conflicts
BEM Methodology
BEM stands for:
- Block → Independent component
- Element → Part of a block
- Modifier → Variation of a block or element
block__element--modifier
BEM Example
<div class="card card--dark">
<h2 class="card__title">Welcome</h2>
<p class="card__text">Learning BEM CSS.</p>
</div>
.card{
padding:20px;
border-radius:10px;
background:#f1f1f1;
}
.card--dark{
background:#222;
color:white;
}
.card__title{
font-size:28px;
}
.card__text{
font-size:16px;
}
What is ITCSS?
ITCSS stands for Inverted Triangle CSS. It organizes CSS from generic styles to specific styles.
ITCSS Layers
- Settings → Variables and config
- Tools → Mixins/functions
- Generic → Reset styles
- Elements → HTML tag styling
- Objects → Layout patterns
- Components → UI components
- Utilities → Helper classes
Example Folder Structure
css/ │ ├── settings/ ├── tools/ ├── generic/ ├── elements/ ├── objects/ ├── components/ └── utilities/
Advantages of BEM & ITCSS
| Feature | Benefit |
|---|---|
| BEM | Reusable and readable class names |
| ITCSS | Organized CSS structure |
| Architecture | Easy scaling for large projects |
Practice Exercise
Create a product card using BEM naming convention.
- Add title, image, and button
- Create a modifier class for dark mode
- Organize styles using ITCSS folders
Container Queries & Modern Layout
Modern CSS introduces powerful layout tools such as Container Queries, Subgrid, and improved Flexbox/Grid techniques. These help build truly responsive websites.
What are Container Queries?
Container Queries allow elements to respond based on the size of their parent container, not the entire screen.
Media Queries → depend on viewport size.
Container Queries → depend on parent container size.
Basic Container Query Example
.card-container{
container-type:inline-size;
}
.card{
padding:20px;
background:#f3f3f3;
}
@container (min-width:500px){
.card{
display:flex;
gap:20px;
}
}
CSS Grid Review
CSS Grid is a two-dimensional layout system used for rows and columns.
.container{
display:grid;
grid-template-columns:repeat(3,1fr);
gap:20px;
}
Subgrid
Subgrid allows child grids to align with the parent grid structure.
.child{
display:grid;
grid-template-columns:subgrid;
}
Modern Flexbox Tips
- Use
gapinstead of margins - Use
flex-wrapfor responsive layouts - Use
align-itemsandjustify-content
Responsive Card Layout
.cards{
display:grid;
grid-template-columns:
repeat(auto-fit,minmax(250px,1fr));
gap:20px;
}
Advantages of Modern Layout
- Cleaner responsive design
- Less media query usage
- Better component-based layouts
- Flexible and scalable UI
Practice Exercise
Create a responsive dashboard layout using:
- CSS Grid
- Container Queries
- Responsive cards
- Flexible navigation
CSS Layers & Native Nesting
CSS now includes powerful modern features such as Layers and Native Nesting. These help organize styles, avoid conflicts, and write cleaner CSS.
What are CSS Layers?
CSS Layers allow developers to control style priority using named layers.
- Prevent style conflicts
- Manage CSS order clearly
- Separate utilities/components/base styles
Layer Syntax
@layer base, components, utilities;
Layer Example
@layer base{
h1{
color:blue;
}
}
@layer components{
.btn{
background:black;
color:white;
padding:10px 20px;
}
}
What is Native Nesting?
Native Nesting allows CSS rules to be nested inside other selectors, similar to SCSS.
Nesting Example
.card{
padding:20px;
h2{
color:darkblue;
}
p{
font-size:16px;
}
}
Using & Selector
.button{
background:black;
color:white;
&:hover{
background:gray;
}
}
Benefits of Modern CSS Features
| Feature | Benefit |
|---|---|
| Layers | Better CSS organization |
| Nesting | Cleaner readable code |
| Modern CSS | Less dependency on preprocessors |
Practice Exercise
Create a small UI library using:
- CSS Layers
- Nested selectors
- Buttons and cards
- Hover effects
Final Project — Design System
Content coming soon...