Advanced CSS and Responsive Design
Multiple Classes to HTML
Multiple classes let you apply several CSS styles to one HTML element by listing class names separated by spaces in the class attribute. This avoids creating a new class for every combination of styles, keeping the code modular and maintainable.
Intuition
Why not write a single class that does everything? Because you often need different combinations of the same basic styles (color, background, underline) across elements. Defining each style as a separate class and then combining them in the HTML lets you reuse those basic building blocks.
How it works
<p class="standard-color standard-underline standard-highlight">Text</p>
Each class refers to a rule in the CSS. The element gets the union of all rules from its classes.
Example from the lecture
Three paragraphs needed different treatments:
| Paragraph | Styles required |
|---|---|
| 1st | Highlight |
| 2nd | Highlight + Underline |
| 3rd | Highlight + Underline + Color |
Without multiple classes – you would need to create a new class (e.g., .highlight-underline) and duplicate the rules.
With multiple classes – apply existing classes directly:
<p class="standard-highlight">Paragraph 1</p>
<p class="standard-highlight standard-underline">Paragraph 2</p>
<p class="standard-highlight standard-underline standard-color">Paragraph 3</p>
Benefits
- Reusability – each class defined once, used many times.
- Modularity – change a single rule to update every element that uses it.
- Semantic HTML – class names describe the style, not the combination.
- Easier maintenance – no need to hunt for duplicated rules.
Exam tip: This technique is essential for writing DRY (Don’t Repeat Yourself) CSS and will be used heavily with Flexbox, Grid, and frameworks like Bootstrap.
Key takeaways
- Add multiple classes by separating names with a space in the
classattribute. - Eliminates the need for combination-specific classes.
- Reduces code duplication and improves maintainability.
- Fundamental for modular, scalable CSS.
CSS Layouts
Layouts control how elements are arranged on the page. Older methods (tables, inline-block, floats) were not designed for the web’s responsive nature. Modern CSS provides Flexbox and Grid as purpose-built tools.
Evolution of layout methods
| Method | Key idea | Major weaknesses |
|---|---|---|
| Tables | Rows & columns for arrangement | Messy HTML, no responsiveness, hard to maintain |
display: inline-block | Elements sit side by side with width/height | Alignment is fragile, vertical-align often fails, overflow, fixed heights break on resize |
float | Push elements left or right | Never intended for layout; clearing issues, collapsing containers |
| Flexbox | One-dimensional (row or column) flexible layout | Only handles one axis at a time |
| Grid | Two-dimensional rows & columns | More complex than Flexbox for simple cases |
Demo: the pain of inline-block
A common layout – sidebar + main content – was attempted with display: inline-block.
.sidebar {
display: inline-block;
width: 30%;
height: 60px; /* forced to align tops */
background: aqua;
}
.main-content {
display: inline-block;
width: 60%;
height: 60px;
background: lightgreen;
}
Problems encountered:
- Alignment – the sidebar and main content did not start at the same vertical position;
vertical-align: middlefailed. - Height mismatch – fixed heights caused overflow when content grew; removing heights broke alignment again.
- Responsiveness – fixed percentages did not adapt; on narrower screens the layout broke.
- Spacing – margins had to be manually added; no automatic gap.
Exam tip: The demo highlights why
inline-blockshould not be used for page layouts. Flexbox or Grid are the standard solutions.
Modern solution: Flexbox
Applying display: flex to the parent container solved almost everything in one line.
main {
display: flex;
gap: 30px;
}
- Sidebar and main content automatically align at the same height (stretch by default).
- No need for
heightorvertical-align. - The
gapproperty creates uniform spacing. - Removing explicit widths causes elements to fill available space; adding
width: 30%on the sidebar and letting the main take the rest works naturally. - The layout adapts to content length without overflow.
Real‑world usage
- Times of India – inspected cards and found
display: flexon parent containers. - Adidas – product listings use
display: gridwithgrid-template-columns: 1fr 1fr 1frand agap.
Why it matters
Flexbox and Grid are the foundation of responsive design. Combined with media queries and frameworks like Bootstrap, they allow layouts to adapt to phones, tablets, and desktops with minimal code.
Key takeaways
- Layouts evolved from tables → inline-block → floats → Flexbox/Grid.
inline-blockis brittle for full-page layouts: alignment, overflow, and responsiveness are hard to control.- Flexbox excels at one-dimensional layouts (row or column).
- Grid handles two-dimensional layouts with explicit row/column definitions.
- Using
display: flexon a parent instantly aligns children, handles spacing withgap, and resizes automatically.
Flexbox
Flexbox (Flexible Box Layout) gives a powerful, one-dimensional layout system for aligning and distributing space among items in a container — even when their sizes are unknown or dynamic. Instead of wrestling with floats, inline‑blocks, or positioning hacks, you set display: flex on the parent and let flex properties handle the rest. Its main strength: responsive arrangements that adapt to screen width without media queries.
The Two Axes
Every flex container has a main axis and a cross axis, determined by flex-direction:
flex-direction | Main axis | Cross axis |
|---|---|---|
row (default) | Horizontal (left → right) | Vertical |
row-reverse | Horizontal (right → left) | Vertical |
column | Vertical (top → bottom) | Horizontal |
column-reverse | Vertical (bottom → top) | Horizontal |
Exam tip: Properties that align act on one axis or the other. Mixing them up is a classic trap. Remember:
justify-contentworks on the main axis;align-itemsworks on the cross axis.
Container (Parent) Properties
Apply these to the parent element (display: flex).
flex-direction
Sets the direction of the main axis and thus the order items are placed.
row(default),row-reverse,column,column-reverse
justify-content
Distributes space along the main axis.
| Value | Effect |
|---|---|
flex-start | Items packed at start (default) |
flex-end | Items packed at end |
center | Items centred |
space-between | Even space between items, none at edges |
space-around | Space around each item (edges get half the gap) |
space-evenly | Equal space everywhere |
align-items
Controls alignment along the cross axis (single‑line containers).
| Value | Effect |
|---|---|
stretch (default) | Items stretch to fill cross‑axis size |
flex-start | Aligned at start of cross axis |
flex-end | Aligned at end |
center | Centred |
baseline | Baselines of text aligned |
flex-wrap
Decides whether items wrap onto multiple lines when there isn’t enough space.
nowrap(default) – force all items onto one line (can overflow).wrap– items break into new lines from top to bottom.wrap-reverse– items wrap from bottom to top.
align-content
Works only when flex-wrap is wrap or wrap-reverse. It distributes space between flex lines along the cross axis (like justify-content does for rows).
| Value | Effect |
|---|---|
flex-start | Lines packed at start |
flex-end | Lines packed at end |
center | Lines centred |
space-between | Even space between lines |
space-around | Space around each line |
space-evenly | Equal space everywhere |
Exam tip:
align-itemsaligns items within a single line;align-contentaligns multiple lines when wrapping occurs. Ifflex-wrapisnowrap,align-contenthas no effect.
Child (Item) Properties
Apply these to the flex children (items) inside the container.
order
Controls the visual order (default 0). Higher values appear later. Items with equal order keep their HTML source order.
/* Moves .b2 to the end, even if it appears first in HTML */
.b2 { order: 1; }
align-self
Overrides align-items for a single item along the cross axis.
- Accepts the same values as
align-items(flex-start,flex-end,center,baseline,stretch).
flex-basis
Sets the initial size of an item along the main axis before any growing or shrinking. In a row layout it acts like width; in a column layout like height. It takes precedence over width (or height) but can be overridden by min‑width/max‑width.
flex-grow
A unitless number that defines how the item grows relative to siblings when there is extra space along the main axis.
- Default
0(no growth). - If all items have
flex-grow: 1, they share extra space equally. - An item with
flex-grow: 2gets twice the growth of an item withflex-grow: 1(not twice the total size).
flex-shrink
A unitless number that defines how the item shrinks relative to siblings when space is tight.
- Default
1(items shrink proportionally). - Setting
flex-shrink: 0prevents the item from shrinking below itsflex-basisor content size.
flex (Shorthand)
Combines three properties in one declaration:
flex: <flex-grow> <flex-shrink> <flex-basis>;
/* Example: */
flex: 1 1 150px; /* grow, shrink, basis */
Order of precedence for sizing (highest to lowest):
min-width/max-widthflex-basiswidth(orheightin column)- Content size (if none of the above set)
Worked Example: flex-grow in action
Six items with flex-basis: 120px inside a container:
.b1,.b2,.b4:flex-grow: 1.b3:flex-grow: 5
After available space is distributed, each of the three grow:1 items increased by ~77 px, while .b3 increased by ~385 px (5 × 77). The final sizes:
– .b1, .b2, .b4: 120 + 77 = 197px
– .b3: 120 + 385 = 505px
Quick Visual: Axis and Alignment
flowchart TD
A[Container display: flex] --> B{flex-direction?}
B -->|row| C[Main: horizontal / Cross: vertical]
B -->|column| D[Main: vertical / Cross: horizontal]
C --> E[justify-content controls horizontal spacing]
C --> F[align-items controls vertical alignment]
D --> G[justify-content controls vertical spacing]
D --> H[align-items controls horizontal alignment]
E & F --> I[Flex children laid out accordingly]
G & H --> I
Exam tip: The
flexshorthand is almost always preferred over settingflex-grow,flex-shrink, andflex-basisseparately. A common pattern isflex: 1(equivalent to1 1 0%).
Key takeaways
- Flexbox requires
display: flexon the parent. flex-directiondecides the main axis; all spacing/alignment properties depend on it.justify-contentcontrols main axis spacing;align-itemscontrols cross axis (single line);align-contentcontrols cross axis (multiple lines when wrapping).order,flex-grow,flex-shrink,flex-basis, andalign-selfare applied to children.- The shorthand
flex: grow shrink basisis the cleanest way to set item flexibility. - Use the CSS Tricks Flexbox Cheat Sheet for quick reference — even experienced developers rely on it.
CSS Grid
CSS Grid is a two-dimensional layout system designed for complex layouts that need control over both rows and columns simultaneously. Unlike Flexbox (which excels in one dimension – either a row or a column), Grid handles both with equal power.
The core idea: define a grid container (parent) and grid items (children). Using properties on the parent you create the grid structure, and using properties on the children you position or size them within that structure.
Grid Container Basics
To create a Grid layout, set the parent container’s display property to grid. The default behavior creates a single-column grid (items stack vertically).
Defining Columns and Rows
| Property | Description | Example |
|---|---|---|
grid-template-columns | Defines the number and width of columns | grid-template-columns: 300px 300px 200px; |
grid-template-rows | Defines the number and height of rows | grid-template-rows: 100px 100px 100px; |
Values can be absolute (px, em), percentage, or fractional units (fr). The fr unit distributes available space proportionally:
grid-template-columns: 1fr 2fr 1fr; /* second column twice as wide as the others */
Repeating Columns/Rows
Use repeat() to avoid typing the same size multiple times:
grid-template-columns: repeat(4, 1fr); /* four equal columns */
Min and Max Sizes with minmax()
The minmax(min, max) function lets you set a flexible range for a column or row. It will never shrink below min and never grow beyond max.
grid-template-columns: 1fr minmax(100px, 1fr) 1fr;
/* The middle column is at least 100px wide, but can grow equally with the others */
Gap Between Tracks
Use gap (shorthand) or row-gap / column-gap to add spacing between grid cells.
gap: 10px 30px; /* row-gap 10px, column-gap 30px */
/* or */
row-gap: 10px;
column-gap: 20px;
Using auto for Content-Based Sizing
A column/row set to auto will size itself to fit the content (no extra space).
Grid Lines, Cells, Tracks & Inspection
When you define a grid, the browser creates invisible grid lines that separate rows and columns. These lines are numbered starting from 1 (top-left) and also negatively from -1 (bottom-right).
- Grid cell – the area between four adjacent grid lines (one unit of the grid).
- Grid track – the space between two adjacent grid lines, i.e., a full row or column.
- Grid item – a child element placed inside the grid.
Exam tip: Negative line numbers (
-1,-2, etc.) let you reference the last line without knowing the total number of tracks – extremely useful for spanning to the far edge.
Chrome DevTools has a built-in Grid overlay (Layout tab → Grid) that shows lines, track sizes, and area names.
Auto Flow & Automatic Track Creation
By default, grid items flow left-to-right, top-to-bottom (row-major). This is controlled by grid-auto-flow.
grid-auto-flow: row(default) – fills rows first, then new rows are added.grid-auto-flow: column– fills columns first, then new columns are added.
When you have more items than explicit cells, extra items create implicit tracks. Their size is controlled by:
grid-auto-rows– height of new rows (when flow is row)grid-auto-columns– width of new columns (when flow is column)
grid-auto-rows: 100px; /* any new row will be 100px tall */
Alignment Inside the Grid
Alignment properties work similarly to Flexbox but operate on two axes: inline (horizontal) and block (vertical).
Aligning Items Within Cells (justify-items / align-items)
These are set on the grid container and affect all items:
| Property | Axis | Effect |
|---|---|---|
justify-items | Horizontal (row axis) | Aligns items inside each cell |
align-items | Vertical (column axis) | Aligns items inside each cell |
Values: start, end, center, stretch (default).
Aligning the Entire Grid (justify-content / align-content)
These move the grid tracks themselves within the container:
| Property | Axis | Effect |
|---|---|---|
justify-content | Horizontal | Distributes tracks across the inline axis |
align-content | Vertical | Distributes tracks across the block axis |
Values: start, end, center, stretch, space-between, space-evenly, etc.
Exam tip:
*-itemsworks inside each cell;*-contentworks on the whole grid. They are not interchangeable.
Per-Item Alignment (justify-self / align-self)
These are set on a grid item to override the container’s justify-items / align-items for that one item.
.item1 {
justify-self: start; /* align only this item left */
align-self: end; /* align it to bottom of its cell */
}
Positioning Grid Items
By default, each item occupies one cell. You can make items span multiple cells by specifying start and end grid lines using properties on the child.
Longhand Properties
grid-column-start: 1;
grid-column-end: -1; /* spans all columns */
grid-row-start: 2;
grid-row-end: 4; /* spans rows from line 2 to line 4 */
Shorthand with span
Use span <number> to indicate how many tracks to cover without specifying exact end lines.
grid-column: span 2; /* spans 2 columns */
/* Equivalent to grid-column-start: auto; grid-column-end: span 2; */
You can also combine line numbers and span:
grid-column: 2 / span 2; /* start at line 2, span 2 columns */
grid-row: 1 / 3; /* start at line 1, end at line 3 */
Grid Template Areas – Visual Layout Design
Instead of manually positioning each item, you can name areas and place items into them. This creates a highly readable, visual layout.
-
On each grid item, give it a name using
grid-area:.header { grid-area: header; } .sidebar { grid-area: sidebar; } .main { grid-area: main; } .footer { grid-area: footer; } -
On the grid container, define the layout with
grid-template-areas:.container { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: 100px 1fr 100px; grid-template-areas: "header header header" "sidebar main main" "footer footer footer"; }
Each row of the string corresponds to a row in the grid. The same name repeats across columns to make an item span multiple cells. A period (.) leaves a cell empty.
Exam tip:
grid-template-areasis the most intuitive way to build page layouts (e.g., header, sidebar, main, footer). It’s also easier to modify than number-based positioning.
Making Grids Responsive with autofit and autofill
Instead of hard-coding a fixed number of columns, you can let the grid decide how many columns fit the container width.
autofill– creates as many tracks as will fit, including empty ones (good for predictable spacing).autofit– creates as many tracks as will fit, but collapses empty tracks (so items stretch to fill the space).
Use with repeat() and minmax() for a fully responsive grid without media queries:
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
/* Each column at least 100px wide, grows equally; extra tracks are collapsed */
As the container width changes, columns adjust their count automatically. This is a CSS-only solution for fluid card layouts.
Key Takeaways
- Set
display: gridon the parent; usegrid-template-columnsandgrid-template-rowsto define structure. - The
frunit distributes available space proportionally.minmax()andrepeat()are essential for flexible grids. - Grid lines are numbered positively (1,2,3…) and negatively (-1,-2,…); use them to position items precisely.
- Alignment:
*-itemsaligns inside cells,*-contentaligns tracks inside the container.*-selfoverrides on a single item. - Grid items can span multiple cells using
grid-column/grid-rowwith line numbers orspan. grid-template-areasprovides a visual, easy-to-maintain layout method.repeat(auto-fit, minmax(min, 1fr))creates responsive grids without media queries.- Always inspect grids using Chrome DevTools Layout tab for debugging track sizes and lines.
Flexbox vs Grid: Overview
Flexbox (Flexible Box) and CSS Grid are modern layout systems that replace older methods like float and positioning. Both make it easy to create responsive designs — containers and items adjust based on available space. Both provide alignment properties along main and cross axes (e.g., justify-content, align-items for Flexbox; justify-items, align-items, justify-content, align-content for Grid).
But they differ in dimensions, control, and content flow.
Key Differences
| Aspect | Flexbox | Grid |
|---|---|---|
| Dimensionality | One-dimensional — lays out items in a single direction (row or column) | Two-dimensional — controls both rows and columns simultaneously |
| Control | Greater control over individual items (grow, shrink, alignment) | Control primarily at the container level (define rows, columns, then place items) |
| Content flow | Content-driven — items adjust based on their size; layout changes dynamically | Structure-first — define the grid, then place items into fixed tracks; layout is pre-defined |
| Wrapping | Items wrap naturally but don’t stick to exact row/column lines | Items always follow the defined grid lines, even when overflowing to new rows |
Live demonstration behavior
- Grid with fixed columns (e.g.,
grid-template-columns: 1fr 1fr 1fr): items occupy cells in order; the seventh item wraps to the next row within the defined column structure. - Flexbox with
flex-wrap: wrap: items flow seamlessly into new lines, but each line is independent — there’s no “row” alignment across lines. Odd numbers of items distribute space per line.
Exam tip: Flexbox is ideal for distributing a set of items along one axis and letting them wrap naturally. Grid is for aligning items across both axes in a predictable grid.
When to Use Each
- Use Flexbox for simple one-dimensional layouts: nav bars, footers, rows of buttons, cards in a single row/column. Its strength lies in alignment and distribution along one direction (
justify-content,align-items,flex-wrap). - Use Grid for full page layouts where you need control over both rows and columns simultaneously: header, sidebar, main content, footer. Grid defines the overall structure; items are placed into named areas.
Working Together (Complementary)
Flexbox and Grid are not mutually exclusive. Use Grid for the big picture (page structure) and Flexbox for the details (alignment within each grid cell).
Worked Example: Page Layout with Grid + Flexbox
A typical responsive page structure:
Page Container (display: grid)
├── Header (display: flex → justify-content: center, align-items: center)
├── Sidebar (display: flex → flex-direction: column, justify-content: flex-start)
├── Main Content (display: flex → flex-direction: column, align-items: center)
└── Footer (display: flex → justify-content: center, align-items: center)
Grid setup for the page container:
grid-template-columns: repeat(3, 1fr)— three equal columnsgrid-template-rows: 10% auto 10%— header 10%, main content auto, footer 10%grid-template-areas:"header header header" "sidebar main main" "footer footer footer"- Each child gets a
grid-areaname matching the template.
Flexbox inside each area:
- Header:
display: flex; justify-content: center; align-items: center; gap: 2em→ navigation links centered. - Sidebar:
display: flex; flex-direction: column; justify-content: flex-start; align-items: center; padding: 10%→ buttons stacked vertically. - Main content:
display: flex; flex-direction: column; align-items: center→ paragraphs centered. - Footer:
display: flex; justify-content: center; align-items: center→ centered text.
Result: a full-page layout built in seconds, responsive by default (relative units like 1fr and %).
Key Takeaways
- Flexbox is one-dimensional; Grid is two-dimensional.
- Flexbox is content-driven; Grid is structure-first.
- Use Flexbox for alignment and distribution within a container; use Grid for overall page layout.
- They complement each other: Grid for the macro layout, Flexbox for micro alignment inside cells.
- Flexbox wraps items naturally; Grid forces items into defined rows/columns.
- Properties like
justify-contentbehave differently: in Flexbox it aligns items along the main axis; in Grid it aligns the entire grid tracks (usejustify-itemsfor aligning items within cells).
Media Queries
Media queries are CSS rules that apply styles conditionally based on properties of the user's device — most commonly screen width, but also orientation, resolution, and more. They are the backbone of responsive design: they let a single HTML page change layout, font sizes, visibility, and other styles at specific breakpoints (width thresholds where the page restructures).
Intuitively: a website that looks great on a 27‑inch monitor would be unusable on a phone. Media queries are the switch that flips the design at the right screen sizes — no JavaScript needed.
Syntax and Key Properties
A media query starts with @media, followed by a condition in parentheses, then a block of normal CSS rules.
@media (condition) {
/* CSS rules go here */
}
Two width‑based conditions are most common:
| Condition | Meaning (English) | Logical equivalent |
|---|---|---|
max-width: 750px | At most 750 px wide | width ≤ 750px |
min-width: 1200px | At least 1200 px wide | width ≥ 1200px |
(min-width: 800px) and (max-width: 1000px) | Width between 800 px and 1000 px | 800px ≤ width ≤ 1000px |
Exam tip:
max-width= “up to and including”.min-width= “starting at and above”. Think ofmaxas a ceiling andminas a floor.
Combining Conditions with and
You can write a range by joining min-width and max-width with the and keyword:
@media (min-width: 800px) and (max-width: 1000px) {
body { background-color: brown; }
}
This style is active only when the viewport is at least 800 px AND at most 1000 px.
How Real Sites Use Breakpoints
Inspecting live responsive sites (e.g., Adidas, Mokobara) reveals multiple breakpoints:
- At ≈1150 px: navigation restructures (menu collapses into a hamburger icon).
- At ≈700 px: search bar moves, layout switches from multi‑column to single column.
These thresholds are defined with media queries in the site’s CSS. The design “breaks” at specific widths and reassembles — hence the term breakpoint.
flowchart LR
A[Viewport width] --> B{Check breakpoints}
B -->|"width ≥ 1200px"| C[4‑column grid, full nav]
B -->|"800px ≤ width < 1200px"| D[2‑column grid, condensed nav]
B -->|"width < 800px"| E[1‑column grid, hamburger menu]
Worked Example: Responsive Grid Layout
Goal: a grid of items that shows 4 columns on wide screens, 2 columns on tablets, and 1 column on phones.
HTML
<div class="grid-container">
<div>1</div><div>2</div><div>3</div><div>4</div>
</div>
CSS – start with a default (any rules outside media queries apply unless overridden):
.grid-container {
display: grid;
justify-items: center;
}
Now add media queries targeting specific ranges:
/* Phone: max-width 750px → 1 column */
@media (max-width: 750px) {
.grid-container {
grid-template-columns: 1fr;
}
}
/* Tablet: between 800px and 1000px → 2 columns */
@media (min-width: 800px) and (max-width: 1000px) {
.grid-container {
grid-template-columns: 1fr 1fr;
}
}
/* Wide desktop: min-width 1200px → 4 columns */
@media (min-width: 1200px) {
.grid-container {
grid-template-columns: repeat(4, 1fr);
}
}
What happens when the viewport shrinks:
- ≥1200 px → four equal columns.
- 800–1000 px → two columns.
- ≤750 px → single column.
- Gaps between breakpoints (e.g., 751–799 px) apply no media‑query rules, so the default
grid-template-columns(if any) or fallback behaviour takes effect.
The same pattern is used on real e‑commerce sites like Adidas: product grids change from 4‑column → 3‑column → 2‑column at different breakpoints.
Exam tip: Avoid overlapping breakpoints. Use
max-widthfor “up to”,min-widthfor “from”, andandfor ranges. Plan breakpoints at natural content thresholds, not arbitrary pixel values.
Other Common Uses
- Images – make images full‑width on mobile, side‑by‑side on desktop.
- Typography – increase font size on larger screens.
- Visibility – hide/show elements (e.g., a hamburger menu icon) based on width.
- Padding and margins – reduce whitespace on small screens.
Key Takeaways
- Media queries apply CSS only when a condition (usually viewport width) is met.
max-width: X= applies to widths ≤ X;min-width: X= applies to widths ≥ X.- Use
andto combine conditions for a range:(min-width: A) and (max-width: B). - Breakpoints are the width values where the design restructures; inspect real sites to find common ones (e.g., 768 px, 992 px, 1200 px).
- Media queries are purely CSS — no JavaScript required for responsive behaviour.
- They can control grids, images, navigation, colours, and any other CSS property.
Bootstrap
A CSS framework is a box of ready-made tools – pre-written CSS components and classes that speed up styling. Bootstrap is the most widely used CSS framework, especially on older sites. Among sites that use a framework, Bootstrap dominates (Tailwind CSS is gaining on newer projects).
Adding Bootstrap via CDN
- Copy the CDN (Content Delivery Network) link into
<head>before your own stylesheet (so your custom CSS overrides Bootstrap). - Copy the JavaScript bundle
<script>into<body>after all content – required for interactive components (dropdowns, carousels, navbars).
<!-- CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- JS (at end of body) -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
Layout Grid System
Bootstrap’s layout is based on a 12-column grid under the hood (it uses Flexbox, not CSS Grid). Three layers: container → row → col.
- Container (
.container) gives a responsive fixed-width wrapper; its max-width changes at predefined breakpoints. - Row (
.row) is a Flexbox container with negative margins to offset column padding. - Column (
.col) automatically takes equal width. Specify width with.col-{number}(sum to 12). Use responsive variants:.col-md-6,.col-lg-4.
| Breakpoint | Infix | Container max-width | Window ≤ → full width |
|---|---|---|---|
| Extra small | (none) | 100% | Always full |
| Small | sm | 540px (approx) | < 576px → 100% |
| Medium | md | 720px | < 768px → 100% |
| Large | lg | 960px | < 992px → 100% |
| Extra large | xl | 1140px | < 1200px → 100% |
| XXL | xxl | 1320px | < 1400px → 100% |
The transcript only mentioned container max-width for
xlas 1320px and that.container-lgbecomes full-width below 960px. Breakpoint pixel values above are standard Bootstrap values; if the lecture didn't state them exactly, rely only on the stated values.
Example: three equal columns
<div class="container">
<div class="row">
<div class="col">Column 1</div>
<div class="col">Column 2</div>
<div class="col">Column 3</div>
</div>
</div>
To control width ratios, use numbered classes: .col-4, .col-3, .col-5 (4+3+5=12). Or mix with .col-auto (width based on content).
Utility Classes
Bootstrap provides shorthand classes for spacing, borders, colors, alignment, etc. Notation: {property}{sides}-{size}.
| Property | Code | Meaning |
|---|---|---|
| Margin | m | margin |
| Padding | p | padding |
| Sides | t | top |
b | bottom | |
s | left (start) | |
e | right (end) | |
x | left + right | |
y | top + bottom | |
| (none) | all sides | |
| Size | 0 | 0 |
1 | 0.25rem | |
2 | 0.5rem | |
3 | 1rem | |
4 | 1.5rem | |
5 | 3rem |
Examples: mt-3 (margin-top 1rem), px-5 (padding-left/right 3rem), mx-auto (auto horizontal margin for centering).
Borders: .border, .border-top, .border-0, .border-primary, .border-5 (width 5px).
Colors: predefined color classes – primary (blue), secondary, success (green), danger (red), warning (orange), etc.
Alignment: text-center, justify-content-center, align-items-start, etc. (equivalent to Flexbox properties).
Components
Bootstrap ships with pre-styled components – copy HTML from the docs and modify classes.
- Buttons: use classes
.btn,.btn-primary,.btn-warning, etc. - Cards:
.cardwith.card-img-top,.card-body,.card-title,.card-text,.btn. - Navbar:
.navbar,.navbar-expand-lg,.nav-item,.nav-link. Responsive hamburger menu requires JavaScript. - Hero sections, forms, icons – all available as examples in the Bootstrap docs.
Exam tip: You do not need to memorise every class; learn how to navigate the documentation and copy‑paste components. The power of Bootstrap is rapid prototyping using pre‑built, professional styles.
Pros and Cons of Frameworks (like Bootstrap)
| Pros | Cons |
|---|---|
| Fast development – no need to write complex media queries | Many classes cluttering HTML |
| Professional styling out of the box | Harder to achieve completely custom designs |
| Well-thought-out, responsive grid | Over-reliance on framework can stifle learning vanilla CSS |
| Large community and documentation | Updating the framework may break custom overrides |
Key Takeaways
- Bootstrap is a CSS framework: a set of ready‑made classes for layouts, utilities, and components.
- Always link via CDN: CSS in
<head>, JavaScript bundle at end of<body>. - The grid system uses
container > row > colwith a 12‑column flexbox layout; responsive breakpoints control width. - Utility classes (
m-*,p-*,border-*, etc.) replace hand‑written CSS for spacing, borders, colors. - Components (buttons, cards, navbar) are copied from docs and customised; interactive ones need the JS bundle.
- Underneath, all Bootstrap styles use standard CSS properties (Flexbox, media queries, colors). Understand the fundamentals to troubleshoot and customise.
Module Summary: Advanced CSS and Responsive Design
Module 5 covered advanced CSS layout and responsiveness — specifically Flexbox, CSS Grid, media queries, and a brief introduction to the Bootstrap framework. The core expectation is to apply these tools to create a well‑structured, responsive website that works seamlessly on mobile and desktop.
Assignment: Build a Responsive Site
Students must enhance their personal resume website from Module 4 using the following techniques:
- Layout – Use Flexbox or Grid to arrange all components across different pages.
- Bootstrap integration – Optionally use Bootstrap components, icons, or its grid system to improve layout.
- Responsiveness – Add media queries to ensure the site looks great on all screen sizes.
Deliverable: A responsive website that functions well on both mobile and desktop devices.
Looking Ahead
The next two modules will cover JavaScript — introducing interactivity and dynamic behaviour into websites.
Key takeaways
- Module 5 focuses on Flexbox, Grid, media queries, and Bootstrap.
- The assignment requires applying these tools to build a responsive resume site.
- Responsive design (via media queries) is mandatory for mobile‑friendly layout.
- Bootstrap components and grid are optional enhancements.
- JavaScript (interactivity) is the next major topic.
Basics of Javascript
What JavaScript Does
JavaScript transforms a static website (HTML + CSS) into a dynamic, interactive experience. Without JavaScript, a page is like a beautiful picture: it can look good but cannot respond to clicks, update content in real time, or fetch live data. JavaScript gives instructions to HTML elements — a script that tells each part what to do and when.
Real-world examples (all require JavaScript)
- Moneycontrol.com – interactive charts, live stock data, ads. Disabling JavaScript breaks chart rendering and removes ads.
- Timeanddate.com – a continuously ticking clock. Without JavaScript, the time freezes on page load.
- Flex (creative portfolio) – scroll-triggered animations, colour changes, horizontal scrolling, falling elements.
- Mission Mass – dynamic page transformations (scroll-driven direction changes).
These sites become unresponsive or broken when JavaScript is turned off.
A brief history
- 1995 – Netscape Navigator held >80% browser market share. Websites were static; every interaction required a server request.
- Netscape hired Brendan Eich, who created JavaScript in 10 days. Originally called LiveScript, renamed to JavaScript to capitalise on Java’s popularity (they are completely different languages).
- Standardised as ECMAScript (abbreviated ES). Modern versions: ES5, ES6 (and later).
- Today, sites like Twitter, YouTube, Netflix, and most of the web depend entirely on JavaScript.
How JavaScript works
Computers understand only binary (0s and 1s). JavaScript is a programming language that acts as a translator: we write human-readable instructions (e.g., alert("Hello")), and the browser’s JavaScript engine converts those instructions into machine code.
JavaScript code Browser engine Machine instructions
(human) → (interpreter) → (0s and 1s)
JavaScript is an interpreted language (runs line‑by‑line in the browser), unlike Java which is compiled.
Key takeaways
- JavaScript makes websites interactive (live updates, click responses, animations).
- It was created in 10 days at Netscape (1995) and standardised as ECMAScript.
- JavaScript is not related to Java; it runs in all major browsers.
- It translates our instructions into commands the browser can execute.
Where to write JavaScript
- Chrome DevTools Console – for quick one‑line tests.
- Open: Menu → More tools → Developer tools (or right‑click → Inspect → Console tab).
- Type
alert("Hello");and press Enter → a popup appears. - Use
Shift+Enterto write multiple lines before executing.
- Chrome DevTools Snippets – for longer code that can be saved and re‑run.
- Sources tab → Snippets (may need to click
>>to find it) → New snippet. - Write code, save, click Run (or
Ctrl/Cmd+Enter). - Output appears in a console at the bottom.
- Sources tab → Snippets (may need to click
- In HTML files (later modules) – JavaScript is added via
<script>tags in a.htmlfile, run with Live Server.
| Tool | Best for | Notes |
|---|---|---|
| Console | Quick tests, single expressions | Not saved; accidental Enter executes |
| Snippets | Multi‑line code, saved snippets | Saved in browser, easy to rerun |
HTML <script> | Full web pages | Used in later modules for DOM |
First command: alert()
alert("Hello");
alert("Hi");
alert("Hello boss");
alert– a built‑in keyword that calls a function (technicallywindow.alert()).- Parentheses
()– hold the argument (the message). - Quotation marks
" "or' '– enclose a string (text). - Semicolon
;– marks the end of an instruction (like a full stop). Always include it.
If you type an invalid command, e.g., sayHi, the browser returns:
Uncaught ReferenceError: sayHi is not defined
Using MDN documentation
To verify valid JavaScript commands and learn details, search MDN JavaScript (Mozilla Developer Network).
Example: search “MDN alert” to see the full specification, variants like open(), focus(), prompt(), etc.
Exam tip:
alert()is a method of thewindowobject, but you can write justalert(). Semicolons are optional in many cases, but using them consistently prevents errors.
Key takeaways
- Use Chrome DevTools Console for one‑liners, Snippets for longer code.
alert()syntax: keywordalert, parentheses, quoted message, semicolon.- Semicolon ends a statement.
- Use MDN as the authoritative reference for JavaScript methods and syntax.
Data Types in JavaScript
Data types define the kind of value a variable can hold — like a water bottle holds water, a box holds toys. In JavaScript, every value has a type, and knowing the type tells you what operations you can perform.
String
A string is a sequence of characters used to represent text. Strings are enclosed in single quotes ('), double quotes ("), or backticks (`).
"Govind" // double quotes
'IIM Bangalore' // single quotes
`IIMB space` // backticks
'' // empty string - still a string
"1234" // digits in quotes - still a string
- Strings can contain letters, numbers, symbols, and special characters (e.g.,
\nfor newline). - Useful for messages, user input, and joining text (concatenation).
Number
A number represents numeric values — integers and decimals alike. JavaScript treats all numbers as the same type (no separate integer/floating distinction).
25
4.5
- Arithmetic operations (
+,-,*,/) work on numbers. - If you wrap digits in quotes (e.g.,
"25"), they become a string, not a number.
Boolean
A boolean has only two possible values: true or false. It is used for decisions and conditional logic.
true
false
- Often results from comparisons (e.g.,
5 > 3→true).
The typeof Operator
Use the typeof operator to check the data type of a value. It is an operator, not a function — no parentheses needed.
typeof "hello" // "string"
typeof 42 // "number"
typeof true // "boolean"
typeof "" // "string"
typeof "1234" // "string" (because quoted)
Exam tip:
typeofis an operator, not a function. Common mistake: writingtypeof(x)— while it works, the correct form istypeof x. Prefer the operator form.
Why Data Types Matter
- Operations behave differently per type: adding numbers sums them; adding strings joins them.
- Knowing the type helps avoid bugs, especially when data comes from user input or external APIs.
typeofis your first debugging tool to confirm what you're working with.
Key takeaways
- String – text in quotes (
"",'', backticks). - Number – any numeric value (no separate integer/decimal).
- Boolean –
trueorfalse. typeof– operator to return the type as a string.- Same literal (e.g.,
25vs"25") can be number or string depending on quotes.
Variables in JavaScript
A variable is a labelled container that stores a value so you can reuse or change it later. Think of it as a box with a label, or a tentacle that grabs a value and can later grab a different one.
Declaring Variables
Three keywords create variables:
| Keyword | Use case | Can reassign? |
|---|---|---|
let | Modern, value may change | Yes |
var | Older style, similar to let but different scope | Yes |
const | Value must stay constant | No (error on reassignment) |
Syntax: keyword variableName = value;
let name = "Govind"; // declare + assign
let month = "January";
const birthYear = 1990; // cannot change later
var price = 200; // older way
- Variable names should be meaningful (
citynotx). - Use
letby default in modern code; useconstwhen the value is fixed.
Assignment and Reassignment
- Declaration creates the variable (using
let,var, orconst). - Assignment gives it a value with
=. - Reassignment changes the value without repeating the keyword.
let city = "Mumbai";
city = "Bangalore"; // reassign – no let/var/const
With const, reassignment throws an error:
const name2 = "Govind";
name2 = "Raj"; // ❌ TypeError: Assignment to constant variable
Reading Variable Values
Use the variable name anywhere you need its value:
let age = 99;
age; // → 99
console.log() – Viewing Values
The console.log() function prints values to the console. It accepts literals (in quotes) or variable names (without quotes).
let greeting = "Hello, welcome!";
console.log(greeting); // prints the variable's value
console.log("Hello"); // prints a string literal
console.log(10); // prints a number
- Essential for debugging and understanding what your code is doing.
Undefined Variables
Referencing a variable that was never declared causes a ReferenceError:
console.log(country); // ❌ country is not defined
Declare it first:
let country = "India";
console.log(country); // → India
Key takeaways
- Variables are containers; declare with
let,var, orconst. letandvarallow reassignment;constdoes not.- Syntax:
let name = value;– keyword, name,=, value, semicolon. - Reassign without repeating the keyword:
name = newValue; console.log()prints values — use it for debugging.- Accessing an undeclared variable throws an error.
Variables with Alert and Prompt
Alert and prompt are built‑in browser functions that let a JavaScript program communicate with the user.
Alert displays a message (popup with an OK button). Prompt asks for input and returns whatever the user types.
Intuition: you want a tiny conversation — ask the user something, store their answer, then respond using that answer.
Syntax
alert("Your message here");
let variableName = prompt("Question for the user");
- alert – takes one string argument; shows the string in a pop‑up.
- prompt – takes one string argument (the question); returns the string the user typed (or
nullif cancelled).
Worked Example – Greet the User
let username = prompt("What is your name?");
alert("Hi " + username + ", welcome to this course.");
Flow:
flowchart LR
A[User types name] --> B[Value stored in username]
B --> C[alert combines text + username]
If the user enters “Shahrukh”, the alert shows: Hi Shahrukh, welcome to this course.
String Concatenation
The + operator joins (concatenates) strings together.
"Hi " + username + ", welcome" becomes one continuous string.
Exam tip: When a variable holds a number (e.g. from
prompt), it is actually a string by default. Concatenation still works, but be aware that"5" + 3="53"(string), not8.
Second Example – Age
let age = prompt("What is your age?");
alert("Wow, you are " + age + " years old.");
You can reuse the same variable in multiple places:
alert("Wow " + username + ", you are " + age + " years old.");
Key Takeaways
- alert displays a message; prompt gets user input.
- prompt returns a string; store it in a variable for later use.
- Use
+to concatenate strings and variables. - Combining prompt and alert creates simple interactive programs.
- Variables become dynamically assigned – their value comes from user input at runtime.
Variable Naming Rules and Camel Case
Good variable names make code readable and maintainable. JavaScript has strict rules and community conventions.
Allowed Characters
- Letters (a–z, A–Z)
- Digits (0–9) – but cannot start with a digit
- Underscore (
_) and dollar sign ($) – avoid both at the start (underscore has special meaning in many contexts)
let name = "Govind"; // valid
let NAME = "Raj"; // different variable (case‑sensitive)
let name123 = "Lakshmi"; // valid
let 1name = "error"; // ❌ SyntaxError
What to Avoid
| Rule | Why |
|---|---|
No special characters (@,#,%) | Cause syntax errors |
| No spaces | let user age → unexpected number |
| No JavaScript reserved words | let, const, function, if, etc. |
No starting with _ (convention) | Reserved for internal/protected properties |
| No starting with a digit | Illegal token |
Exam tip: Reserved words include
break,case,catch,class,const,continue,debugger,default,delete,do,else,export,extends,finally,for,function,if,import,in,instanceof,let,new,return,super,switch,this,throw,try,typeof,var,void,while,with,yield. Never use them as variable names.
Case Sensitivity
name and NAME are two different variables. JavaScript is case‑sensitive.
Lower Camel Case (Recommended Convention)
Start with a lowercase letter; capitalise the first letter of each subsequent word.
let userName = "Govind"; // camelCase
let userAge = 21;
let cityOfResidence = "Mumbai";
let workOfArt = "picasso";
Without camelCase: workofart could be misread as work of art or workof art.
With camelCase: workOfArt is instantly clear.
Best Practices
- Descriptive –
let totalItemsinstead oflet x. - Concise – avoid overly long names like
totalNumberOfElementsInCart; usetotalItems. - Consistent – stick to camelCase throughout your project.
- Meaningful – the name should indicate what data the variable holds.
Dynamic Typing
JavaScript does not require you to declare a data type. The type is determined by the assigned value – and can change later.
let age = 25; // number
age = "twenty five"; // now string – no error
This flexibility is powerful but can cause bugs. Clear naming helps you (and others) keep track of what type is expected.
Key Takeaways
- Variable names: letters, digits (not first),
_,$. No spaces, no reserved words. - Case‑sensitive –
myVar≠myvar. - Use lower camelCase –
userName,totalPrice. - Be descriptive yet concise.
- JavaScript is dynamically typed – same variable can hold different types.
Variable Reassignment
Variable reassignment means giving a new value to a variable that already exists. A variable’s value can be changed at any time, and assigning one variable to another copies the current value (for primitive types like strings and numbers). This is a foundational concept for understanding how JavaScript stores and manages data in memory.
Swapping values
A classic task is swapping the values of two variables (e.g., cup1 = "coffee", cup2 = "tea" → swap so cup1 holds "tea" and cup2 holds "coffee").
Method 1: using a temporary (third) variable
- Store the value of
cup1into a third variablecup3. - Assign
cup1the value ofcup2. - Assign
cup2the value ofcup3.
let cup1 = "coffee";
let cup2 = "tea";
let cup3; // empty cup
cup3 = cup1; // cup3 = "coffee"
cup1 = cup2; // cup1 = "tea"
cup2 = cup3; // cup2 = "coffee"
After the swap: cup1 → "tea", cup2 → "coffee", cup3 still holds "coffee".
How copying works: When we wrote
cup3 = cup1, the value"coffee"was copied intocup3. Changingcup1later (e.g.,cup1 = "juice") does not affectcup3– each variable has its own independent memory slot.
Method 2: arithmetic swap (numbers only)
For numeric variables, values can be swapped without an extra variable using addition and subtraction.
let x = 5, y = 10;
y = x + y; // y = 5 + 10 = 15
x = y - x; // x = 15 - 5 = 10
y = y - x; // y = 15 - 10 = 5
console.log(x, y); // 10, 5
Why it works: The trick uses the sum as a temporary storage. After the first step, y holds the sum (x + y); then x becomes the original y (sum – original x), and finally y becomes the original x (sum – new x).
Exam tip: The arithmetic swap is a clever trick but only works for numbers (and can fail with very large values causing overflow, or with floats). In real code, use a temporary variable – it’s clearer and works for any type.
Key insight: primitive values are copied, not referenced
When you assign let a = b for primitive values (strings, numbers, booleans, null, undefined, Symbol, BigInt), JavaScript copies the value. The two variables become completely independent:
let x = 2;
let y = x; // y = 2 (a copy)
x = 10; // x changes, but y remains 2
console.log(y); // 2
This applies to the cup example: after the swap, cup3 still holds "coffee". If you later write cup3 = "juice", cup2 does not change.
Contrast with objects: (Out of scope for this lecture, but note that objects and arrays are stored by reference, not copied.)
Key takeaways
- Assigning a primitive variable to another copies the value – each variable has its own memory slot.
- Swapping values can be done with a temporary variable (any type) or with arithmetic (numbers only).
- After a copy, modifying one variable does not affect the other.
- The arithmetic swap trick is efficient but limited – know it as an exercise, but prefer the temp-variable method in practice.
Strings: Indexing, Properties, Concatenation
A string is an ordered sequence of characters used to represent text. In JavaScript, strings can be written with double quotes (" "), single quotes (' '), or backticks (` `). All are equivalent – the choice is stylistic.
Indexing and Bracket Notation
Computers count positions starting at zero – this is zero-based indexing.
Take let greeting = "Hello".
The character–index mapping:
| Character | Index |
|---|---|
| H | 0 |
| e | 1 |
| l | 2 |
| l | 3 |
| o | 4 |
To retrieve a character, use bracket notation: string[index].
greeting[0]→"H"greeting[1]→"e"greeting[4]→"o"
If the index exceeds the last valid position, JavaScript returns undefined – no error is thrown, the program continues.
greeting[99]→undefined
Exam tip: Accessing out-of-bounds always gives
undefined, not an error. This is a frequent interview and exam question.
The .length Property
The length property returns the total number of characters in the string. It is a property, not a method – no parentheses.
"Hello".length→5- The highest valid index is always
length - 1(here,4).
Because indexing starts at zero, length is one greater than the last index. For "Simran" (6 characters), Simran.length = 6 and Simran[5] = "n".
Concatenation and Type Coercion
Strings can be joined with the + operator – this is concatenation.
"Raj" + " Simran" → "Raj Simran"
When a string and a number are added, JavaScript performs type coercion: it converts the number to a string before concatenating.
"1" + 1→"11"(string)"Hello" + 42→"Hello42"
This can lead to unexpected results:
| Expression | Result | Explanation |
|---|---|---|
"1" + 1 | "11" | Number 1 coerced to string |
1 + "1" | "11" | Same coercion |
1 + 1 + "2" | "22" | Left-to-right: 1+1=2, then 2 + "2" = "22" |
"2" + 1 + 1 | "211" | Left-to-right: "2" + 1 = "21", then "21" + 1 = "211" |
Exam tip: Avoid mixing strings and numbers in the same expression. If concatenation is intended, convert numbers manually with
String(n)or.toString()to make intent clear.
Immutability
Strings are immutable – once created, their individual characters cannot be changed by assigning to an index.
let animal = "cat";
animal[0] = "b"; // no error, but does nothing
console.log(animal); // still "cat"
To modify a string, you must reassign the entire variable:
animal = "bat"; // works
This applies to all string manipulations – any operation that appears to change a string actually returns a new string.
Key takeaways
- Strings are zero-indexed; use
str[i]to access characters. - Out-of-bounds indexing yields
undefined, not an error. .lengthgives the character count (not the highest index).+joins strings; mixing numbers and strings causes type coercion — be explicit.- Strings are immutable – direct character assignment fails; reassign the whole string.
String Methods
String methods are functions attached to string objects that perform actions on text — converting case, trimming whitespace, searching, extracting, replacing, and more. Unlike string properties (e.g., .length), methods do work and always end with parentheses (). Most string methods do not modify the original string; they return a new string instead.
Syntax
string.method(arg1, arg2, ...)
stringcan be a variable or a string literal.- The parentheses may contain optional arguments — values that control the method's behaviour.
Common string methods at a glance
| Method | What it does | Returns |
|---|---|---|
.toUpperCase() | Converts all characters to uppercase. | New string |
.toLowerCase() | Converts all characters to lowercase. | New string |
.trim() | Removes whitespace from both ends. | New string |
.indexOf() | Finds the first index of a substring (search from start). | Number or -1 |
.slice() | Extracts a part of the string (by index). | New string |
.replace() | Replaces the first occurrence of a substring with another. | New string |
.repeat() | Repeats the string a specified number of times. | New string |
Exam tip:
.indexOfreturns-1when the substring is not found — a common bug if you forget to check for that.
1. Changing Case: .toUpperCase() and .toLowerCase()
Intuition: Convert text to all caps or all lowercase, e.g., for normalising user input.
Examples (from lecture):
let name = "govind";
console.log(name.toUpperCase()); // "GOVIND"
console.log(name); // "govind" (original unchanged)
let shout = "Hello!";
console.log(shout.toLowerCase()); // "hello!"
2. Cleaning Whitespace: .trim()
Intuition: Remove accidental spaces before/after user input — common in form data.
Behaviour: Removes spaces, tabs, newlines from both ends. Returns a new string.
let badInput = " hello world ";
let clean = badInput.trim();
console.log(clean); // "hello world"
console.log(badInput); // " hello world " (unchanged)
3. Searching: .indexOf(substring, start?)
Intuition: Find where a piece of text first appears inside a string. Useful for checking existence or extracting from a known point.
- Returns the index (0-based) of the first occurrence of
substring. - The optional second argument –
start– tells the method to begin searching from that index. - Returns
-1ifsubstringis not found.
Examples:
let paragraph = `I think Ruth's dog is cuter than your dog.`;
console.log(paragraph.indexOf("T")); // 2
console.log(paragraph.indexOf("TH")); // 2
console.log(paragraph.indexOf("dog")); // 13
console.log(paragraph.indexOf("dog", 14)); // 37 (starts searching from index 14)
console.log(paragraph.indexOf("cat")); // -1 (not found)
4. Extracting a Substring: .slice(start, end?)
Intuition: Cut out a portion of a string by index — like a pair of scissors for text.
- If only
startgiven: returns from that index to the end. - If
startandendgiven: returns fromstartup to but not includingend. - Negative indices count from the end of the string (
-1= last character).
Examples:
let paragraph = "I think Ruth's dog is cuter than your dog.";
console.log(paragraph.slice()); // whole string
console.log(paragraph.slice(5)); // "nk Ruth's dog is cuter than your dog."
console.log(paragraph.slice(5, 10)); // "nk Ru"
console.log(paragraph.slice(-2)); // "g."
console.log(paragraph.slice(-10)); // " your dog."
Exam tip:
.slice()does not modify the original string — always store the result in a new variable.
5. Replacing Text: .replace(search, replacement)
Intuition: Find a specific substring and swap it with something else. Only the first match is replaced.
search: the substring (or regex) to look for.replacement: the new string to put in its place.
Examples:
let paragraph = "I think Ruth's dog is cuter than your dog.";
let newPar = paragraph.replace("dog", "cat");
console.log(newPar); // "I think Ruth's cat is cuter than your dog."
// Only the first "dog" changed.
// Replace only part of a word
let partial = paragraph.replace("do", "DE");
// "I think Ruth's DEg is cuter than your dog."
For advanced replacements (all occurrences, case-insensitive), use regular expressions.
6. Repeating Text: .repeat(count)
Intuition: Generate a string repeated
counttimes – useful for padding, ASCII art, or test data.
console.log("ha".repeat(3)); // "hahaha"
Chaining Methods
Because each method returns a new string, you can call another method on the result — forming a method chain. This makes code concise.
Without chaining:
let corrected = badInput.trim();
let upper = corrected.toUpperCase();
With chaining:
let best = badInput.trim().toUpperCase();
console.log(best); // cleaned and uppercased, all in one line
The order matters: first trim, then uppercase (or vice versa – both work here).
Key Takeaways
- String methods are called with parentheses; properties (like
.length) are not. - Most methods return a new string and leave the original untouched – always capture the result in a variable.
.indexOfreturns-1when not found..slice(start, end)does not include the character atend..replaceonly replaces the first match (use regex for global).- Method chaining lets you combine multiple operations in one expression.
- MDN Web Docs is the authoritative reference for all string methods – bookmark it.
String Template Literals
Template literals are a cleaner, more readable way to create strings in JavaScript when you need to embed variables or expressions. Instead of glueing pieces together with +, you use backticks (`) and placeholders written as ${ ... }.
The problem: concatenation
let name = "Govind";
let age = 99;
let city = "Bangalore";
let country = "India";
alert("Hi " + name + " from " + city + ", " + country + "! Welcome here to our tutorial.");
This works, but:
- Hard to read and write – many
+signs and manual spacing. - Adding apostrophes or special characters forces quote changes.
- Long strings become error‑prone.
Template literal syntax
Use backticks instead of single or double quotes. Inside, any ${ expression } is evaluated and converted to a string automatically.
alert(`Hi ${name} from ${city}, ${country}! Welcome here to our tutorial.`);
| Feature | Old concatenation | Template literal |
|---|---|---|
| Quote style | ' or " | ` (backtick) |
| Variable insertion | "..." + var + "..." | `${var}` |
| Expression insertion | Must pre‑compute | `${2 + 4}` → "6" |
| Multi‑line strings | Need \n | Just press Enter inside backticks |
Exam tip: Template literals only work with backticks. Using single or double quotes will treat
${...}as literal text, not an expression.
Embedding any expression
Anything inside ${ } is a valid JavaScript expression – variables, arithmetic, function calls, even conditional logic. The result is coerced to a string.
let price = 25;
alert(`The price for ${ask} is $${price}.`); // → The price for eggs is $25.
To include a literal dollar sign, write $ before the placeholder – only ${ triggers evaluation.
Multi‑line strings
Template literals preserve line breaks. No \n needed.
alert(`Hi
Yes`);
// Output:
// Hi
// Yes
Key takeaways
- Template literals use backticks (
`) and${...}placeholders. - They replace cumbersome
+concatenation. - Any expression inside
${}is evaluated and string‑coerced. - Multi‑line content is natural – just hit Enter.
- Always use backticks; single/double quotes do not support template syntax.
Null and Undefined
Both represent “nothing” but are used in different scenarios.
| Concept | Who sets it? | Meaning | typeof |
|---|---|---|---|
undefined | Automatically by JavaScript | A variable has been declared but not assigned; a missing property. | "undefined" |
null | Explicitly by the programmer | “I intend to leave this empty.” | "object" (historical quirk) |
Undefined
JavaScript assigns undefined when something hasn’t been defined yet.
let x;
console.log(x); // undefined
Also appears when:
- Accessing a non‑existent array index:
"abc"[10]→undefined - A function returns nothing:
function f() {}→undefined
Null
You assign null to indicate a variable is intentionally empty.
let y = null;
console.log(y); // null
typeof y; // "object" (this is a long‑standing JS bug, but testable)
Exam tip:
nullis an object type in JavaScript – a historical mistake.undefinedis its own type. They are loosely equal (null == undefined→true) but strictly not equal (null === undefined→false).
When to use each
- Use
nullwhen you want to explicitly say “no value here” (e.g., future assignment, cleared data). - Let JavaScript give you
undefinedwhen something is missing – you do not usually assignundefinedyourself.
Key takeaways
nullis programmer‑set;undefinedis JS‑set.typeof null→"object";typeof undefined→"undefined".- Both mean “nothing”, but context matters.
- Loosely equal (
==), but strict equality (===) isfalse.
Numerical Operators
JavaScript provides arithmetic operators to perform basic math on numbers. Intuition: these work like a calculator but live inside code, operating on variables or literal values.
Arithmetic Operators
| Operator | Name | Example (x=10, y=20) | Result |
|---|---|---|---|
+ | Addition | x + y | 30 |
- | Subtraction | x - y | -10 |
* | Multiplication | x * 5 | 50 |
/ | Division | y / 5 | 4 |
** | Exponentiation (power) | x ** 2 | 100 |
% | Modulus (remainder) | 10 % 3 | 1 |
Modulus is especially useful for checking divisibility — e.g., a number is even if
number % 2 === 0.
Order of Operations (Operator Precedence)
JavaScript follows the same precedence as standard math: Parentheses → Exponents → Multiplication/Division → Addition/Subtraction (PEMDAS / BODMAS). Evaluation is left-to-right for operators of equal precedence.
flowchart LR
A[Expression] --> B{Parentheses first?}
B -->|Yes| C[Evaluate inside ()]
C --> D
B -->|No| D[Exponents **]
D --> E[* / % left to right]
E --> F[+ - left to right]
F --> G[Result]
Best practice: Use parentheses () to make intent explicit, even when precedence is clear.
(5 + 2) * 3→ clearly first add, then multiply.5 + 2 * 3→11(multiply first:2*3=6, then5+6=11).
Special Operators
Increment (++) and Decrement (--)
- Increase or decrease a variable by exactly 1.
- Only work on variables (not on literals like
5++). - Modify the variable in place.
let x = 10;
x++; // x becomes 11
x--; // x becomes 10 again
Compound Assignment Operators
Used to modify a variable by a larger amount concisely.
| Operator | Equivalent to | Example (starting x=10) |
|---|---|---|
x += 4 | x = x + 4 | x → 14 |
x -= 5 | x = x - 5 | x → 5 |
x *= 2 | x = x * 2 | x → 20 |
x /= 2 | x = x / 2 | x → 5 |
Exam tip:
++and--change the variable itself — they are not expressions that return a new value (though they can be used in expressions; prefix vs. postfix matters, but this lecture only covers the basic postfix form).
Worked Example: Check if a number is even
let num = 21;
if (num % 2 === 0) {
console.log("even");
} else {
console.log("odd");
}
// Output: odd
Key takeaways
- Six core arithmetic operators:
+, -, *, /, **, %. - Use
%to get remainder;num % 2 === 0tests evenness. - Order: Parentheses → Exponents → MD → AS. Use parentheses for clarity.
++and--increment/decrement by 1 on variables.- Compound assignment (
+=,-=,*=,/=) shortensx = x op value.
Math Object
The Math object is a built-in JavaScript collection of properties (constants) and methods (functions) for common mathematical operations. Intuition: you don't have to write your own square root or PI — the browser gives them to you.
Access via Math (capital M) followed by a dot and the property/method name.
Properties (constants)
| Property | Value |
|---|---|
Math.PI | 3.141592653589793 |
Methods
Rounding
| Method | Behaviour | Example | Result |
|---|---|---|---|
Math.round(x) | Rounds to nearest integer | Math.round(3.43) → 3; Math.round(5.55) → 6 | |
Math.floor(x) | Rounds down to lower integer | Math.floor(5.9999) → 5 | |
Math.ceil(x) | Rounds up to higher integer | Math.ceil(3.43) → 4 |
Other Common Methods
| Method | Purpose | Example | Result |
|---|---|---|---|
Math.abs(x) | Absolute value (removes sign) | Math.abs(-1) | 1 |
Math.sqrt(x) | Square root | Math.sqrt(4) | 2 |
Math.pow(base, exp) | Exponentiation (base**exp) | Math.pow(2,3) | 8 |
Math.random() | Random decimal between 0 (inclusive) and 1 (exclusive) | Math.random() | e.g. 0.732 |
Generating Random Integers (Worked Example)
Goal: a random integer between 1 and 10 (inclusive).
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// Simplified for 1–10:
let rand = Math.floor(Math.random() * 10) + 1;
Why it works:
Math.random()→0.0to0.999...- Multiply by 10 →
0.0to9.999... Math.floor()→ integer0to9- Add
1→ integer1to10
Exam tip: to get a random integer in
[min, max], the general formula isMath.floor(Math.random() * (max - min + 1)) + min.
Practical Example: Circumference of a Circle
let radius = 25;
let circumference = 2 * Math.PI * radius;
console.log(circumference); // 157.07963267948966
Chaining Methods
Methods can be nested, executed inside-out:
let result = Math.floor(Math.sqrt(Math.abs(-999)));
// 1. Math.abs(-999) → 999
// 2. Math.sqrt(999) → 31.606...
// 3. Math.floor(31.606) → 31
console.log(result); // 31
Key takeaways
Math.PIgives π.- Three rounding methods:
round(nearest),floor(down),ceil(up). abs,sqrt,poware standard math helpers.Math.random()returns[0,1); useMath.floor(Math.random() * N) + 1for integers 1..N.- Chaining methods works inside-out; keep code readable with parentheses.
Logical Operators
Logical operators let you combine multiple conditions into a single expression that evaluates to true or false. They are the building blocks of decision‑making in JavaScript — everything from showing a cart count (“1 item” vs. “0 items”) to checking whether a user meets all requirements for a license.
Before understanding logical operators, you must master comparison operators, which compare two values and return a boolean.
Comparison operators
| Operator | Meaning | Example | Result |
|---|---|---|---|
< | Less than | 3 < 4 | true |
> | Greater than | 3 > 4 | false |
<= | Less than or equal to | 10 <= 10 | true |
>= | Greater than or equal to | 9 >= 10 | false |
== | Loose equality (type coercion allowed) | 10 == '10' | true |
=== | Strict equality (type must also match) | 10 === '10' | false |
!= | Loose inequality | 10 != '10' | false |
!== | Strict inequality | 10 !== '10' | true |
Loose equality (==) coerces one value to match the other’s type (e.g., string '10' becomes number 10). This can lead to surprising results:
'' == 0 // true (empty string is coerced to 0)
false == 0 // true
Exam tip: Always prefer strict equality (
===) and strict inequality (!==) in your code. They behave predictably because they do not perform type coercion. Loose equality is rarely needed and often a source of bugs.
Logical operators — truth tables
JavaScript provides three logical operators: AND (&&), OR (||), NOT (!).
| A | B | A && B | A || B | !A |
|---|---|---|---|---|
true | true | true | true | false |
true | false | false | true | false |
false | true | false | true | true |
false | false | false | false | true |
&&(AND) →trueonly when both sides aretrue.||(OR) →truewhen at least one side istrue.!(NOT) → inverts the boolean value.
Short‑circuit evaluation
&& stops evaluating as soon as it finds a falsy operand. || stops as soon as it finds a truthy operand. This is important for performance and for avoiding side effects, but for now focus on the boolean result.
Worked examples
1. Driving license eligibility (AND)
let age = 25;
let hasLL = true; // has learner's license
let eligible = (age >= 18) && (hasLL === true);
console.log(eligible); // true
If either condition fails (e.g., age = 17 or hasLL = false), the result is false.
2. Club entry (OR)
let age = 9;
let hasSpecialPermit = true;
let allowed = (age > 10) || (hasSpecialPermit === true);
console.log(allowed); // true (permit overrides age)
Only when both are false (age <= 10 and no permit) the result is false.
Comparing strings with logical operators
Strings can be compared with <, >, <=, >=. JavaScript compares them character by character based on their Unicode code points.
'B' > 'A' // true (Unicode 66 > 65)
'a' > 'A' // true (97 > 65)
Capital letters have lower Unicode values than lowercase letters, so 'A' < 'a' is true. This can be unintuitive — always test string comparisons in your specific context.
Key takeaways
- Logical operators (
&&,||,!) combine or invert booleans; understand their truth tables. - Comparison operators (
<,>,<=,>=,===,!==) return booleans; always prefer strict equality (===/!==) over loose equality. - Loose equality (
==) coerces types — can produce unexpected results like'' == 0. - Strings are compared by Unicode values:
'A' < 'a','B' > 'A'. - Practise combining conditions with
&&and||to solve real‑world eligibility checks (age + license, special permit, etc.).
Conditional Statements
Conditional statements allow code to execute only when a condition evaluates to true. They control the flow of execution based on variable states or logical checks — the program decides what to run, when.
The if Statement
Syntax:
if (condition) {
// code runs if condition is true
}
ifis a keyword;conditionmust be a boolean (true/false).- Curly braces
{}form a block; no semicolon after the closing brace. - Statements before and after the
ifblock always execute in normal top‑to‑bottom order.
Example – hot day check:
let temperature = 31;
if (temperature > 30) {
console.log("This is a hot day");
}
Output: "This is a hot day" only when temperature > 30.
if…else if…else Chain
For multiple conditions, use else if and optionally a final else as a default.
Syntax:
if (condition1) {
// block A
} else if (condition2) {
// block B
} else if (condition3) {
// block C
} else {
// default – runs if no condition above is true
}
Execution rule: Only the first block whose condition is true executes; all subsequent conditions are skipped. else runs only if no preceding condition is true.
Example – temperature classifier:
let temperature = 21;
if (temperature < 20) {
console.log("Normal day");
} else if (temperature < 25) {
console.log("Kind of hot day");
} else if (temperature < 30) {
console.log("Hot day");
} else {
console.log("Crazy hot day");
}
21→ first conditionfalse, secondtrue→"Kind of hot day".100→ all threeelse ifconditionsfalse→"Crazy hot day".
flowchart TD
A[Start chain] --> B{Condition1?}
B -->|true| C[Execute block1]
B -->|false| D{Condition2?}
D -->|true| E[Execute block2]
D -->|false| F{Condition3?}
F -->|true| G[Execute block3]
F -->|false| H[Execute else block]
C --> I[End of chain]
E --> I
G --> I
H --> I
Example – marks grading:
let marks = 95;
if (marks > 95) {
alert("Excellent marks");
} else if (marks > 80) {
alert("Great marks");
} else {
alert("You can do better");
}
With 95: first condition false, second true → "Great marks". Even if later conditions are also true, only the first matching block executes.
Chain vs. Multiple Separate if Statements
| Structure | Behavior |
|---|---|
if…else if…else | Only one block runs (first true condition). |
Multiple standalone if | Each if is independent; all true conditions execute. |
Example – separate ifs:
if (temperature < 20) console.log("Normal"); // runs if true
if (temperature < 25) console.log("Kind of hot"); // also runs if true
For temperature = 10, both print. With a chain, only the first would print.
Nesting if Statements
An if block can contain another if…else structure for hierarchical decisions.
Example – driving license eligibility:
let age = 25;
let hasLL = "Y";
if (age >= 18) {
if (hasLL === "Y") {
alert("You can take DL");
} else {
alert("First get a LL");
}
} else {
alert("Grow older");
}
- Outer
ifchecks age eligibility first. - Only if
age >= 18does the innerifcheck for a learner’s license.
Alternative using else if (without nesting):
if (age >= 18 && hasLL === "Y") {
alert("You can take DL");
} else if (age >= 18 && hasLL !== "Y") {
alert("First get a LL");
} else {
alert("Grow older");
}
Both achieve the same logic; choose nesting when conditions are naturally grouped.
Logical Operators in Conditions
Combine multiple sub‑conditions with && (AND), || (OR), ! (NOT). They can be written directly in the condition or pre‑stored in a variable.
if (age >= 18 && hasLL === "Y") { ... }
Exam tip: In an
if…else ifchain, order matters. When overlapping ranges exist (e.g.,marks > 95andmarks > 80), the first true condition executes and the rest are ignored. Always test edge cases likemarks = 96where both could be true.
Key Takeaways
ifruns code only when its condition istrue.else ifadds additional conditions;elseis the default catch‑all.- In a chain, only one block executes — the first true one.
- Separate
ifstatements are independent and may both run. - Nesting places an
ifinside anotherifto handle hierarchical decisions. - Use logical operators (
&&,||,!) to combine conditions.
Nested Conditionals
Nested conditionals are if statements placed inside another if (or else/else if) block. They allow decisions that depend on multiple layers of conditions — the inner check only matters if the outer condition is true.
Structure
if (outerCondition) {
if (innerCondition) {
// runs when both true
} else {
// outer true, inner false
}
} else {
// outer false
}
Worked example: Movie ticket pricing
A cinema charges different prices based on two factors: age (≥18 or <18) and membership (Y/N). Without nesting, four separate conditions would be needed. Nesting makes the dependency explicit.
let age = parseInt(prompt("What is your age?"));
let member = prompt("Are you a member? (Y/N)");
if (age > 18) {
if (member === "Y") {
alert("Your ticket price is 200");
} else {
alert("Your ticket price is 300");
}
} else {
// age <= 18
if (member === "Y") {
alert("Your ticket price is 50");
} else {
alert("Your ticket price is 100");
}
}
The logic flows as:
flowchart TD
A[Age > 18?] -->|Yes| B[Member?]
A -->|No| C[Member?]
B -->|Y| D[Price 200]
B -->|N| E[Price 300]
C -->|Y| F[Price 50]
C -->|N| G[Price 100]
Input validation with isNaN()
User input from prompt() is always a string. Use parseInt() to convert to a number, then check with isNaN() to ensure a valid numeric entry. The lecture wrapped the entire nesting inside an if (!isNaN(age)) block.
if (!isNaN(age)) {
// nested conditionals here
} else {
alert("Please enter a valid age");
}
Benefits & drawbacks
| Benefit | Drawback |
|---|---|
| Handles dependent conditions cleanly | Readability suffers as nesting depth increases |
| Avoids repeating outer checks | Debugging becomes harder |
| Matches natural decision hierarchies | Overuse leads to "spaghetti logic" |
Exam tip: When asked to simplify nested code, consider using logical operators (
&&,||) to flatten conditions. For the ticket example, the price could be computed with a single expression:if (age > 18) ? (member === "Y" ? 200 : 300) : (member === "Y" ? 50 : 100)— but nesting is clearer for beginners.
Key takeaways
- Nested
ifs let you test conditions that depend on earlier results. - Always validate numeric input with
parseInt()+isNaN(). - Keep nesting shallow (≤3 levels) to maintain readability.
- Example: ticket price depends on age first, then membership.
Truthiness
Truthiness refers to how JavaScript treats a non‑boolean value as true or false when used in a boolean context (e.g., inside an if condition). Not every value is a literal true or false, but every value behaves as one of them.
Falsy values (the complete list)
Only these six (plus 0n for BigInt) evaluate to false:
| Value | Example |
|---|---|
false | false |
0, -0 | 0, -0 |
"" | empty string |
null | null |
undefined | undefined |
NaN | NaN |
All other values — including any non‑zero number, non‑empty string, array, object, function — are truthy.
Quick code demonstration
if (0) console.log("truthy"); // never runs
if ("hello") console.log("truthy"); // runs
if (null) console.log("truthy"); // never runs
if ([]) console.log("truthy"); // runs (array is truthy)
Practical benefit: simplified conditions
Instead of writing verbose checks like:
if (email !== "" && email !== null && email !== undefined) { ... }
you can write:
if (email) { ... }
The if (email) condition is false when email is "", null, or undefined — exactly the cases you want to reject.
Worked example: Email form validation
let email = prompt("Enter your email:");
if (email) {
alert("Thank you");
} else {
alert("Please enter email. It is mandatory.");
}
If the user presses Cancel (null) or leaves it empty (""), the condition fails and the else block runs.
Exam tip: A common mistake is assuming
if ("false")is false. It is truthy because it's a non‑empty string. Only the booleanfalseis falsy. Also,if ([])is truthy — empty arrays are objects, which are truthy.
Key takeaways
- Truthiness lets any value act as a boolean in conditions.
- Falsy values:
false,0,"",null,undefined,NaN. - Use truthy checks to write cleaner conditions (
if (age)instead ofif (age !== 0 && age !== null ...)). - Beware:
"0","false",[],{}are all truthy. - Understanding truthiness prevents bugs when validating user input.
Array Basics
Arrays solve the problem of managing collections of data. Instead of dozens of individual variables (song1, song2, …), one array holds all items in an ordered list.
Declaration – use square brackets []:
let playlist = []; // empty array
let fruits = ['banana', 'apple', 'peach']; // initialised with three strings
Key fact: typeof an array returns "object" – arrays are a special kind of object in JavaScript.
What can an array hold?
- Any data type — numbers, strings, booleans,
null,NaN, even other arrays. - Mixed types in the same array are allowed (JavaScript is dynamically typed).
let mixed = [1, 11.4, "asd", true, NaN, null, [1, 2, 3]];
// mixed.length is 8; the nested array counts as one element
Nested arrays (arrays inside arrays) are useful for complex data like matrices or grouped records.
The length property
array.length returns the count of elements, not the highest index.
Example: fruits.length → 3 even though indices go 0,1,2.
Exam tip:
lengthis a property, not a method — no parentheses. Use it to loop or to add an element at the end viaarray[array.length] = "new".
Key takeaways – Array creation & properties
- Arrays store multiple values under one variable, making code cleaner.
- Declare with
[]; empty or initialised with comma-separated values. typeof array→"object".- Arrays can mix types, including nested arrays.
lengthgives the number of elements, not the last index.
Indexing and Mutability
Arrays are zero-indexed. Access elements with square brackets:
console.log(fruits[0]); // "banana"
console.log(fruits[2]); // "peach"
console.log(fruits[99]); // undefined — no error
Arrays are mutable – you can change an element directly:
fruits[0] = "mango"; // changes first element
fruits[3] = "mango"; // adds a new element at index 3
fruits[10] = "tomato"; // adds at index 10; indices 4–9 become empty slots (undefined)
Exam tip: Mutability is a key difference from strings. Strings are immutable –
str[0] = "B"does nothing; arrays change in place.
Sparse arrays – assigning to an index far beyond length creates empty slots (filled with undefined but not actual undefined values). The array’s length jumps to that index + 1.
let fruits = ['banana','apple','peach'];
fruits[10] = 'tomato';
// fruits[4..9] are empty; fruits.length becomes 11
Manual addition to the end (cumbersome)
fruits[fruits.length] = 'strawberry'; // works but verbose
Array Methods – Adding and Removing Elements
JavaScript provides built-in methods that handle indexing automatically. Most modify the original array (in place), unlike string methods that return a new string.
| Method | Operation | Location | Return value | Mutates? |
|---|---|---|---|---|
push(elem1, elem2, ...) | Add one or more | End | New array length (implied) | Yes |
pop() | Remove one | End | Removed element | Yes |
unshift(elem1, elem2, ...) | Add one or more | Start | New array length | Yes |
shift() | Remove one | Start | Removed element | Yes |
push and pop – work at the end
let fruits = ['tomato', 'green strawberry'];
fruits.push('kiwi', 'blueberry'); // adds two elements
console.log(fruits); // ['tomato','green strawberry','kiwi','blueberry']
let popped = fruits.pop(); // removes 'blueberry'
console.log(popped); // 'blueberry'
console.log(fruits); // ['tomato','green strawberry','kiwi']
shift and unshift – work at the start
Analogy (queue):
shiftremoves the first person; everyone shifts forward.unshiftadds a “celebrity” to the front; everyone shifts back.
let queue = [1,2,3,4,5,6];
let first = queue.shift(); // removes 1, returns 1
console.log(queue); // [2,3,4,5,6]
queue.unshift('govind', 'friend'); // adds two to front
console.log(queue); // ['govind','friend',2,3,4,5,6]
Exam tip:
shiftandunshifthave confusing names. Remember: shift = remove first → everyone shifts forward; unshift = add first → everyone un-shifts (moves back). Practice with small arrays.
Key difference from strings
let str = "cat";
str[0] = "b"; // fails silently – str remains "cat"
str.toUpperCase(); // returns "CAT" but str unchanged
let arr = [1,2,3];
arr.push(4); // arr becomes [1,2,3,4] – modified in place
- Strings: methods return a new string; original unchanged.
- Arrays (most mutator methods): modify the array directly.
Key takeaways – Indexing & methods
- Access/modify elements with
arr[index]. - Arrays are mutable; assigning beyond
lengthcreates empty slots. push/popoperate at the end;unshift/shiftat the start.- All four methods mutate the original array.
popandshiftreturn the removed element;pushandunshiftreturn the new length (commonly used but not explicitly required).- Always check MDN for full details on array methods.
More Array Methods
Array methods are built-in functions that let you manipulate, query, and transform arrays efficiently. The key difference between them is whether they mutate (modify) the original array or leave it unchanged. Most methods return a new array or a single value instead.
concat – Combine arrays
concat() merges two or more arrays into a new array. It does not change the original arrays.
const veggies = ['tomato', 'cucumber', 'carrot'];
const fruits = ['apple', 'banana'];
const combined = veggies.concat(fruits);
// combined → ['tomato', 'cucumber', 'carrot', 'apple', 'banana']
// veggies is unchanged
Also accepts multiple arrays: veggies.concat(fruits, playlist).
includes – Check for existence
includes() returns a Boolean – true if the element exists in the array, false otherwise. It performs an exact match and does not modify the array.
veggies.includes('cucumber'); // true
veggies.includes('car'); // false (partial match not allowed)
indexOf – Find the first index
indexOf() returns the first index of a given element, or -1 if not found. Works like the string version. Does not mutate.
veggies.indexOf('carrot'); // 2
veggies.indexOf('car'); // -1
join – Make a string from an array
join() concatenates all elements into a string, separated by a given separator (default is comma). The array itself is unchanged.
veggies.join(); // "tomato,cucumber,carrot"
veggies.join(' - '); // "tomato - cucumber - carrot"
veggies.join(' - govind - '); // "tomato - govind - cucumber - govind - carrot"
reverse – Flip the order
reverse() reverses the order of elements in place – the original array is mutated.
console.log(veggies); // ['tomato', 'cucumber', 'carrot']
veggies.reverse();
console.log(veggies); // ['carrot', 'cucumber', 'tomato']
slice – Extract a portion
slice(start, end) returns a shallow copy of a portion of the array from start (inclusive) to end (exclusive). Negative indexes count from the end. Original array is not modified.
const arr = ['tomato', 'cucumber', 'carrot', 'enter sandman'];
arr.slice(1, 4); // ['cucumber', 'carrot', 'enter sandman'] (index 1 to 3)
arr.slice(1); // ['cucumber', 'carrot', 'enter sandman'] (from index 1 to end)
arr.slice(-2); // ['carrot', 'enter sandman'] (last two elements)
splice – Add, remove, or replace
splice(start, deleteCount, item1, item2, ...) mutates the array. It removes deleteCount elements starting at index start, then optionally inserts any provided items at that position.
deleteCount | Items provided | Effect |
|---|---|---|
| > 0 | none | Remove that many elements |
| 0 | yes | Insert items without removing anything |
| > 0 | yes | Replace removed elements with the items |
Examples
let arr = veggies.concat(fruits, playlist); // large test array
// Remove 2 items from index 1
arr.splice(1, 2); // removes 'cucumber' and 'carrot'
// Remove 2 from index 1 and insert 'govind'
arr.splice(1, 2, 'govind');
// Insert without removal: arr.splice(1, 0, 'govind', 'raj', veggies);
Exam tip: The fastest way to tell if a method mutates: read MDN. Common mutating methods:
reverse,splice,push,pop,shift,unshift. Non-mutating:concat,includes,indexOf,join,slice,map,filter.
Quick reference table
| Method | Mutates? | Returns | Purpose |
|---|---|---|---|
concat | No | New array | Combine arrays |
includes | No | Boolean | Check existence |
indexOf | No | Number (index or -1) | Find first index |
join | No | String | Create string from array |
reverse | Yes | The mutated array itself | Reverse order |
slice | No | New array (shallow copy) | Extract a portion |
splice | Yes | Array of removed elements | Add/remove/replace in place |
Key takeaways
concat,includes,indexOf,join,slicedo not modify the original array.reverseandsplicemutate the original array.spliceis the most flexible: you can delete, insert, or replace in one call.- The
slicemethod behaves like the stringslice– same syntax, zero-based, negative indexes work. - Always verify method behaviour on MDN; memorisation is not required – practice builds familiarity.
Arrays as Reference Types
JavaScript arrays are reference types, not primitive values. A variable holding an array stores a memory address (a reference) to where the array’s data lives—not the data itself. This has two critical consequences: value-based comparison fails, and assignment creates aliases.
Arrays Are Not Equitable by Value
Two arrays with identical elements are different objects in memory. Using == or === compares their references, not their contents.
const fruits1 = ['apple', 'banana'];
const fruits2 = ['apple', 'banana'];
console.log(fruits1 == fruits2); // false
console.log(fruits1 === fruits2); // false
To compare actual array contents, you must iterate element-by-element or use a utility (e.g., every() with index matching). Direct equality always returns false for distinct arrays.
Assignment Creates a Shared Reference
When you assign an array to another variable, the new variable points to the same memory location. Mutating the array through either variable changes the shared data.
const a1 = [1, 2];
const a2 = a1; // a2 references same array as a1
a1[1] = 5; // mutate the shared array
console.log(a1, a2); // both are [1, 5]
This contrasts with primitive values (numbers, strings), where assignment copies the value:
| Data type | Operation | Outcome |
|---|---|---|
| Primitive | let x=1; let y=x; x=2; | y remains 1 |
| Array (reference) | let a=[1,2]; let b=a; a[0]=5; | b also sees [5,2] |
How to break the reference – create a true copy:
- Assign a new array literal:
a2 = [1, 2]; - Use
.slice()(returns a shallow copy):a2 = a1.slice();
After a true copy, mutations to the original do not affect the copy.
let a1 = [1, 2];
let a2 = a1.slice();
a1[0] = 10;
console.log(a1, a2); // [10, 2] and [1, 2]
Exam tip: Any direct assignment
arr2 = arr1makes both variables reference the same array. Mutations through either one affect the other. To guard against unintended side effects, always copy with.slice()or the spread operator.
Key takeaways
- Arrays are stored as references;
==/===compare memory locations, not contents. - Two different arrays with identical elements are never
===. - Assigning an array to a new variable creates an alias, not a copy.
- Mutating the array through any alias changes the shared data.
- Use
.slice()(or spread[...arr]) to create a shallow copy and break the alias.
Multidimensional Arrays (Nested Arrays)
A multidimensional array is an array whose elements are themselves arrays. Useful for matrices, grids, and tabular data.
Example – 3×3 matrix (2D array):
const matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
Accessing elements:
matrix[0]→ first row:[1, 2, 3]matrix[0][1]→ first row, second column:2- Use successive bracket notation:
[row][col]for 2D.
Higher dimensions – adding another level of nesting (array inside an array inside an array) creates a 3D structure.
Key takeaways
- Nested arrays create multidimensional structures (2D, 3D, etc.).
- Access elements with multiple bracket indices:
arr[i][j][k]. - Common uses: matrix operations, game boards, spreadsheets.
Overall Key Takeaways
- Arrays are reference types – never compare with
==/===to check content equality. - Assigning an array copies the reference, not the data; mutations propagate.
- Create independent copies with
.slice()or spread syntax. - Multidimensional arrays (arrays of arrays) enable row–column data structures; index with multiple brackets.
JavaScript Objects
Objects in JavaScript are collections of key-value pairs. They store multiple related values, each labeled with a meaningful key (or property name). Think of an object as a labeled filing cabinet: you access a value by its label, not by a numeric index (as in arrays). Objects are fundamental for representing complex, structured data.
Syntax
An object literal is defined with curly braces {}. Inside, keys and values are separated by a colon :, and pairs are comma-separated:
let person = {
name: "Govind", // key: "name", value: "Govind"
age: 120, // key: "age", value: 120
isStudent: false, // key: "isStudent", value: false
classes: ["web development", "Excel"], // value can be an array
address: "Bannerghatta, Bangalore"
};
Keys are implicitly converted to strings (even if you omit quotes). The convention is to use camelCase keys that follow variable naming rules.
Properties
Each key-value pair is called a property. You have already used properties on built-ins (e.g., "hello".length). Objects let you define your own.
Values can be any data type:
- string, number, boolean
- array
- nested object (another object)
- function (covered in a later module)
Accessing Properties
Two ways to read a property’s value:
| Notation | Syntax | Example | Notes |
|---|---|---|---|
| Dot notation | object.key | person.name → "Govind" | Key must be a valid identifier (no spaces, no numbers at start) |
| Bracket notation | object["key"] | person["age"] → 120 | Key is always a string (even if you write 123, it becomes "123") |
Use dot notation for known, simple keys; bracket notation when the key is dynamic or contains characters that break dot syntax.
Dynamic keys with bracket notation
Bracket notation accepts a variable whose value is a string key:
let searchKey = "name";
console.log(person[searchKey]); // "Govind"
searchKey = "123";
console.log(person[123]); // Access key "123", works because key is auto-converted
Exam tip: Bracket notation is essential for computed or runtime‑determined keys. Dot notation is safer for hard‑coded keys, but bracket notation is more flexible — know both.
Modifying and Adding Properties
You can change an existing property or add a new one by simple assignment:
person.name = "Simran"; // dot notation – update
person.isStudent = true; // update
person.ethnicity = "Indian"; // add new property (dot)
person["fatherName"] = "Shah Rukh Khan"; // add new property (bracket)
Properties that don’t exist are created on the fly.
Nested Objects
A property’s value can itself be an object, enabling deep data structures:
let person = {
name: "Govind",
address: {
city: "Bangalore",
street: "Bannerghatta",
pinCode: 123456
}
};
console.log(person.address.city); // "Bangalore"
console.log(person["address"]["pinCode"]); // 123456
Access nested properties by chaining dot or bracket notation.
Use Cases
- User profiles (username, email, password)
- Product details (name, price, available)
- Application settings (theme, volume)
- Every HTML element as a DOM object (next module)
- The entire
documentobject is a JavaScript object
Objects make code more readable and data more organised than separate variables.
Key takeaways
- Objects are key-value pairs inside
{}; keys are always strings. - Dot notation is concise for known, valid identifiers; bracket notation handles dynamic or problematic keys.
- Properties can be added or updated by assignment on the fly.
- Values can be any type, including nested objects and arrays.
- Bracket notation requires the key as a string (or variable holding a string).
- Use objects to bundle related data instead of many independent variables.
Loops in JavaScript
Loops let you repeat actions without duplicating code. Instead of writing hundreds of lines to display each comment or product, one loop iterates over the collection and handles each item dynamically.
Why loops matter
- Process lists of data (comments, products, search results).
- Display many items from arrays or objects.
- Perform repetitive calculations.
- Keep code clean, concise, and adaptable.
The for loop – the most common loop
The for loop runs a block of code a specific number of times. Its syntax has three parts inside parentheses, separated by semicolons:
for (initialization; condition; increment) {
// body – code to repeat
}
| Part | Purpose | Example |
|---|---|---|
| Initialization | Declare and set a loop variable (often i). Runs once before the loop starts. | let i = 0 |
| Condition | Checked before each iteration. If true, the body runs; if false, the loop stops. | i <= 10 |
| Increment | Updates the loop variable after each iteration. | i++ (adds 1) |
Order of execution
flowchart TD
A[Initialization: i = 0] --> B{Condition: i <= 10?}
B -->|True| C[Execute body]
C --> D[Increment: i++]
D --> B
B -->|False| E[Exit loop]
Worked example: Print numbers 0 to 10
for (let i = 0; i <= 10; i++) {
console.log(i);
}
How it runs (step‑by‑step):
i = 0→ check0 <= 10→ true → print0→ibecomes1i = 1→ check1 <= 10→ true → print1→ibecomes2- … continues until
i = 10→ print10→ibecomes11 i = 11→ check11 <= 10→ false → exit
Output: 0 1 2 3 4 5 6 7 8 9 10 (11 numbers, because i <= 10 includes 10).
Iterating over an array with a for loop
Given an array playlist = ["Enter Sandman", "Nothing Else Matters", "Fade to Black", "Unforgiven"], we can print each element:
for (let i = 0; i < playlist.length; i++) {
console.log(playlist[i]);
}
istarts at0(first index).- Condition uses
playlist.length(here 4) → loops whilei < 4→ indices 0,1,2,3. - Prints each song.
Number the songs (1‑based)
for (let i = 0; i < playlist.length; i++) {
console.log(`Song ${i + 1} is ${playlist[i]}`);
}
i + 1is just for display; the actual loop variableiremains unchanged.
Variations of the for loop
1. Different step sizes
| Increment expression | Effect | Example output (0 to 10, step 2) |
|---|---|---|
i += 2 | Skips every other number | 0 2 4 6 8 10 |
i *= 9 | Multiplies each step | 1 9 81 (if start at 1) |
2. External counter (initialization outside)
let i = 1;
for (; i <= 100; i += 9) {
console.log(i);
}
3. Increment inside the body
for (let i = 1; i <= 100; ) {
console.log(i);
i += 9;
}
All variations work as long as the loop variable is updated and the condition eventually becomes false.
Infinite loops – the critical trap
An infinite loop occurs when the condition never becomes false. The program freezes or crashes.
Dangerous examples
// Multiply by 9 starting from 0
for (let i = 0; i <= 100; i *= 9) {
console.log(i); // i stays 0 forever
}
// Condition always true
for (let i = 0; i >= 0; i++) {
console.log(i); // i keeps increasing, condition never false
}
Exam tip: Always ensure that something inside the loop changes the loop variable so that the condition will eventually be
false. The most common mistake is an increment that doesn’t actually change the value (e.g.,i *= 9wheni = 0) or a condition that can never be satisfied (e.g.,i >= 0withi++).
Key takeaways
forloops repeat code a fixed number of times using initialization, condition, and increment.- The condition is checked before each iteration; the increment runs after the body.
- Use
array.lengthas the upper bound when iterating over arrays. - Increment can be any expression (
+=2,*=9, etc.) but must eventually make the condition false. - An infinite loop crashes the application – always verify that the loop will terminate.
- The
forloop is the foundation; other loops (while,for…in,for…of) are covered in later videos.
Nested Loops
A nested loop places one loop inside another. The inner loop runs through all its iterations for every single iteration of the outer loop. This structure is essential for processing multidimensional data – for example, a 2D grid or an array of arrays.
How it works (basic example)
for (let i = 0; i < 2; i++) {
console.log("outer loop", i);
for (let j = 0; j < 3; j++) {
console.log("inner loop", j);
}
}
Output:
outer loop 0
inner loop 0
inner loop 1
inner loop 2
outer loop 1
inner loop 0
inner loop 1
inner loop 2
The outer loop runs twice, and for each of those two runs the inner loop runs three times – total 6 inner iterations.
Traversing a nested array (traditional approach)
Given a nested (2D) array, you need one loop for the outer array and another loop for each inner array.
const nestedArray = [[1, 2], [3, 4, 5], [6, 7]];
for (let i = 0; i < nestedArray.length; i++) {
console.log("Outer array:", nestedArray[i]);
for (let j = 0; j < nestedArray[i].length; j++) {
console.log("Inner element:", nestedArray[i][j]);
}
}
The outer loop index i selects each sub‑array; the inner loop index j walks through the elements of that sub‑array.
for...of – modern iteration for arrays and strings
for...of directly gives you each value of an iterable (arrays, strings, Maps, Sets, etc.). No indexing needed – it’s more readable and less error‑prone.
Array example
for (const outerArray of nestedArray) { // outerArray is each sub‑array
console.log("Outer array:", outerArray);
for (const element of outerArray) { // element is each value inside
console.log("Inner element:", element);
}
}
Same output as the nested‑loop version above, but simpler.
String example (strings are iterable)
for (const char of "Hello") {
console.log(char); // prints H, e, l, l, o
}
Exam tip:
for...ofworks on any iterable, but not on plain objects. Tryingfor (const x of person)will throw a TypeError.
for...in – object keys (use with caution)
for...in iterates over the keys (property names) of an object. You can then access values via bracket notation.
const person = { name: "Alice", age: 25, student: true };
for (const key in person) {
console.log(key, person[key]); // name Alice, age 25, student true
}
Drawbacks:
- Confusing name – many languages use
infor arrays, so it’s easy to mix up withfor...of. - It also iterates over inherited enumerable properties (unless filtered).
- Not recommended for arrays; use
for...ofinstead.
Better alternative: Object.keys, Object.values, Object.entries
Instead of for...in, use these static methods that return arrays – then iterate with for...of.
| Method | Returns | Example usage |
|---|---|---|
Object.keys(obj) | Array of keys | for (const k of Object.keys(person)) |
Object.values(obj) | Array of values | for (const v of Object.values(person)) |
Object.entries(obj) | Array of [key, value] pairs | for (const [k, v] of Object.entries(person)) |
Example (preferred approach):
const person = { name: "Alice", age: 25 };
// Keys only
for (const key of Object.keys(person)) {
console.log(key); // name, age
}
// Values only
for (const val of Object.values(person)) {
console.log(val); // Alice, 25
}
// Key-value pairs
for (const [key, val] of Object.entries(person)) {
console.log(key, val); // name Alice, age 25
}
This pattern is explicit, works with any array‑iteration method, and avoids the confusion of for...in.
Summary of loop choices
flowchart TD
A[What to iterate?] --> B{Array or iterable?}
B -->|Yes| C[Use for...of]
B -->|No – it's an object| D[Use Object.keys/values/entries + for...of]
C --> E[Or use traditional for loop with index]
D --> F[Avoid for...in, it's confusing]
Key takeaways
- Nested loops: outer loop controls rows, inner loop controls columns (or sub‑elements).
for...ofis the cleanest way to iterate arrays, strings, and other iterables.for...initerates object keys but is error‑prone; preferObject.keys()/Object.values()/Object.entries().- Use traditional
for (let i = 0; i < arr.length; i++)when you need the index or break early. - For objects, always convert to an array first using
Object.*methods, then usefor...of.
Exam tip: Interviewers love asking why
for...inon an array is bad – it includes inherited properties and key order isn’t guaranteed. Stick withfor...offor array values.
Functions in JavaScript
A function is a reusable block of code that performs a specific task. Instead of writing the same logic over and over, you define it once and call it whenever needed. This follows the DRY (Don't Repeat Yourself) principle, making code more readable, modular, and testable.
Defining vs Calling
- Defining a function stores it in memory without executing the code.
- Calling (or invoking) a function runs the defined code.
// Defining
function greet() {
console.log("Hello world");
}
// Calling
greet(); // logs "Hello world"
If you only reference the function name without parentheses (e.g., greet), JavaScript just tells you it's a function — it doesn't run it.
Parameters and Arguments
Functions can accept inputs to work with. The placeholder in the definition is a parameter; the actual value passed during the call is an argument.
function greet(name, age) {
console.log(`Hello world ${name}. Wow, you are ${age} years old.`);
}
greet("Govind", 24); // "Hello world Govind. Wow, you are 24 years old."
| Term | Definition | Example |
|---|---|---|
| Parameter | Variable defined in the function declaration | name, age |
| Argument | Actual value supplied when calling the function | "Govind", 24 |
If you call a function without providing an argument for a defined parameter, that parameter becomes undefined — the function still runs but with undefined in place.
Hoisting
JavaScript hoists function declarations to the top of their scope, so you can call a function before its definition appears in the code. However, relying on this is discouraged — always define before calling for clarity and easier debugging.
Worked Example: Generating a Random Number Repeatedly
Instead of writing console.log(Math.random()) multiple times, wrap it in a function:
function printRandom() {
console.log(Math.random());
}
printRandom(); // logs a random number
printRandom(); // logs another random number
printRandom(); // logs another random number
Now you have a single block you can call from anywhere.
Exam tip: Hoisting only applies to function declarations (the
functionkeyword form), not to function expressions (e.g.,const f = function() {}). Know the difference — it’s a common trick question.
Key takeaways
- A function is a reusable block of code defined with the
functionkeyword. - Defining stores the code; calling (with
()) executes it. - Parameters are placeholders in the definition; arguments are the actual values passed.
- Missing arguments become
undefined— the function still runs. - Hoisting allows calling before definition, but good practice defines first.
Advanced Concepts in Functions
Functions in JavaScript can be treated as first-class citizens: they can be assigned to variables, passed as arguments, and returned from other functions. This flexibility enables powerful patterns like callbacks, factory functions, and recursion.
Assigning Functions to Variables
A function can be referenced by a variable without being executed. The variable can then be used to call the function.
function add(a, b) { return a + b; }
let addition = add; // No parentheses – we assign the function itself
console.log(addition(1, 2)); // 3
Anonymous functions — functions without a name — can be created and directly assigned to a variable. A function statement without a name is invalid, but when used in an assignment it becomes valid.
let addition = function(a, b) { return a + b; };
addition(1, 2); // 3
Passing Functions as Arguments (Callbacks)
Because functions are first-class, they can be passed into other functions as arguments. This pattern is called a callback and enables reusable, dynamic logic.
Worked Example: executeXTimes
function randomNumber() {
console.log(Math.floor(Math.random() * 100));
}
function executeXTimes(fn, count) {
let i = 0;
while (i < count) {
fn(); // fn is the function passed in
i++;
}
}
executeXTimes(randomNumber, 5); // logs 5 random numbers
randomNumberis passed without parentheses — we pass the reference, not the result.- Inside
executeXTimes,fnis called usingfn().
Returning Functions (Factory Functions)
A function can return another function. This allows creating specialized functions on the fly — a factory function.
function multiplierFactory(multiplier) {
return function(value) {
return value * multiplier;
};
}
const double = multiplierFactory(2);
const triple = multiplierFactory(3);
console.log(double(10)); // 20
console.log(triple(10)); // 30
- The outer function captures the
multiplierargument via closure. - The returned inner function uses that captured value whenever called.
Recursion
Recursion is when a function calls itself. It is useful for traversing nested structures where the depth is unknown (e.g., nested arrays, trees).
Worked Example: Printing a Nested Array
function printNestedArray(arr) {
for (let item of arr) {
if (Array.isArray(item)) {
printNestedArray(item); // recursive call
} else {
console.log(item);
}
}
}
let nestedArray = [
[2.1, 2.2, 2.3],
3, 4,
[[5.11, 5.12], [5.21, 5.22]],
6, 7, 8, 9
];
printNestedArray(nestedArray);
// Output: 2.1, 2.2, 2.3, 3, 4, 5.11, 5.12, 5.21, 5.22, 6, 7, 8, 9
- Base condition: when an item is not an array, print it and stop recursing that branch.
- Without a base condition, infinite recursion would crash the program.
Exam tip: Always ensure a recursive function has a base case that terminates the calls.
Object Methods
Methods are functions stored as properties of an object. They can access and modify the object’s data using the this keyword.
Defining a Method – Two Syntaxes
-
Property + anonymous function:
let person = { name: "Govind", age: 25, speak: function() { return `My name is ${this.name}`; } }; -
Shorthand syntax (more modern):
let person = { name: "Govind", age: 25, greet() { return `Hi, my name is ${this.name}, age ${this.age}`; } };
- Call a method with parentheses:
person.speak()→"My name is Govind" thisinside the method refers to the object the method belongs to. Changingperson.nameupdates the output.- All methods are functions, but not all functions are methods — methods are tied to a specific object.
Key Takeaways
- Functions can be assigned to variables, making them first-class citizens.
- Anonymous functions work when assigned, but not as standalone statements.
- Callbacks (passing functions as arguments) enable reusable, dynamic code.
- Factory functions return specialized functions via closures.
- Recursion solves problems with nested structures; always include a base condition.
- Methods are functions inside objects; use
thisto reference the object’s properties.
Business, Design and Product perspectives for web development
Module 2 Introduction: Business, Product & Design Perspectives
Module 1 established the technical foundation: internet mechanics, HTML/CSS/JS rendering, browser behavior, and internet history. Module 2 shifts from how websites are built to why they are built — the planning decisions made before a single line of code.
Core shift in focus
| Module 1 (Technical) | Module 2 (Strategic) |
|---|---|
| How the internet works | Business objectives – what outcome must the site drive? |
| How files (HTML, CSS, JS) create pages | Product management – think like a PM: which features matter most for that outcome? |
| Browser rendering | Design patterns, visual hierarchy, color palettes, fonts – how to visually achieve the desired result |
What Module 2 covers
- Defining clear business objectives → every design and feature decision must be traceable to a specific outcome (e.g., increase sign-ups, reduce support tickets, boost average order value).
- Analyzing live websites → reverse-engineer the decisions behind existing features.
- Prioritizing features → given multiple possible features, choose the ones that best serve the objectives.
- Design perspective → apply design patterns (reusable solutions to common UX problems), visual hierarchy (arrange elements to guide the eye), color palettes, and typography to achieve the desired user response.
Why it matters: A technically perfect site can fail if it doesn't serve a clear business goal. This module builds the planning discipline needed to align code with purpose.
Learning outcome
By the end of this module, you can plan websites that are both functional (they work) and strategically aligned (they achieve specific business goals).
Key takeaways
- Module 2 moves beyond code to strategic planning: business objectives → feature prioritization → design execution.
- Three pillars: business, product (features, prioritization), and design (patterns, hierarchy, color, typography).
- Every design choice should be intentional and traceable to a desired outcome.
- Real website analysis and feature trade-offs are core practice skills.
Business Objectives
Business objectives define the core purpose of a website and guide every subsequent decision in content, design, and user experience. Without them, a site becomes like a store without signs or product arrangement — visitors are confused, frustrated, and likely to leave. A clear objective answers: Is this site meant to inform, sell, or generate leads?
By setting the objective early, designers and developers create a coherent, purposeful site that serves both the business and the user.
Why objectives matter
A website built without a clear purpose lacks direction. Visitors don’t know what to do or expect. Clear objectives:
- Shape content type and style (articles vs. product descriptions).
- Determine design choices (readability vs. bold CTAs).
- Influence interaction design (search/navigation vs. cart/checkout).
- Keep the site focused — every element works toward the goal.
Impact on content, design, and interaction
| Aspect | Informational site (e.g., blog) | E‑commerce site (e.g., online store) |
|---|---|---|
| Content | In-depth articles, resources, easy navigation | Product descriptions, reviews, images |
| Design | Minimal colors, clean typography, readable sections | Vibrant, visually engaging, eye‑catching offers |
| Call‑to‑actions (CTAs) | Subtle, placed after content (e.g., newsletter sign‑up) | Prominent, multiple “Add to bag” buttons |
| User interaction | Search, related articles links, subscription form | Shopping cart, streamlined checkout, high‑intent paths |
Different objectives lead to fundamentally different user experiences.
Worked examples: TechCrunch vs. Nykaa
TechCrunch (informational)
Objective: inform and engage.
- Simple layout, focus on typography, one brand color (green).
- No distracting colors in reading sections.
- Easy navigation with categories at top.
- CTAs (e.g., subscribe) are less prominent, hidden after content.
Nykaa (e‑commerce)
Objective: drive sales.
- Vibrant homepage with offers to attract low intent users (browsing).
- Sign‑in option highlighted; pop‑ups for sign‑up.
- Detailed categories structured for high intent users (ready to buy).
- Product pages showcase details, reviews, related products, multiple “Add to bag” CTAs.
- Post‑purchase flow streamlined for seamless checkout.
Exam tip: Always ask “What is the main purpose of this site?” before deciding on any feature, layout, or element. Every component must serve the objective.
How objectives connect to decisions
flowchart LR
O[Business Objective] --> C[Content style]
O --> D[Design & visual]
O --> I[Interaction / UX]
C --> E[Article vs. product]
D --> F[Subtle vs. bold CTAs]
I --> G[Search vs. cart]
Key takeaways
- Business objectives give a website direction: inform, sell, or generate leads.
- Without them, the site confuses users and fails to achieve business goals.
- Objectives directly shape content, design (colors, CTAs), and interaction (navigation, checkout).
- Low intent users browse; high intent users know what they want and need a fast path to purchase.
- Compare TechCrunch (informational) and Nykaa (e‑commerce) to see how different objectives produce completely different sites.
Product Management Principles
Applying product management principles to web development shifts the focus from aesthetics to purposeful, impact-driven design. The core idea: every website must answer two fundamental questions – Why is it needed? and What do we want to achieve with it? Success comes from meeting business objectives while delivering a stellar user experience.
First Principles: Purpose-Driven Design
Before any design or code, define the website’s core purpose. A clear purpose ensures every element serves that goal. Common primary goals:
- Drive sales (e-commerce)
- Generate leads (conversion funnels)
- Increase brand awareness (content / marketing)
Exam tip: Always start an exam answer with the two fundamental questions. They are the foundation for all subsequent product management decisions.
Structuring Around Business Objectives
Structure the website around the primary goal so that the user journey naturally leads to the desired outcome. Mapping out user journeys reduces friction and keeps attention on the objective.
Example – Flipkart
Business objective: drive e-commerce sales.
Structure the homepage to highlight sales, offers, product categories, ratings, and reviews – everything points toward purchase.
flowchart LR
A[Land on homepage] --> B[Browse categories / search]
B --> C[Subcategory pages]
C --> D[Product page]
D --> E[Add to cart]
E --> F[Checkout: payment + address]
F --> G[Purchase completed]
Apply this by:
- Defining primary goals – sell, inform, or engage.
- Designing user journeys – map every step from entry to conversion.
- Highlighting key features – banners, CTAs, pop-ups to direct attention.
- Reducing friction – remove unnecessary steps; make each next action obvious.
Prioritizing Features
Not all features contribute equally. Prioritize those that directly support business objectives.
Prioritization criteria (from the lecture):
| Criterion | What it means | Example |
|---|---|---|
| Analyze user behavior | Use tools like Google Analytics to see what users interact with most | High‑click items get priority |
| Focus on ROI | Features that directly impact revenue (lead forms, e‑commerce integrations) take precedence | “Buy now” over “Share on WhatsApp” |
| Test and iterate | Put something out → test (A/B testing) → keep or change | Iterate based on real data |
Apply to Flipkart: “Add to cart” and “Buy now” are mandatory; “Share on social media” is lower priority. Personalized product recommendations boost cross‑selling, lightning deals create urgency – both aligned with driving sales.
Balancing Business and User Needs
A great website balances business goals with user expectations. Ignoring either leads to poor engagement or unmet objectives.
Example – Zomato
- Business wants: encourage users to order food.
- User wants: quickly find restaurants, view menus, get food fast.
- Balanced approach: clear search, filters, delivery-time indicators, ratings – plus CTAs, nudges, visual deals to complete purchase.
Tips for balance:
- Prioritize clarity and ease of use.
- Gather user feedback to identify pain points.
- Align every decision with both business and user perspectives.
- Think from the user’s perspective.
User-Centered Design
To create an intuitive website, understand the user deeply.
Process:
- Put yourself in the user’s shoes – conduct surveys, gather insights, talk to users.
- Build user personas – who they are, needs, family structure, time available.
- Build the website for that persona.
- Continuously test with real users.
This ensures the design matches actual mental models and workflows.
Key Takeaways
- Start with two fundamental questions: why needed and what to achieve.
- Structure the website and user journey around clear business objectives.
- Prioritize features by user behavior, ROI, and iterative testing.
- Balance business goals (CTAs, nudges) with user needs (clarity, speed).
- Use user personas and continuous testing to design intuitive experiences.
- Every design decision should align with both business and user expectations.
What Is Color Theory?
Color theory is the science and art of using colors – how they mix, match, contrast, and, most importantly, how they affect human emotions and perceptions. It is not merely aesthetic: colors are psychological. A well-chosen palette can make a visitor want to stay on a site; a chaotic one can drive them away. The biological and cultural responses to color are equally powerful.
Color psychology deepens color theory by revealing how different hues influence emotions, behaviors, and decision-making. Warm colors (red, orange) can raise heart rate; cool colors (blue, green) can lower it and build trust.
How Color Shapes User Experience
- Biological response – universal physiological reactions (e.g., red → urgency, excitement, danger)
- Cultural response – learned associations vary across societies (e.g., red = celebration in India, danger in Western traffic signals)
- Intensity & contrast – high-contrast designs grab attention; subtle tones promote relaxation. Streaming platforms like Netflix use high‑contrast red/black; wellness sites prefer soft green/white.
Exam tip: The Olympic study is a favorite exam hook – athletes wearing red won ~60% of matches against equally skilled opponents wearing blue. This illustrates color’s subconscious influence even in high‑stakes performance.
Breakdown of Individual Colors – Psychology & Brand Examples
| Color | Core Associations | Typical Web/Brand Use | Examples from Transcript |
|---|---|---|---|
| Red | Energy, war, danger, strength, urgency, excitement | Stop signs, sales promotions, call‑to‑action buttons (“Buy Now”, “Limited Offer”) | Netflix (attention‑grabbing), Puma sale banner |
| Blue | Calmness, trust, reliability, peace, loyalty, competence, spiritual | Banking, healthcare, payment providers, productivity/health apps | Razorpay, JustPay, PayPal, insurance sites |
| Yellow | Creativity, happiness, energy, attention‑grabbing | Brands wanting to stand out; educational sites (boosts engagement) | Mokobara’s yellow Mokomini bag (went viral, often out of stock) |
| Green | Nature, growth, freshness, harmony, balance, health, eco‑friendliness | Grocery, pharmacy, wellness, food delivery (freshness signal) | Flipkart Grocery (green variant), BigBasket, medicinal/pharmacy sites |
| Brown | Dependability, ruggedness, trustworthiness, simplicity, nature | Outdoor, natural, “earthy” branding | Timberland (brown in shoes / products to signal ruggedness) |
| White | Cleanliness, simplicity, innocence, honesty, clarity | Minimalist design, high‑end tech | Apple (white + silver + black → sophistication) |
| Black | Formality, drama, sophistication, security, luxury, timelessness | Luxury branding, professional services | Nykaa (uses black/pink combination); luxury perfumes |
| Purple / Pink | Compassion, sophistication, femininity (cultural), luxury | Cosmetics, feminine‑targeted brands | Nykaa (pink/purple to signal femininity & luxury) |
Each color’s psychological impact is leveraged deliberately in branding and UI to evoke the desired emotional response.
Applications in Web Development
- Call to action (CTA) – red for urgency (“Limited Offer”); green for success (checkout confirmation)
- Trust signals – blue & green together evoke trust and healing
- White space – enhances clarity, reduces cognitive load
- Educational sites – yellow to boost engagement and creativity
- Pharmacy / health – green signals freshness and health
The choice of color goes far beyond aesthetics – it directly influences conversion, trust, and user behavior.
Tools for Choosing Effective Color Palettes
Professionals use curated palettes to avoid reinventing the wheel. Recommended resources from the lecture:
| Tool | Purpose | How to Use |
|---|---|---|
| Color Hunt | Pre‑made, trendy color schemes | Browse themes (retro, warm, cold, summer, winter, happy, skin, kids, Christmas, wedding, pastel) → copy hex codes → use in CSS |
| Adobe Color | Custom palette generation | Pick a base color → choose harmony rule (e.g., triadic, complementary) → generate harmonised colors |
| Coolors (coolors.co) | Interactive palette generator & visualiser | Lock preferred colors, press space for random alternatives; see how palette looks on sample UI (mobile, web, logo, charts, icons) |
Exam tip: Memorise at least one of these tools by name – they appear in design‑related exam questions as “industry‑standard resources”.
Cultural Context & Accessibility
- Red – celebration vs. danger (e.g., Indian weddings vs. Western stop signs)
- Pink – culturally associated with femininity (Nykaa’s target demographic)
- Contrast – high contrast for headlines/CTAs; softer contrast for body text. Must test for readability and avoid jarring combinations.
- Accessibility – ensure sufficient colour contrast for visually impaired users (e.g., using tools like WebAIM contrast checker – implied, not explicitly mentioned in transcript, but a logical extension of “test for accessibility”).
Key Takeaways
- Color theory = science + art of colour mixing, matching, and emotional impact.
- Color psychology adds a biological and cultural layer: each colour triggers specific feelings (e.g., blue → trust, red → urgency).
- Use high contrast to grab attention; low contrast to promote calm (Netflix vs. wellness sites).
- Tools like Color Hunt, Adobe Color, and Coolors help generate professional palettes quickly.
- Always consider cultural context and accessibility – what works in one market may fail in another.
- Brand choices are deliberate: Apple (white), Timberland (brown), Nykaa (pink), Razorpay (blue) all signal their brand values through colour.
Typography
Typography is the craft of arranging text to make written language legible, readable, and visually appealing. It is not merely choosing a font—it shapes the user’s experience, conveys mood, and can make or break a message. Poor typography creates cognitive roadblocks; good typography feels invisible and effortless.
Legibility vs. Readability
These are the two pillars of typography.
- Legibility – How easily individual characters can be distinguished (e.g.,
0vs.O). Fonts like Roboto have clear, well-defined glyphs. - Readability – How easily a reader can engage with a block of text. Depends on line spacing, font size, layout, and overall visual comfort.
Exam tip: Legibility is about letters; readability is about the reading experience. Both must be good.
Font Families
Fonts fall into two main families, plus decorative categories.
| Family | Characteristics | Common Examples | Typical Use Cases |
|---|---|---|---|
| Serif | “Feet” (serifs) at ends of strokes; classic, formal, authoritative | Times New Roman, Georgia | Print media, legal documents, luxury brands, academic journals |
| Sans Serif | “Without” serifs; clean, modern, minimalist | Helvetica, Arial, Open Sans, Roboto, Lato | Digital screens, apps, websites, tech startups, lifestyle blogs |
| Script | Cursive, decorative, elegant | (e.g., Pacifico) | Invitations, headings (avoid long paragraphs) |
| Display | Bold, unique, attention-grabbing | (e.g., Playfair Display) | Headlines, sparingly for impact |
- Serifs originated from ancient stone carving—sculptors naturally created these strokes because sharp 90° angles were hard to carve.
- Sans literally means “without.”
Psychology of Fonts
Each font family evokes specific emotions:
- Serif – Stable, traditional, authoritative.
- Sans Serif – Clean, friendly, contemporary.
- Script – Elegant, personal.
- Display – Bold, impactful.
Choose fonts that align with your brand’s message (e.g., an eco-friendly brand might pair a serif heading with a sans serif body).
Word Superiority Effect
The brain recognizes entire words faster than individual letters. Lowercase letters have more distinct shapes, making them easier to read. Avoid all caps for body text—it slows reading and feels like shouting.
Visual Hierarchy
Typography guides the reader’s eye through content using size, weight, and spacing. For a blog post:
- Title: Large, bold, display font → 46 px
- Subheadings: Medium, clean (e.g., Roboto Bold) → 24 px
- Body text: Small, readable (e.g., Open Sans) → 16 px or 12 px
The ratio between levels creates a clear structure.
Google Fonts
Google Fonts is a free library with preview tools to adjust size, spacing, and see live examples. Top picks: Open Sans, Roboto, Lora (sans serif). The Knowledge section (especially Readability and Accessibility) offers guidance on how fonts influence reading.
Spacing and Contrast
- Whitespace (between lines, words, letters) is critical—too much or too little hurts readability.
- Contrast between text and background must be sufficient. Use colour-checking tools to meet accessibility standards (e.g., Web Content Accessibility Guidelines).
Reading Styles
People read differently depending on context and device. Typography must adapt.
| Reading Style | Context | Mobile | Desktop |
|---|---|---|---|
| Glanceable | Headlines, notifications, key stats | Large, bold text | Prominent banners, CTAs |
| Interlude | Navigation menus, summaries, snippets | Compact, clear labels, collapsible menus | Well-structured sidebars, quick summaries |
| Long-form | Articles, novels | Responsive layout, text adjusts to small screens | Larger fonts, wider spacing, comfortable reading |
Pick the ideal font and size based on the dominant reading style of your content.
Key Takeaways
- Typography is a language that sets tone and guides the reader.
- Legibility (character clarity) and readability (text comfort) are both essential.
- Serif = formal/authoritative; Sans Serif = modern/friendly; Script = decorative; Display = impactful.
- Use visual hierarchy (size, weight, spacing) to structure content.
- Adapt typography to reading style: glanceable, interlude, or long-form.
- Always test contrast and use tools like Google Fonts for pairing and preview.
Call to Action (CTA)
A call to action (CTA) is a trigger — often a button or link — designed to guide users toward a specific action: signing up, making a purchase, or learning more. Without clear CTAs, users feel lost; CTAs act as signposts directing them along a planned journey.
Why CTAs matter
- Guide user behavior – steer visitors toward goals (filling a form, downloading an app, buying a product).
- Increase engagement – well-placed CTAs keep visitors on the site longer.
- Drive conversions – turn casual visitors into paying customers, subscribers, or leads.
Example: On a Flipkart product page, the “Add to Cart” and “Buy Now” buttons are bold, contrasting, and large — and they remain visible as the user scrolls (sticky).
Types of CTAs
| Type | Purpose | Example |
|---|---|---|
| Lead generation | Collect user information (email, phone) for follow-up | GoDigit – “You want to see prices? Give us these two info points.” |
| Purchase | Drive direct sales | Flipkart / Amazon – “Add to Cart”, “Buy Now” |
| Learn more | Provide additional information for users not ready to commit | Kia Cars – prominent “Know More” button on a dark luxury background |
| Social sharing | Encourage users to share content on social media | The Better India – share buttons (Facebook, Twitter, LinkedIn, WhatsApp) appear after user scrolls |
| Free trial / demo | Entice users to try software (common for SaaS) | Zoho – “Get Started for Free”, “Try Zoho One” |
Color psychology in CTAs
Colors are powerful psychological tools that evoke emotions and guide decisions. Contrast against the background is essential — a bright CTA on a neutral background pops.
| Color | Effect | Example |
|---|---|---|
| Red | Creates urgency, grabs attention | Zoho’s “Sign Up” / “Try Zoho One” buttons |
| Green | Associated with success, positivity | Payment gateways – “Proceed to Pay” |
| Blue | Evokes trust, reliability | Bank login buttons; Facebook’s login button |
| Yellow / orange | Energetic, eye-catching | Flipkart’s “Add to Cart” and “Buy Now” (orange/yellow on blue background); Shop Now buttons |
Layout tips for CTAs
- Above the fold – place CTAs where users see them without scrolling. MakeMyTrip: flight search inputs are at the top of the homepage.
- Follow natural eye path – center of screen or below engaging content. Google Chrome: “The browser that’s built to be yours” hero text, then a centered “Download Chrome” button.
- White space – surround the CTA with enough spacing to make it pop. Apple: plain layout followed by a single “Buy” button.
- Sticky CTAs – keep CTAs visible as the user scrolls. Flipkart: “Add to Cart” and “Buy Now” remain accessible while browsing specifications and reviews.
Best practices
- Use action-oriented language – words that inspire immediate action: Buy Now, Sign Up, Download, Get Started, Add to Cart.
- Make the value proposition clear – explicitly state what the user gains (e.g., “Recharge Now” emphasizes convenience).
- Test and optimize – experiment with colors, placements, and text via A/B testing; keep what resonates.
Exam tip: A CTA’s effectiveness depends on the combination of color, contrast, placement, and language. Single-factor changes rarely suffice – always test holistic variations.
Key takeaways
- CTAs are triggers that guide users toward a specific action.
- They drive conversions, increase engagement, and shape user behavior.
- Types include lead generation, purchase, learn more, social sharing, and free trial/demo.
- Color choice (red, green, blue, yellow) taps into psychology; contrast with background is critical.
- Placement strategies: above the fold, natural eye path, ample white space, sticky positioning.
- Best practices: action-oriented copy, clear value, and continuous A/B testing.
User Interface (UI) Design
User Interface (UI) design is the craft of making a website intuitive, engaging, and user-friendly. It answers the question: how should elements be arranged so users find what they need without thinking? The core tools are visual hierarchy, layout, alignment, white space, and audience adaptation.
Visual Hierarchy – Guiding the Eye
Visual hierarchy determines the order in which information is noticed and processed. Users naturally gravitate to the biggest, boldest, and brightest elements first. Without hierarchy, all text looks identical and the reader has no focus—like an invitation where every line has the same size and color.
Ways to create visual hierarchy:
| Method | How it works | Example |
|---|---|---|
| Color & contrast | Bright, contrasting colors draw attention; muted colors recede | Nykaa’s “Add to Bag” and “Vitamin C Moisturizer” highlighted in a pop color |
| Size | Larger elements grab attention first | Go Digit’s input fields for registration number and mobile number are enormous (half the size of Virat Kohli’s image) to drive conversions |
| Position | Elements placed in the natural scan path get noticed earlier | F‑pattern or Z‑pattern (see below) |
Natural scanning patterns
- F‑pattern: Users scan left to right across the top, then move down and scan again, forming an “F”. Most common for text-heavy pages.
- Z‑pattern: Users scan left to right, then diagonally down to the left, then left to right again. Common for pages with a single strong focal point.
Exam tip: Always place your most important content (e.g., call‑to‑action, key headline) where the eye lands first—top left for F‑pattern, or top center for Z‑pattern.
Layout & Structure – Making Content Digestible
A good layout guides the user’s journey. After seeing many websites, users expect certain elements in certain places:
- Navigation at the top (not interspersed in content).
- Date/time typically in the bottom‑right corner (like a computer clock).
- Share buttons towards the right edge.
Poor layout example: Times of India – cluttered, advertisements popping up, menu in the middle, datetime at the top, incomplete sentences. Overwhelms and discourages reading.
Better layout example: The Hindu – clear hamburger menu on top left, login on right, logo in center, content broken into “Premium”, “Latest News”, and “Main topics”.
Good layout example: TechCrunch – logo top‑left, hamburger top‑right, categories clearly at the top, biggest article on left with image, smaller headlines on right, ad placed at bottom‑right.
Balanced layout uses:
- Short paragraphs interspersed with images/visuals.
- Card‑based design (Google News shows “Your briefing” as a card).
- Ideal line length for readability: 40–60 characters per line. Too long (like Wikipedia’s monotonous blocks) loses the reader; too short feels choppy.
Exam tip: Wikipedia is often cited as a bad layout example – long unbroken lines, no visual breaks. Compare with a page that uses shorter sentences and cards.
Alignment – The Polish Factor
Alignment is one of the simplest ways to elevate design. A mix of differently aligned titles creates visual discord (e.g., some text centered, some left‑aligned, some right‑aligned). Good alignment uses a single axis – either all centered or all left‑aligned.
- Reduce alignment points: keep items along a few clean grid lines.
- Example: Compare an invitation with scattered alignment (jarring) vs. fully centered or fully left‑aligned (ordered and polished).
White Space – Letting Design Breathe
White space (empty space) is an essential design element, not wasted area. It prevents clutter and directs focus. Luxury shops space out products → feels premium. Discount stores pack shelves → feels cheap. The same applies to UI:
- Apple’s website: lots of white space → sophisticated, valuable.
- Ad‑heavy, cluttered sites: feel low‑quality, stressful.
Designing for the Audience
Always tailor design to the intended users:
| Audience | Design approach |
|---|---|
| Children | Vibrant colors, playful typography (even comic fonts) |
| Corporate users | Minimalist, professional, subdued colors |
| Finance / Legal | Trustworthy, clear, structured |
| E‑commerce | Eye‑catching buttons, visuals that drive purchase |
| Teenage fashion | Trendy, dynamic |
| Medical | Clarity and trustworthiness |
One style does not fit all. Choose colors, fonts, and content that resonate with the specific audience.
Key takeaways – UI Design
- Visual hierarchy controls attention through color, size, and position.
- Users scan in F or Z patterns – place key content accordingly.
- Good layout includes clear navigation, short paragraphs, and ideal line length (40–60 chars).
- Alignment must be consistent along a single axis; avoid mixed alignments.
- White space makes a design feel premium and focused.
- Always design for the audience – adapt colors, typography, and structure to their expectations.
Mobile vs Desktop Design
Desktop and mobile users interact very differently. With mobile usage booming in India, optimizing for both is essential. The differences span layout, navigation, input method, performance, and interactions.
Layout Differences
| Aspect | Desktop | Mobile |
|---|---|---|
| Screen size | Large → multiple columns, side‑by‑side items, grids | Small → single column, cards take full width |
| Content density | Show many items at once (Amazon: 4‑grid, scrollable bar, many categories at top) | Show fewer items; categories hidden behind “Shop by Category” |
| Search bar | Prominent, but not the only navigation | Highly prominent – searching is the primary way to find products |
| Categories | Top navigation bar, visible immediately | Bottom navigation or hamburger menu; more visual‑based |
Responsive design ensures content adjusts seamlessly between devices.
Navigation
- Desktop: Top navigation bar with dropdown menus – users can hover and see subcategories. Flipkart desktop shows fashion, electronics, home appliances with subcategories prominently.
- Mobile: Relies on hamburger menus or bottom navigation bars to save space. No hover → subcategories are only available on the product page via filters.
- Design rule: Simplify navigation for mobile – use collapsible menus or sticky navigation bars.
Touch vs Click
| Input | Characteristics | UI implication |
|---|---|---|
| Desktop (mouse/trackpad) | Precision clicks possible; small buttons OK | Buttons can be small (e.g., Amazon rating link, dropdown arrow) |
| Mobile (touch) | Thumbs lack precision; large targets needed | Buttons must be larger with enough padding to avoid accidental clicks |
Example: On Amazon’s desktop, the “ratings” link is tiny; on mobile, the same element is much larger.
Speed & Performance
- Desktop: Faster internet, better processing → heavy websites with high‑res images, dynamic ads, videos, detailed listings load quickly.
- Mobile: Often on 4G (inconsistent speeds) → need to compress images, reduce animations, and optimize scripts for fast loading.
Interactions
- Desktop: Hover effects reveal sub‑menus, tooltips, etc.
- Mobile: Hover does not exist. Use touch‑friendly alternatives: swipe gestures, accordions, tap‑to‑expand menus.
Key takeaways – Mobile vs Desktop
- Layout: Desktop uses multiple columns; mobile uses single‑column cards.
- Navigation: Desktop has visible top menus with dropdowns; mobile uses hamburger or bottom nav.
- Touch targets: Mobile buttons must be larger to prevent mis‑taps.
- Performance: Mobile needs optimised images and fewer animations for slower networks.
- Interactions: Replace hover with tap, swipe, or accordion patterns.
- Always test on both devices – mobile optimization is a necessity in mobile‑first markets.
Assignment: Analyze and Improve a Small Business Website
This assignment tests your ability to apply product management and design principles to a real-world scenario. You will analyze an existing small business website, identify strengths and weaknesses, and propose improvements that align design, functionality, and business goals. The goal is not just to spot flaws, but to understand how every design choice serves (or fails) the site’s primary objective.
Selecting a Website
Pick a real website for a small local business – e.g., a restaurant, hair salon, service provider. Ensure you can access and evaluate it.
Analysis Framework
Use the concepts from the module (color, typography, UI, user flow, content structure) to assess the site systematically.
| Aspect | Key Questions |
|---|---|
| Business goals | What is the primary business objective (e.g., increase online orders, drive foot traffic, collect leads)? Do the design elements support that goal? |
| User needs | Who are the users? What do they need (hours, menu, contact info)? How well are those needs addressed? |
| Design elements | Evaluate color schemes, typography, spacing/white space. Are they consistent, legible, and appropriate for the brand? |
| Call‑to‑actions (CTAs) | Are CTAs clear, prominent, and effective? (e.g., “Order Now”, “Book Appointment”) |
| User experience (UX) | Is navigation intuitive? Is information easy to find? Is the site optimized for its primary objective? |
Deliverable
Create a concise report (2–3 pages) or a PPT presentation. Structure it into clear sections:
- Brief introduction of the small business.
- Strengths and weaknesses of the current site.
- Actionable improvement suggestions with concrete examples.
- Summary explaining how proposed changes align with business goals and improve user experience.
Include photos, screenshots, and visual mockups to show the difference between current and proposed designs.
Worked Example (from transcript)
Scenario: A bakery’s website goal is to increase online orders.
Observation: Site has small images and unclear CTAs.
Improvement: Add a prominent “Order Now” button and larger, appetizing product images.
Your recommendations should similarly connect a specific flaw to a concrete fix and the business goal it supports.
Exam tip: For this assignment, explicitly state why each improvement serves the business goal — that linking is the core skill.
Key takeaways
- Analyze a real small‑business website against module principles.
- Evaluate business goals, design, CTAs, UX, and user needs.
- Suggest actionable improvements with examples.
- Deliver a 2–3 page report or PPT with visuals.
- Demonstrate how design and business goals must align.
CMS and WordPress Basics, online ready to use tools
Introduction: AI and WordPress
This module bridges two worlds: WordPress – the world's most widely used Content Management System (CMS) – and AI-powered development – using machine learning tools to generate, optimize, and debug code. The goal is to combine the simplicity of a CMS with the speed of AI to build websites faster and with fewer errors.
WordPress — A Content Management System
A Content Management System (CMS) is software that lets users create, manage, and modify website content without needing technical expertise. WordPress is the dominant CMS because it:
- Simplifies website creation (no manual HTML/CSS required for basic pages)
- Offers a huge ecosystem of themes and plugins
- Is used by individuals, small businesses, and large enterprises alike
This module covers only the basics of WordPress – enough to understand how it fits into a developer's toolkit.
AI-Powered Development
Over the previous modules you built websites from scratch using HTML, CSS, and JavaScript. AI tools now let you do the same work faster and more efficiently by:
- Generating layouts – AI can produce HTML/CSS structures from a description
- Improving styling – suggest CSS refinements or responsive adjustments
- Automating JavaScript functions – write and debug common scripts
- Suggesting best practices – optimise code style, accessibility, performance
The core insight: AI does not replace the need to understand code, but it handles repetitive tasks and catches mistakes, freeing you to focus on architecture and design.
Key takeaways
- WordPress is a CMS that lowers the barrier to building websites.
- AI tools can write, optimise, and enhance code across HTML, CSS, and JavaScript.
- This module combines both: learn WordPress basics and practise using AI to speed up web development.
- The skills from earlier modules (manual coding) are still essential – AI is an accelerator, not a crutch.
Introduction to WordPress
WordPress is the world’s most widely used content management system (CMS), powering over 40% of all websites. It enables building websites without manual coding (HTML, CSS, JavaScript) through a drag‑and‑drop interface, making development faster, easier, and accessible to non‑developers.
Why Use WordPress?
- Free & open source – anyone can download, use, and modify it.
- Highly customizable – thousands of themes and plugins available.
- User‑friendly – no coding knowledge required; intuitive admin interface.
- CMS‑driven – content is managed via posts (dynamic, blog‑like) and pages (static).
WordPress.org vs WordPress.com
| Aspect | WordPress.org (Self‑Hosted) | WordPress.com (Hosted) |
|---|---|---|
| Hosting | You bring your own domain & hosting | WordPress.com takes care of hosting |
| Control | Full control over customization, themes, monetization | Limited customization (free tier) |
| Setup | Requires manual download & installation | Sign up and start immediately |
| Cost | Free software + hosting fees | Free basic plan; paid plans remove ads & add features |
| Recommended for | Professional sites, full ownership | Beginners, quick prototyping, learning |
Exam tip: For a free, low‑commitment start to learn WordPress, use WordPress.com. For a production site with complete freedom, use self‑hosted WordPress.org.
Getting Started with WordPress.com
- Sign up at
wordpress.com– create an account. - Choose a domain – free subdomain (
yoursite.wordpress.com) or a paid custom domain. - Select a theme – pick a starting design (can be changed later).
- Set site title – e.g., “IIMB WordPress Demo”.
- Launch – the site is live immediately.
Creating Pages and Posts
- Pages – for static content (Home, About, Contact).
- Created from Pages → Add New.
- Each page can be customized with blocks (text, images, forms, maps).
- Posts – for dynamic, time‑sensitive content (blogs, news).
- Created from Posts → Add New.
- Automatically show up on the designated Blog page (set under Settings → Reading).
- Navigation menus – add/remove links to pages, posts, or external URLs via the Navigation block on the editor.
Worked example (from the demo):
- Homepage: added a logo, updated text “Welcome to the WordPress demo website”, linked a button.
- About page: created with simple title and paragraph.
- Contact page: added a contact form and a Google Maps block.
- Blog page: displayed posts in a three‑column grid.
Customizing Appearance
- Themes – change the entire look via Appearance → Themes.
- Content remains intact when switching themes.
- Recommended: finalize a theme before building content.
- Styles – adjust colors, fonts, typography globally via the Styles panel.
- Header & Footer – remain constant across all pages; editable in the template editor.
- Blocks – drag‑and‑drop elements (images, buttons, galleries, maps, etc.) build pages without code.
Publishing and Maintenance
- Changes must be saved and published to reflect on the live site.
- After publishing, edits can be made anytime.
- Paid plans unlock: custom domain, removal of WordPress.com branding, plugins (SEO, security), custom emails, and advanced user roles.
Intuition: WordPress treats the homepage as a template (often called Home or Front Page), other pages inherit its header/footer, and posts are managed separately. This structure makes it easy to update navigation or design once and have it propagate everywhere.
Key Takeaways
- WordPress powers >40% of the web; it’s free, open‑source, and requires no coding.
- WordPress.org (self‑hosted) gives full control; WordPress.com (hosted) is simpler for beginners.
- Content is split into pages (static) and posts (dynamic, blog‑like).
- The block editor (drag‑and‑drop) allows inserting and customizing text, images, forms, maps, etc.
- Themes change the look without losing content; headers/footers are shared across pages.
- Menus and navigation are managed via the Navigation block and can link to pages, posts, or external URLs.
- Start with a free WordPress.com site to explore; move to self‑hosted for real‑world professional use.
Using AI & ChatGPT for Code Generation
Large Language Models (LLMs) like ChatGPT and Claude can generate, debug, and optimise code far faster than manual writing. The key to getting reliable, useful output is prompting — how you phrase your request. Knowing the basics of HTML, CSS, and JavaScript (covered in earlier modules) lets you guide the AI, evaluate its suggestions, and fix issues when the output is incomplete or wrong.
Why Prompting Matters
A vague prompt almost always yields unpredictable or broken code.
| Prompt style | Example | Result |
|---|---|---|
| Too vague | “Write me a text animation script.” | Works sometimes, fails if your HTML structure differs. Often misses needed elements, uses different styling or logic each time. |
| Specific | “Create a typing animation for these three sentences, loop infinitely, with a 2-second pause before backspacing at 50 ms, using only Vanilla JS.” | Reliable, predictable, matches your exact intent. |
Key insight: The AI does not know your webpage, your element IDs, or your desired behaviour. The more context you provide, the more likely the generated code will work as is.
Anatomy of a Good Prompt
A high-quality prompt should include:
- What the code should do – e.g., “type out each character one by one, then delete characters one by one like a backspace”.
- Structure of your webpage – e.g., “I have an HTML file with a
<p id=“animated-text”></p>element”. - Constraints – e.g., “Don’t use jQuery”, “Only Vanilla JS”, “Use
querySelectorinstead ofgetElementById”. - Behaviours – e.g., “Pause 2 s after finishing a sentence”, “Loop infinitely”.
- Step-by-step breakdown – for complex tasks, break the request into smaller parts.
Step‑by‑Step Approach – Worked Example
The transcript walks through building a typewriter effect (from Module 7) using ChatGPT. The lesson: a single vague prompt produces a script that may work, but a broken‑down, iterative process yields a clean, modular, debug‑friendly result.
1. Vague prompt → Unpredictable
Prompt: "Write me a text animation script for my website."
Output: A script that uses getElementById("animated-text") but does not supply the HTML. When pasted into an existing page without that element, nothing works. Adding the element (<p id="animated-text"></p>) might make it run, but the next time you ask, the AI might give a completely different animation (e.g., fade‑in instead of typing).
2. Specific prompt → Works better
Prompt: "Give me a JavaScript that creates a typing animation for these three sentences:
[‘Hello world’, ‘Welcome’, ‘Goodbye’]. Loop through them. After each sentence, pause 2 s,
then delete characters one by one at a faster rate. Use only Vanilla JS."
Output: A self-contained script with sentenceIndex, charIndex, a isDeleting flag, and recursive typeEffect function. Works out of the box.
3. Iterative refinement → Modular, re-usable
Even the good output can be improved. The transcript shows how to guide ChatGPT to:
- Replace a ternary operator with a clear
if-elsestructure (for readability). - Add comments.
- Switch from
getElementByIdtoquerySelector(better practice). - Add a blinking cursor.
- Wrap everything inside a
DOMContentLoadedlistener. - Keep functions separate and call them from a
startAnimationdispatcher.
Why this works: Because you know the basics (DOM, querySelector, event listeners, function scope), you can tell the AI exactly what changes to make.
The Role of Foundational Knowledge
You do not need to be an expert, but you must understand core concepts to:
- Guide the prompt – e.g., “Use
querySelectorbecause it’s more flexible”. - Evaluate output – When ChatGPT suggests “use
clearIntervalfor better control”, you can judge whether it’s truly needed (here, it was not). - Debug errors – If the script references an element that doesn’t exist, you know to add it.
- Break down problems – AI works best on small, logical steps (just like you would write code manually).
Exam tip: The most common mistake is trusting AI output without testing. Always copy the generated code into your project and verify it works. If you don’t understand the code, ask the AI to explain it first.
Best Practices Summary
| Practice | Why |
|---|---|
| Be specific about desired behaviour, HTML structure, and constraints. | Reduces ambiguity; code matches your page. |
| Break tasks into steps – ask for one function at a time. | Easier to debug and refine each piece. |
| Request comments and clear variable names. | Improves readability for you and others. |
| Use your existing knowledge to correct or guide the AI. | Keeps code aligned with best practices (e.g., querySelector over getElementById). |
| Question and iterate – never accept the first output as final. | AI often makes small mistakes; you can fix them iteratively. |
| Leverage AI to explain unknown syntax (e.g., ternary operator, arrow functions). | Fills knowledge gaps while coding. |
Key takeaways
- Vague prompts → random, often broken code. Specific prompts → reliable code.
- A good prompt includes: task, HTML structure, constraints, behaviours.
- Know the basics to guide the AI, evaluate its suggestions, and fix errors.
- Break complex requests into smaller, logical steps.
- Always test AI-generated code; iterate until it meets your exact needs.
Module Recap: Conclusion and Key Takeaways
The course laid a foundational web development skill set, starting from the fundamentals of how the internet works through the distinction between frontend and backend, then building practical competency in HTML, CSS, and JavaScript for creating interactive web pages. Finally, WordPress was introduced as a content management system (CMS) — a real-world tool for managing sites without deep code.
Core competencies acquired
- Internet fundamentals — request/response, client-server model, domain names.
- Frontend markup & styling — HTML for structure, CSS for layout and appearance.
- Interactivity — JavaScript for dynamic behaviour (DOM manipulation, events).
- CMS basics — WordPress as an “online-ready” tool for quickly building and managing content-driven sites.
Key takeaways
- The course built a strong, general base — not just syntax, but the mental model for solving web problems.
- This foundation opens doors to deeper specialisation: frontend frameworks, backend scripting, or full-stack development.
- The digital world evolves constantly; the skills learned are transferable — the goal is to keep learning, creating, and innovating.
Transition tip: Treat this module as a launchpad. The WordPress section, in particular, is a stepping stone to managing live sites or exploring e‑commerce, membership, and custom theme development.
HTML Basics and Building Webpages
Introduction to HTML
HTML (HyperText Markup Language) is the foundation of every web page. It defines what content appears and how it is structured. CSS controls visual styling and JavaScript adds interactivity, but HTML alone is sufficient to build a complete, functional website. Without HTML, the other two layers have nothing to work on.
What “HyperText Markup Language” really means
- HyperText – text that can link to other pages or resources. The first website ever (by Tim Berners‑Lee) consisted entirely of hyperlinked text; clicking a blue link navigates to another document.
- Markup – extra annotations that tell the browser how to display or organise the content.
Analogy: In WhatsApp, wrapping text in asterisks (*text*) makes it bold. The asterisks are a simple markup language. HTML works the same way, but uses tags instead of symbols.
HTML tags: the building blocks of a webpage
An HTML tag is a markup instruction enclosed in angle brackets (< >). Tags tell the browser what role a piece of content plays (e.g., heading, paragraph, link). A typical tag comes in an opening and closing pair.
| Tag pair | Purpose | Browser rendering |
|---|---|---|
<h1>…</h1> | Main heading | Large, bold text |
<p>…</p> | Paragraph | Normal body text |
Once a browser parses an HTML file, it uses these tags to decide font size, alignment, and hierarchy — no CSS required for basic structure.
Worked example: heading vs. plain text
The lecture demonstrated a simple HTML file:
Some normal text here.
<h1>This is a Heading</h1>
Some more normal text.
When rendered in the browser:
- The first line appears as ordinary plain text.
- The
<h1>-tagged text is larger, bolder, and visually distinct — it is treated as a top‑level heading.
This shows that markup directly changes how content is displayed without any extra styling files.
Key takeaways
- HTML = HyperText (links) + Markup (tags for structure).
- Tags are the core mechanism: they define the role and appearance of content.
- A complete website can be built with HTML alone; CSS and JavaScript are optional enhancements.
- The
<h1>tag is used for the most important heading; browsers render it larger and bolder by default. - Always pair opening and closing tags (e.g.,
<h1>…</h1>) — missing a closing tag can break the layout.
HTML Elements and Header Tags
HTML elements are the building blocks of web pages. An element consists of an opening tag, content, and a closing tag. For example, <p>Text</p> – the <p> is the opening tag, the content is "Text", and </p> is the closing tag. Some elements (e.g., <br>, <img>) have no closing tag and are called self-closing or void elements.
Heading Tags (<h1> to <h6>)
Heading tags define hierarchical headings, exactly like a book’s title, chapters, sections, and sub-sections. Intuitively, they tell both the browser and the reader: "This text is a heading, not just big bold text."
| Tag | Usage | Visual size (typical) |
|---|---|---|
<h1> | Main title (one per page recommended) | Largest |
<h2> | Major sections / chapters | Large |
<h3> | Sub-sections within an <h2> | Medium |
<h4> | Sub-sub-sections | Smaller |
<h5> | Low-level headings | Small |
<h6> | Lowest heading level | Smallest |
The browser renders each level with a distinct font size and weight, establishing a visual hierarchy.
Purpose: Semantic Structure & SEO
Headings do more than change font size. They:
- Show relationships between content (e.g., a
<h2>module belongs under the<h1>course title). - Help search engines (SEO) understand the page’s outline. Skipping levels (e.g., jumping from
<h1>to<h3>) is considered poor practice. - Improve accessibility for screen‑reader users navigating by headings.
Example: “Website Development” Course Outline
<h1>Website Development</h1>
<h2>Module 1: Introduction</h2>
<h3>Video 1: Welcome Notes</h3>
<h3>Video 2: HTTP and Request Response</h3>
<h2>Module 2: Product Principles</h2>
<h3>Video 1: Product Principles</h3>
<h3>Video 2: Design</h3>
<h2>Module 3: HTML Basics</h2>
<h3>Video 1: Intro</h3>
<h3>Video 2: Heading Tags</h3>
This structure mirrors a table of contents. The <h1> is the course title; <h2>s are modules; <h3>s are videos within each module. Nesting is consistent: no skipped levels.
flowchart TD
H1["<h1> Website Development"] --> H2a["<h2> Module 1: Introduction"]
H1 --> H2b["<h2> Module 2: Product Principles"]
H1 --> H2c["<h2> Module 3: HTML Basics"]
H2a --> H3a1["<h3> Video 1: Welcome Notes"]
H2a --> H3a2["<h3> Video 2: HTTP and Request Response"]
H2b --> H3b1["<h3> Video 1: Product Principles"]
H2b --> H3b2["<h3> Video 2: Design"]
H2c --> H3c1["<h3> Video 1: Intro"]
H2c --> H3c2["<h3> Video 2: Heading Tags"]
Exam tip: Never skip heading levels (e.g.,
<h1>→<h3>). This hurts both visual consistency and SEO. Always nest<h2>under<h1>,<h3>under<h2>, etc.
Key Takeaways
- An HTML element = opening tag + content + closing tag (unless void/self‑closing).
- Heading tags (
<h1>...<h6>) define content hierarchy, not just size. - Use one
<h1>per page (the main title), then<h2>for major sections,<h3>for sub‑sections, etc. - Proper heading structure improves readability, accessibility, and SEO.
- Do not skip levels – always descend sequentially.
HTML Structure
Every HTML file must follow a specific structure with mandatory elements to render correctly across all browsers. This foundation — called the HTML boilerplate — is a reusable template that ensures all essential parts are present before you add content.
Most code editors, such as VS Code, auto-generate this boilerplate: type ! and press Enter to produce the full structure.
The Document Type Declaration
The DOCTYPE declaration goes first:
<!DOCTYPE html>
This tells the browser you are using HTML5 (the modern version). Every HTML file must begin with this declaration.
The HTML Root Element
After DOCTYPE, the <html> tag wraps the entire document. This is the root element.
<html lang="en">
The lang attribute (e.g., lang="en" for English) is optional in basic usage but helps with accessibility and search engines.
The Head Element
The <head> section contains metadata — information for the browser, not visible on the page. Inside the head you typically find:
<meta charset="UTF-8">— sets the character encoding to support most languages and symbols.<meta name="viewport" content="width=device-width, initial-scale=1.0">— ensures the page scales correctly on mobile devices (controls how content fits the screen width).<title>— defines the text that appears on the browser tab. For example:<title>Intro to Webpages</title>
The head elements are children of the head tag (nested inside it). The title text is the only part immediately visible to the user (in the tab).
The Body Element
The <body> section holds all content visible to users: headings, paragraphs, images, links, lists, tables, etc.
<body>
<h1>This is a webpage</h1>
</body>
Everything added inside the body appears in the browser's main viewport.
Document Hierarchy (Visual)
flowchart TD
A[<!DOCTYPE html>] --> B[<html lang="en">]
B --> C[<head>]
C --> D[<meta charset>]
C --> E[<meta viewport>]
C --> F[<title>]
B --> G[<body>]
G --> H[Visible content: h1, p, img, etc.]
Indentation
HTML files use indentation (spaces or tabs) to show nesting — which elements are children of which. Proper indentation makes the code readable; it is not required by the browser but is a best practice.
Exam tip: You do not need to memorise the entire boilerplate — know that
!+ Enter in VS Code generates it. But you must recognise what each part does. The most commonly tested elements:DOCTYPE,html,head,title, andbody.
Key takeaways
- DOCTYPE
<!DOCTYPE html>declares HTML5 version to the browser. <html>is the root element; often includes alangattribute.<head>holds metadata (charset, viewport, title) — not visible on the page.<title>text appears in the browser tab.<body>contains all visible content (headings, text, images, etc.).- The boilerplate can be auto-generated in VS Code (
!+ Enter).
Indentation in HTML
Indentation is the practice of adding leading spaces (or tabs) at the start of a line to visually show the nesting structure of HTML elements. It does not affect how the page is rendered, but it profoundly improves code readability, organization, and debuggability.
Why Indentation Matters
| Reason | Explanation |
|---|---|
| Readability | Clean, structured code allows you and others to understand the document hierarchy at a glance – vital as projects grow. |
| Organization | The visual hierarchy clearly shows where each element opens and closes. |
| Debugging | Proper indentation makes it easy to spot unclosed tags (e.g., a missing </head>). Unindented code hides such errors. |
| Collaboration | Consistent indentation across a team ensures everyone can parse the code quickly. |
Indented vs. Unindented – A Side‑by‑Side Comparison
<!-- Indented (clear hierarchy) -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Page Title</title>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
<!-- Unindented (structure invisible) -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Page Title</title>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
In the unindented version, it is difficult to see where <head> ends or whether <meta> has a closing tag. Indentation eliminates that confusion.
How to Apply Indentation
- Manually: Press <kbd>Tab</kbd> or add spaces before each nested tag.
- Automatically (recommended): Install Prettier (or a similar code formatter). Right‑click → Format Document (or use the keyboard shortcut). Prettier will re‑indent everything consistently.
Customising Indentation Preferences
| Setting | Options | Notes |
|---|---|---|
| Tab width | Usually 2 or 4 spaces | Personal preference; many developers use 4. |
| Use tabs vs. spaces | Tabs (\t) or spaces ( ) | Most teams pick one and stick to it. |
| Setting location | Extensions → Prettier → settings (e.g., tabWidth, useTabs) | Adjust to match your team’s style guide. |
Nesting and the Parent‑Child Rule
Elements in HTML form a parent‑child (or ancestor‑descendant) relationship. Indentation mirrors this:
graph TD
html --> head
html --> body
head --> meta
head --> title
body --> h1
- Parent elements stay at the same horizontal level (e.g.,
<head>and<body>are both children of<html>, so they share the same indentation). - Child elements are indented one level deeper than their parent.
- Closing tags should align vertically with their opening tag (e.g.,
</head>is at the same indentation level as<head>).
Exam tip: Even though indentation is not graded in a browser, an exam or interview question may present unindented code and ask you to spot a missing closing tag. Practise “reading” indentation to catch errors instantly.
Key takeaways
- Indentation is purely for humans – it has zero effect on rendering.
- It improves readability, organisation, debugging, and team collaboration.
- Parent elements sit at the same level; children are indented one level deeper.
- Use a formatter like Prettier to enforce consistent indentation automatically.
- Always align opening and closing tags at the same indentation level.
- Choose tabs or spaces and a tab width (commonly 2 or 4 spaces) and apply it uniformly.
Paragraph Tag
The paragraph element (<p>) is the fundamental HTML building block for grouping and formatting blocks of text on a webpage. It visually separates text into distinct chunks with spacing between them, making content readable and structured.
What the Paragraph Element Does
- Starts with an opening tag
<p>and ends with a closing tag</p>. - All text that belongs to the paragraph goes between these two tags.
- Without it, plain text in HTML collapses into one continuous line, ignoring line breaks in the source code.
Plain Text vs. Paragraph Tags
| Scenario | Result |
|---|---|
Plain text (no <p> tags) | All text runs together into one long line, even if written as multiple lines in the editor. |
Text wrapped in <p>…</p> | Each paragraph gets a visual space above and below, creating clear separation. |
Why It Matters
- Readability: Separate paragraphs are easier for humans to scan and read.
- Accessibility: Screen readers use
<p>tags to identify where a paragraph begins and ends. This helps visually impaired users navigate and understand content structure.
Practical Example — Placeholder Text
When building a website without final copy, placeholder (dummy) text gives a realistic preview of how the layout will look. Tools like lipsum.com generate text with varied line lengths and word sizes, providing a better sense of final spacing than repeated phrases.
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. ...</p>
<p>Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ...</p>
<p>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris ...</p>
Exam tip: The closing
</p>tag is optional in some older HTML specifications, but always include it for proper structure and accessibility — many browsers will still render text without it, but screen readers and validators may break.
Key takeaways
- Use
<p>to split text into visually separated blocks. - Plain text in HTML runs together;
<p>fixes that. - Paragraph tags improve readability for sighted users and navigation for screen readers.
- Placeholder text (e.g., from lorem‑ipsum generators) helps preview layouts without real content.
Self-Closing Tags (Void Elements)
Self-closing tags (also called void elements) are HTML tags that require no closing tag and contain no content. Unlike regular tags (e.g., <p>...</p>) which wrap content between an opening and a closing tag, a self-closing tag is self-contained — it represents an element that doesn’t “wrap” anything.
| Regular tag | Self-closing tag |
|---|---|
<p>Some text</p> | <hr /> or <br> |
| Has opening tag + content + closing tag | Only an opening tag (optionally with a trailing slash) |
The forward slash in a self-closing tag (e.g., <hr />) goes at the end, not the start as in a closing tag.
Exam tip: The slash is optional in modern HTML — browsers treat
<br>,<br/>, and<br />identically. However, using the trailing slash is recommended for consistency and readability.
Horizontal Rule <hr>
The <hr> (horizontal rule) element draws a thematic break — a horizontal line — across the page. It visually separates sections of content (e.g., between two paragraphs).
When to use: To divide content where a new section begins (not merely for decoration).
Example (from lecture):
<p>First paragraph text.</p>
<hr />
<p>Second paragraph text.</p>
- The line extends from left to right edge.
- No content is placed inside
<hr>– it is purely visual.
Caution: Do not overuse <hr>. Too many horizontal rules make the page look cluttered.
Break Element <br>
The <br> (line break) element inserts a new line within the same block of text — it does not start a new paragraph. It is used when you need a line break inside a single paragraph or other block-level element.
When to use:
- Poetry, addresses, song lyrics
- Any text where line breaks are part of the content’s meaning
Example (address of IIM Bangalore):
<p>
IIM Bangalore<br>
Bilekhahalli, Bannerghatta Road<br>
Bangalore – 560076
</p>
The rendered output keeps all lines inside one <p> tag, but displays on separate lines.
Exam tip: Never use
<br>to add vertical spacing between paragraphs – use CSSmarginor a new<p>tag instead.<br>is for structural line breaks within a single phrase.
Key Takeaways
- Self-closing (void) tags have no content and no closing tag; examples:
<hr>,<br>,<img>. <hr>creates a horizontal rule to separate sections – use sparingly.<br>adds a line break inside a paragraph – use for addresses, poetry, etc.- The trailing slash is optional in modern HTML but recommended for code clarity.
- Browsers ignore text placed inside a self-closing tag (it is not meant to hold content).
Ordered and Unordered Lists and Nesting
Lists are a fundamental way to group related items on a webpage. The choice between ordered (<ol>) and unordered (<ul>) depends on whether the sequence of items carries meaning.
- Unordered list (
<ul>) – when the order of items does not matter. Rendered with bullet points. - Ordered list (
<ol>) – when the sequence is important (e.g., step-by-step directions). Rendered with sequential numbers.
HTML structure
Each list type contains list items (<li>). The tags themselves (<ul>, <ol>) do not display content; only <li> elements produce visible list items.
<!-- Unordered list: order irrelevant -->
<ul>
<li>Only one guest allowed</li>
<li>No entry after 6:00 PM</li>
<li>Wear fancy clothes for DJ night</li>
</ul>
<!-- Ordered list: order matters -->
<ol>
<li>Arrive at Majestic Metro</li>
<li>Take Metro to JP Nagar</li>
<li>Rent a cab towards Vega City Mall</li>
<li>Take right at Vega City → IIMB</li>
</ol>
Exam tip: The numbering in an ordered list is automatically generated based on the order of
<li>elements in the code. Reordering<li>tags renumbers the output.
Nesting lists
Nesting means placing one HTML element inside another. A list can be nested inside a list item to create sub‑lists. This establishes a parent–child relationship in the document tree.
Example – adding warnings under the first step of the directions:
<ol>
<li>Arrive at Majestic Metro
<ul>
<li>Be careful of pickpockets</li>
<li>Metro closes at 10:00 PM</li>
</ul>
</li>
<li>Take Metro to JP Nagar</li>
<li>Rent a cab towards Vega City Mall</li>
<li>Take right at Vega City → IIMB</li>
</ol>
The inner <ul> becomes a child of the first <li>, and its <li> elements are children of that inner <ul>. Nesting can continue further (lists inside lists inside lists).
Relationship diagram
flowchart TD
A["<ol> (ordered list)"] --> B["<li> Arrive at Majestic Metro"]
B --> C["<ul> (nested unordered list)"]
C --> D["<li> Be careful of pickpockets"]
C --> E["<li> Metro closes at 10:00 PM"]
A --> F["<li> Take Metro to JP Nagar"]
A --> G["<li> Rent cab..."]
A --> H["<li> Take right at Vega City"]
Worked example – IIMB fest webpage
Building a simple invitation page with two sections:
- Points to remember (unordered list)
- Directions (ordered list with nested warnings)
<h1>IIMB Fest – Welcome!</h1>
<h2>Points to remember</h2>
<ul>
<li>Only one guest allowed</li>
<li>No entry after 6:00 PM</li>
<li>Wear fancy clothes for DJ night</li>
</ul>
<h2>Directions to IIMB</h2>
<ol>
<li>Arrive at Majestic Metro
<ul>
<li>Watch out for pickpockets</li>
<li>Last metro at 10:00 PM</li>
</ul>
</li>
<li>Take Metro to JP Nagar</li>
<li>Rent a cab towards Vega City Mall</li>
<li>Take right at Vega City → IIMB</li>
</ol>
Rendered output: the directions appear numbered, with bullet‑point sub‑notes under the first step.
Comparison: <ul> vs <ol>
| Aspect | <ul> (unordered) | <ol> (ordered) |
|---|---|---|
| Default marker | Bullet point | Number (1, 2, 3…) |
| When used | Order irrelevant | Order matters (steps, rankings) |
| Example | Tips, features, ingredients | Recipes, directions, top‑10 lists |
Exam tip: Nested lists must be placed inside an
<li>element, never directly inside another<ul>or<ol>. Incorrect nesting breaks the document structure.
Key takeaways
- Use
<ul>for bullet lists (order unimportant); use<ol>for numbered lists (order required). <li>tags are the only visible content containers inside lists.- Nesting is done by placing a full
<ul>or<ol>inside an<li>. - Nesting creates parent‑child relationships analogous to an outline or tree structure.
Example Webpage: IIMB Fest 2024
A practical demonstration integrates previously learned HTML elements (headings, paragraphs, ordered lists, unordered lists) into a single functioning webpage.
Building the Boilerplate
Every HTML page begins with a boilerplate — the minimal structural template required for a browser to interpret the document correctly.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>IIMB Fest 2024</title>
</head>
<body>
<!-- Content goes here -->
</body>
</html>
<!DOCTYPE html>declares this is an HTML5 document.<html lang="en">sets the language (English).<meta charset="UTF-8">ensures text encoding supports all characters.<meta name="viewport">scales the page to the device width (responsive).<title>defines the browser tab title — not rendered on the page itself.- Everything inside
<head>is metadata; the user does not see it.
Structuring Visible Content (the <body>)
Content inside <body> is rendered in the browser window. The page builds from top to bottom:
- Main heading –
<h1>IIMB Fest 2024</h1>– the most prominent text. - Introductory paragraph –
<p>Welcome to the Best Fest in Bangalore.</p> - Sub-heading for instructions –
<h2>Instructions</h2> - Unordered list (bullet points) –
<ul>for items with no inherent order. - Sub-heading for directions –
<h2>Directions to Reach</h2> - Ordered list (numbered) –
<ol>for sequential steps.
Exam tip: Always match heading levels logically. An
<h1>should be the page title;<h2>is a major sub-section. Skipping levels (e.g.,<h1>then<h3>) breaks accessibility and semantics.
Adding Lists
The transcript uses two list types from prior videos:
| List Type | Tag | Use Case | Example Content |
|---|---|---|---|
| Unordered (bullet) | <ul> + <li> | Items without sequence | Only one guest allowed; No entry after 6 PM; Wear good clothes for DJ night |
| Ordered (numbered) | <ol> + <li> | Sequential steps | Arrive at Mastic Metro; Be careful of pickpockets; Metro closes at 10 PM; Take metro to JP Nagar; Rent a cab; Take a ride at Vega City; Arrive at IIMB |
The ordered list for directions demonstrates a step‑by‑step journey. The unordered list captures rules that have no specific order.
Viewing the Page
The lecturer uses Live Server (a VS Code extension) to auto‑refresh the page on save. The rendered page shows:
- A bold heading "IIMB Fest 2024".
- A welcoming paragraph.
- A bullet‑point list of instructions.
- A numbered list of directions.
The result is functional but visually plain – styling is deferred to CSS later in the course.
Connection to what comes next
The current page will be extended with anchor elements (<a>) for links and images (<img>). CSS will eventually add layout and beautification.
Key takeaways
- Every HTML page starts with
<!DOCTYPE html>and the<html>,<head>,<body>structure. - Use
<h1>for the primary page heading;<h2>for major sections. - Unordered lists (
<ul>) group items without ordering; ordered lists (<ol>) imply sequence. - Metadata in
<head>(charset, viewport, title) is not rendered but is essential. - Tools like Prettier and Live Server improve developer workflow.
Anchor Element
The anchor element (<a>) creates hyperlinks — the foundation of web navigation. Without it, users couldn't jump between pages or resources. Intuitively, it turns a piece of text (or any inline content) into a clickable link.
Syntax & basic behaviour
<a>Visit IIMB</a>
This displays plain text, not a link. To make it functional, an attribute is needed.
The href attribute
href (hypertext reference) specifies the destination URL. It is tag-specific to the anchor element.
<a href="https://www.iimb.ac.in">Visit IIMB</a>
The text Visit IIMB becomes a blue, underlined link. Clicking it navigates to the given URL.
Exam tip: Without the
hrefattribute, the anchor element is just inert text. Thehrefattribute is what turns it into a hyperlink.
Nesting anchor tags inside other elements
An anchor can wrap any inline or block content (headings, list items, etc.).
| Wrapping scope | Result |
|---|---|
Entire heading <h2> | Entire heading becomes a link |
Entire list item <li> | Whole item (including bullet) becomes clickable |
| Single word inside a list item | Only that word is linked |
Example:
<li><a href="...">Be careful of pickpockets</a></li>
Only the word "Be careful of pickpockets" is linked; the rest of the item is not.
Attributes: global vs. tag-specific
Attributes give HTML elements extra functionality.
- Global attributes — apply to nearly every HTML element (e.g.,
draggable,hidden,class,id). - Tag-specific attributes — unique to certain elements (e.g.,
hreffor<a>,srcfor<img>).
Best practice: use official documentation (MDN) rather than memorising every attribute.
Examples of global attributes from the lecture
draggable="true"— allows the element to be dragged.<li draggable="true">Only one guest is allowed</li>hidden="until-found"— hides the element until the browser finds a text match (e.g., via Ctrl+F).
Searching for "wear" reveals the item.<li hidden="until-found">Wear good clothes</li>
The two most important global attributes, class and id, will be covered later (critical for CSS/JavaScript).
Key takeaways
- The anchor element
<a>creates hyperlinks only when itshrefattribute is present. hrefis a tag-specific attribute; global attributes likedraggableandhiddenwork on most elements.- An anchor can wrap entire elements (headings, list items) or just a part of them.
- Never memorise all attributes – use MDN documentation to look them up.
classandidare essential global attributes that unlock styling and scripting.
Image Tag (<img>)
The image tag (<img>) embeds images — static photos, animated GIFs — into a webpage. It is a void element (no closing tag) because its content is the image itself, not text.
Attributes
| Attribute | Purpose | Example |
|---|---|---|
src | Source – URL or file path to the image | src="https://..." or src="./images/photo.webp" |
alt | Alternative text – fallback text if image fails, used by screen readers and SEO | alt="IIMB logo" |
height | Height – sets image height in pixels (width adjusts automatically unless width also set) | height="40" |
width | Width – sets image width in pixels | width="100" |
Exam tip:
alttext is required for accessibility and SEO. If the image is purely decorative, usealt=""(empty) — never omit the attribute.
Image sources
-
Online (URL): Provide a direct link to the hosted image (e.g., from placeholder.co or picksome.photos).
<img src="https://via.placeholder.com/150" alt="placeholder"> -
Local (relative path): Use the
./notation to specify the file relative to the HTML document.
<img src="./images/dj.gif" alt="DJ night">– assumes animages/folder in the same directory.
File formats & WebP
- GIF – supports animation but larger file sizes.
- JPEG/PNG – static images, larger sizes.
- WebP – modern format by Google, produces smaller files while maintaining good quality, supports both static and animated images. Recommended for faster loading.
Practical example: Adding a logo and a GIF
<!-- Logo before heading -->
<img src="https://iimblogo.url/logo.png" alt="IIMB logo" height="40">
<!-- GIF inside a list item -->
<li>DJ Night
<br>
<img src="./images/dj.gif" alt="DJ night" height="100">
</li>
The height attribute prevents the logo from overwhelming the heading; the <br> places the GIF on a new line.
Key takeaways
<img>is a void element: no closing tag.srcspecifies the image location (URL or local path).altprovides fallback text and improves accessibility/SEO.- Use
heightandwidthto control image dimensions. - Prefer WebP for smaller file sizes and faster loading.
HTML Comments
HTML comments are invisible notes embedded in the source code. They are never rendered in the browser — only developers see them (via “View Page Source” or an editor). Their job: to document, remind, or temporarily disable code without affecting the page.
Syntax
<!-- This is a comment. It will not appear in the browser. -->
- Start with
<!-- - End with
--> - Everything between is ignored by the browser
Exam tip: Comments must be placed inside the HTML file. They do not hide CSS or JavaScript — they only hide the HTML markup they wrap.
Why use comments?
| Purpose | Example |
|---|---|
| Notes & reminders | <!-- TODO: add a contact form later --> |
| Debugging | Temporarily comment out a <li> to see if it causes a layout problem. |
| Documentation | Explain a tricky section: <!-- anchors inside list items make the whole bullet clickable --> |
| Collaboration | Leave instructions for teammates: <!-- Sarah: please check the link target --> |
Worked example (from the lecture)
Original code — a note that shows up in the browser (bad):
<p>For reference: If I add anchor around list item, the entire list item including the bullet point becomes a link</p>
Fix — wrap it in a comment:
<!-- For reference: If I add anchor around list item, the entire list item including the bullet point becomes a link -->
Now it disappears from the rendered page.
VS Code shortcut
- Windows/Linux:
Ctrl + / - Mac:
Cmd + /
Select the line(s) you want to comment/uncomment and press the shortcut.
Key takeaways
- Comments use
<!-- ... -->and are invisible in the browser. - Use them for notes, reminders, debugging (temporarily disable code), and collaboration.
- They do not hide content from users who view the source.
- The editor shortcut (
Ctrl+/orCmd+/) makes toggling comments fast. - Comments keep code clean and help future you (or your team) understand intent.
Inline Comments
Inline elements share horizontal space with other elements, unlike block elements which occupy the full available width of their parent container. This distinction is fundamental to HTML layout and controls how content flows on the page.
Block vs Inline – The Core Difference
A block-level element always starts on a new line and takes up the entire horizontal space available, stretching from left to right. An inline element occupies only the space needed for its content, allowing subsequent elements to sit beside it on the same line.
| Property | Block elements | Inline elements |
|---|---|---|
| Horizontal space | Full width available | Only the width of content |
| Line break before/after | Always starts on a new line | No automatic line break |
| Typical examples | <h1>–<h6>, <p>, <hr>, <div> | <a>, <img>, <span>, <strong> |
| Can contain | Inline elements or other blocks | Only other inline elements (or text) |
Worked example (from demo):
Placing two <h1> elements and an <h2> side by side in code causes each to appear on its own line in the browser because they are blocks. Below them, an <img> and an <a> tag placed consecutively appear on the same line because they are inline.
When inspected in Chrome DevTools, the hover highlight for block elements spans the entire browser width, while the highlight for inline elements only covers the element’s bounding box.
Generic Containers: <div> and <span>
These are neutral, semantically empty elements used purely for grouping and styling.
-
<div>– A generic block container. Wrapping any content inside<div>forces that content onto a new line and causes the div to occupy full width. -
<span>– A generic inline container. It does not change layout; it allows targeting a specific portion of text or inline content without affecting flow.
Example – <div> effect:
Wrapping an anchor tag <a href="...">IIMB link</a> with <div> pushes the link to the next line because the div is a block element.
Example – <span> effect:
Inserting <span> around a word inside a paragraph <p> produces no visual change; the span simply marks that portion for later styling or scripting.
<!-- Block element wrapping inline content -->
<div>
<a href="https://www.iimb.ac.in">IIMB link</a>
</div>
<!-- Span within a paragraph -->
<p>Some sample text. <span>This is the second line.</span></p>
Exam tip: Use
<div>for structural sections (like headers, footers, columns) and<span>when you need to style a small piece of text within a sentence. Mixing them up can break your layout.
Key Takeaways
- Block elements (
<h1>,<p>,<div>,<hr>) occupy the full width and stack vertically. - Inline elements (
<a>,<img>,<span>) sit side‑by‑side and only take the space they need. <div>is a generic block container;<span>is a generic inline container.- Neither
<div>nor<span>has default styling; they are purely structural. - Use Chrome DevTools hover highlighting to quickly identify whether an element is block or inline.
Forms
Forms are HTML elements that collect user input and send it to a server for processing. Every login page, search bar, or checkout flow relies on a form. A form itself is an invisible container – it only renders content through the input elements and labels placed inside it.
The action attribute
The action attribute tells the browser which URL to send the collected data to.
When a form is submitted (e.g., by pressing Enter in a search field), the browser builds a request URL by taking the action URL and appending a query string containing the form data.
- Example from Amazon: the search form has
action="/s"and a text input namedk. Submittinglaptopstakes the browser to/s?k=laptops.
Exam tip: The form’s
actiondoes not need to be a full URL – it can be a relative path. The data is encoded as key=value pairs in the query string (GET method unless specified otherwise).
Common input types
HTML provides many input types, each triggering a specific browser control (text box, color picker, numeric spinner, etc.). Not all types are supported in every browser, but modern browsers handle most consistently.
type attribute | Rendered as | Use case |
|---|---|---|
text | Single-line text box | Username, search term |
email | Text box with email format hint | Email address |
number | Numeric spinner (with up/down arrows) | Age, quantity |
color | Color picker | Favourite colour |
password | Obscured text box | Password input |
submit | Button that submits the form | Form submission (next video) |
The name attribute is essential – it becomes the key in the query string sent to the server. Without a name, the input’s value is not transmitted.
Input attributes
Every input element can carry:
type– specifies the kind of input control.name– the key used when submitting the data (e.g.,username,email).id– a unique identifier for the element, used for linking labels and for CSS/JavaScript.
Labels
A label is a textual description associated with a specific input. Clicking the label automatically focuses or activates the linked input – improving accessibility and usability.
Two ways to associate a label with an input:
-
forattribute – setforto theidof the target input.<label for="username">Enter username</label> <input type="text" id="username" name="username"> -
Wrapping – place the input inside the label tag. No
forneeded.<label>Enter username <input type="text" name="username"> </label>
Both render identically. The for method is more explicit and works even when the label and input are not adjacent in the markup.
Important: The label must be placed near its input in the HTML – they do not magically rearrange. Use <br> or <p> to control vertical layout.
<form action="/submit-form-info">
<label for="username">Enter username</label>
<input type="text" id="username" name="username"><br><br>
<label for="email">Enter your email</label>
<input type="email" id="email" name="email"><br><br>
<label for="age">Mention your age</label>
<input type="number" id="age" name="age"><br><br>
<label for="favcolor">Pick your favourite color</label>
<input type="color" id="favcolor" name="color">
</form>
Form structure diagram
flowchart TD
A[Form element] --> B[action attribute]
A --> C[Input elements]
C --> D[type]
C --> E[name]
C --> F[id]
A --> G[Labels]
G --> H["for = id"]
G --> I["Wrapping input inside label"]
Key takeaways
- A form is a container; nothing is visible until you add inputs.
- The
actionattribute defines where the data is sent (URL or relative path). - Every input should have a
name– without it, the input’s value is not submitted. - Common input types include
text,email,number,color,password, andsubmit. - Labels improve usability; associate them via
for(matching inputid) or by wrapping the input. - Inputs without
nameare invisible to the server – a frequent beginner mistake.
Buttons in HTML Forms
A button is the primary way users interact with a form — submitting data, resetting fields, or triggering custom actions. Intuitively: every click needs a purpose; the type attribute tells the browser what that purpose is.
The button element
Syntax:
<button type="submit|button|reset">Visible Text</button>
The text between the opening and closing tags becomes the button's label. The type attribute controls its default behavior.
Button types and their behavior
type value | Default action | Use case |
|---|---|---|
submit (or omitted) | Submits the form to the URL in the action attribute | Standard form submission |
button | No default action; does nothing by itself | Custom JavaScript-driven actions |
reset | Resets all form fields to their initial values | Clearing a form (not covered in this lecture) |
Important: If type is not specified, the browser defaults to type="submit". This can cause unintended form submissions if a developer forgets to set the type.
Inside vs. outside a form
- Button inside a form – A
submitbutton submits the form it belongs to. Abuttontype button does nothing until JavaScript is attached. - Button outside a form – Even with
type="submit", a button that is not inside any<form>element has no default submit behavior. It exists solely for JavaScript-based actions.
Exam tip: The most common exam trap — a button with no
typeattribute defaults tosubmit, even if the developer intended it to be a plain button. Always explicitly settype="button"to prevent accidental form submission.
Key takeaways
- The
<button>element always requires a closing tag; the text inside is the label. - Default
typeissubmitwhen inside a form. type="button"removes the default submit action — useful for custom JavaScript.- Buttons outside a form never submit anything, regardless of
type. - Understanding button types is essential for controlling form behavior and enabling interactive web applications.
The name Attribute in HTML Forms
Every form input that sends data to a server needs a name attribute. Without it, the user’s input is invisible to the backend.
Intuition: a form is like a delivery slip. The name is the label on the blank (e.g., “email”), and the value is what the user writes in that blank. The server can only read data that has a label.
How form data is sent
When a form is submitted (GET method by default), the browser collects every <input> that has a name attribute and assembles key-value pairs:
<key> = <value>
These pairs are appended to the form’s action URL as a query string, starting with ?, each pair separated by &.
Structure:
action-url?name1=value1&name2=value2&...
Exam tip: The
nameattribute is what appears as the key in the query string. Theidattribute is for CSS/JavaScript — it is not sent to the server.
Worked example
Given this form:
<form action="/submit-form-info">
<input name="username" value="">
<input name="email" value="">
<input name="age" value="">
<input name="color" type="color">
<button type="submit">Submit</button>
</form>
User fills:
- username →
govind - email →
govind.iimb.ac.in - age →
99 - color →
#aabbcc
On submit, browser navigates to:
/submit-form-info?username=govind&email=govind.iimb.ac.in&age=99&color=%23aabbcc
Notice special characters (like #) are URL-encoded (%23).
What happens when name is missing
If an input has no name attribute, its value is never sent in the request.
Example: Remove name="email" from the form above.
Submitted query string:
/submit-form-info?username=govind&age=99&color=%23aabbcc
The email field is completely absent — the server receives no data for that input.
Submission flow
flowchart LR
A[User fills inputs] --> B[Browser collects name=value pairs]
B --> C{Every input has a name?}
C -->|Yes| D[Append to URL as query string]
C -->|No| E[Missing inputs are skipped]
D --> F[Server reads keys to process data]
Why backend developers care
Server-side code (PHP, Python, Node.js, etc.) references form data by the name value. If the name is missing or misspelled, the server cannot retrieve that piece of data.
name present | Data sent to server | Server can process |
|---|---|---|
| Yes | Yes | Yes |
| No | No | No |
Key takeaways
- The
nameattribute labels an input’s value as a key in the key‑value pair sent to the server. - Form data is transmitted via the query string (in GET) as
?key1=value1&key2=value2. - Inputs without a
nameattribute are omitted from the request. - Every input that should be processed by the backend must have a unique, meaningful
name. - Special characters in values are URL‑encoded automatically.
Forms: Building a Registration Form
HTML forms allow users to input data and send it to a server. Intuitively, think of a form as a container that collects information (e.g., name, email) and packages it into key=value pairs appended to the URL (or sent via POST). Every input field needs a name (the key) and a value (the user’s entry or a fixed option) to be transmitted.
Form Structure
The <form> element defines the container. Two key attributes:
action– the URL where data is sent (here"/register"placeholder).method–GET(default, seen in URL) orPOST(not shown, but implied).
Inside the form, each input is paired with a <label> for accessibility. The label’s for attribute matches the input’s id.
<form action="/register">
<!-- inputs and button go here -->
<button type="submit">Register</button>
</form>
Exam tip: A form with only a submit button and no inputs does nothing – data must come from named input elements.
Text Input & Validation: type="text", required, minlength, maxlength
Collect a participant’s name using a text input. Use required (Boolean attribute) to prevent submission when empty. Enforce length with minlength and maxlength.
<label for="name">Enter your name</label>
<input type="text" id="name" name="name" required minlength="2" maxlength="12">
required– browser shows a popup: “Please fill out this field”.minlength="2"– “Please lengthen this text to 2 characters or more”.maxlength="12"– prevents typing beyond 12 characters.- Validation is client-side (browser built-in); appearance varies by browser.
Email Input: type="email"
For capturing participant email addresses that must contain an @ symbol. The type="email" attribute invokes built-in email validation.
<label for="email">Enter your email</label>
<input type="email" id="email" name="email">
- Submitting
govi(no@) → “Please include an '@' in the email address.” - On valid submission, the
@is URL-encoded as%40.
Dropdown (Select) Menu: <select> + <option>
Use a dropdown to limit T‑shirt size choices. The <select> element’s name attribute becomes the key; each <option> has a value sent as the value.
<label for="tshirt-size">Select t-shirt size</label>
<select id="tshirt-size" name="tshirt-size">
<option value="">Please select an option</option>
<option value="38">38</option>
<option value="40">40</option>
<option value="42">42</option>
<option value="44">44</option>
</select>
- Options render in the order written in the HTML.
- If
<option>lacks avalueattribute, nothing is submitted for that choice. - The
nameof the<select>is the key; thevalueof the chosen<option>is the value.
Checkbox: type="checkbox"
Use a checkbox to obtain agreement (e.g., to fest rules). To make it mandatory, add required.
<label for="terms">Do you agree to all conditions?</label>
<input type="checkbox" id="terms" name="terms" value="agreed" required>
- Unchecked: the
namekey is omitted entirely from the submission. - Checked: sends
terms=agreed(ifvalueis set) orterms=on(default). - With
required, browser prevents submission until the box is ticked.
Radio Buttons: type="radio"
Allow mutually exclusive selection, e.g., “Student” vs. “Alumni”. All radio buttons in the same group must share the same name attribute. Provide explicit value attributes to send meaningful data.
<label for="alumni">Alumni</label>
<input type="radio" id="alumni" name="attendee-type" value="alumni">
<label for="student">Student</label>
<input type="radio" id="student" name="attendee-type" value="student">
- Same
nameensures only one radio can be selected at a time. - If
valueis missing, the sent value ison(unhelpful). - The
forlabel linkage allows clicking the label to select the radio.
How the Submission URL Works (GET method)
When the form is submitted via GET, all key=value pairs are appended to the action URL:
/register?name=Govind&email=govind%40gmail.com&tshirt-size=42&terms=agreed&attendee-type=alumni
- Keys come from the
nameattribute of each input/select. - Values come from the
valueattribute (or user typed text for text/email). @is encoded as%40.- Unchecked checkboxes and unselected radio buttons do not appear.
flowchart LR
A[User fills form] --> B{Client-side validation}
B -->|Fail| C[Browser shows error]
B -->|Pass| D[Form submitted]
D --> E[Data appended to URL as key=value]
E --> F[Server receives data]
Exam tip: The
nameattribute is essential – without it, the input’s data is never sent. For checkboxes and radios, always provide a meaningfulvalueattribute.
Worked Example: Complete Registration Form
<form action="/register">
<!-- Name -->
<label for="name">Enter your name</label>
<input type="text" id="name" name="name" required minlength="2" maxlength="12">
<br><br>
<!-- Email -->
<label for="email">Enter your email</label>
<input type="email" id="email" name="email">
<br><br>
<!-- T-shirt size dropdown -->
<label for="tshirt-size">Select t-shirt size</label>
<select id="tshirt-size" name="tshirt-size">
<option value="">Please select</option>
<option value="38">38</option>
<option value="40">40</option>
<option value="42">42</option>
<option value="44">44</option>
</select>
<br><br>
<!-- Checkbox -->
<input type="checkbox" id="terms" name="terms" value="agreed" required>
<label for="terms">Do you agree to all conditions?</label>
<br><br>
<!-- Radio buttons -->
<input type="radio" id="alumni" name="attendee-type" value="alumni">
<label for="alumni">Alumni</label>
<input type="radio" id="student" name="attendee-type" value="student">
<label for="student">Student</label>
<br><br>
<button type="submit">Register</button>
</form>
Submission sample (if alumni selected):
/register?name=Govind&email=govind%40iimb.ac.in&tshirt-size=42&terms=agreed&attendee-type=alumni
Key takeaways
- A form sends data as key=value pairs; keys come from
nameattributes, values from user input orvalueattributes. required,minlength,maxlength, and type‑specific validation (email, number) provide client‑side checks.- Use
<select>with<option>for dropdowns; thevalueattribute determines what is sent. - Checkboxes send nothing when unchecked; use
requiredto force agreement. - Radio buttons with the same
nameenforce single selection; always set avaluefor each. - Labels linked by
for(matchingid) improve usability and accessibility.
HTML Tables
HTML tables organise data into rows and columns — like a spreadsheet in the browser. Use them whenever you need to display tabular data: product comparisons, statistics, schedules.
Crucial rule: tables are for data, not for page layout (use CSS for layout).
Table Structure
Every table is built from three core elements nested in a strict hierarchy:
flowchart TD
A[`<table>`] --> B[`<tr>` (row)]
B --> C[`<th>` header cell or `<td>` data cell]
B --> D[more cells]
A --> E[more `<tr>` rows]
<table>— the container.<tr>— a table row. Rows are stacked vertically.<td>— a data cell.<th>— a header cell (automatically bold and centred; semantically marks a row/column heading).
Browsers often auto-insert <tbody> around data rows, but you do not need to write it explicitly.
Exam tip: Always use
<th>for headers — this is both semantic and helps accessibility. Never style a<td>to look like a header.
Basic Table (no spanning)
| Name | Height (cm) | Height (in) |
|---|---|---|
| Raja | 180 | 73.5 |
| Ram | 165 | 67.5 |
| Mohan | 172 | 70.0 |
<table>
<tr>
<th>Name</th>
<th>Height (cm)</th>
<th>Height (in)</th>
</tr>
<tr>
<td>Raja</td>
<td>180</td>
<td>73.5</td>
</tr>
<tr>
<td>Ram</td>
<td>165</td>
<td>67.5</td>
</tr>
<tr>
<td>Mohan</td>
<td>172</td>
<td>70.0</td>
</tr>
</table>
Each <tr> contains the same number of cells. Header row uses <th>, data rows use <td>.
Spanning Cells: rowspan and colspan
Sometimes a cell needs to stretch across multiple rows or columns — exactly like merging cells in Excel.
| Name | Height | |
|---|---|---|
| in cm | in inches | |
| Raja | 180 | 73.5 |
| Ram | 165 | 67.5 |
| Mohan | 172 | 70.0 |
colspan="n"— cell spansncolumns horizontally.rowspan="n"— cell spansnrows vertically.
Code for the table above:
<table>
<tr>
<th rowspan="2">Name</th>
<th colspan="2">Height</th>
</tr>
<tr>
<th>in cm</th>
<th>in inches</th>
</tr>
<tr>
<td>Raja</td>
<td>180</td>
<td>73.5</td>
</tr>
<tr>
<td>Ram</td>
<td>165</td>
<td>67.5</td>
</tr>
<tr>
<td>Mohan</td>
<td>172</td>
<td>70.0</td>
</tr>
</table>
When you use rowspan or colspan, omit the cells that would have been in the merged area. The total number of logical columns per row must stay consistent.
Exam tip: Count columns carefully. In the example above, the first row has 2 cells (
rowspan+colspan), the second row has 2 cells (both<th>), and each data row has 3<td>— but because the first cell of each data row is already occupied by therowspanfrom row 1, you only write<td>twice per data row. Mistaking the count is a common error.
Real‑World Example: IIMB Fest Event Schedule
Add a schedule table to the IIMB Fest website (below the forms, separated by <hr>):
<h2>Event Schedule</h2>
<table>
<tr>
<th>Timings</th>
<th>Event</th>
<th>Venue</th>
</tr>
<tr>
<td>9:00 AM</td>
<td>Opening Ceremony</td>
<td>Main Auditorium</td>
</tr>
<tr>
<td>10:00 AM</td>
<td>Panel Discussion</td>
<td>Seminar Hall</td>
</tr>
<tr>
<td>12:00 PM</td>
<td>Lunch</td>
<td>Cafeteria</td>
</tr>
<tr>
<td>2:00 PM</td>
<td>Cultural Activities</td>
<td>Amphi Theater</td>
</tr>
</table>
| Timings | Event | Venue |
|---|---|---|
| 9:00 AM | Opening Ceremony | Main Auditorium |
| 10:00 AM | Panel Discussion | Seminar Hall |
| 12:00 PM | Lunch | Cafeteria |
| 2:00 PM | Cultural Activities | Amphi Theater |
Key Takeaways
- Tables are built from
<table>,<tr>,<td>(data), and<th>(headers). - Rows are defined with
<tr>; cells go inside rows. - Use
rowspanto merge cells vertically andcolspanto merge horizontally. - Tables are for tabular data only — never use them for page layout.
- Always include proper header cells (
<th>) for accessibility and clarity. - Styling (borders, colours, spacing) is done with CSS, not HTML.
Semantic HTML
Semantic HTML uses meaningful tags that describe the purpose of content, not just its appearance. Instead of generic containers like <div> or <span>, you use tags such as <header>, <footer>, <main>, <section>, <nav>, <article>, and <form>. These make the structure of a webpage clear to browsers, developers, search engines, and assistive technologies.
Why semantic HTML matters
| Benefit | Explanation |
|---|---|
| Accessibility | Screen readers and assistive tech can interpret content better — e.g., a <nav> tells the reader "this is a navigation region". |
| SEO | Search engines give more weight to content inside semantic tags (e.g., <h1> for the top heading) and index pages more effectively. |
| Code maintainability | Developers instantly understand what each block is supposed to do — finding, updating, and collaborating becomes much easier. |
Semantic vs. non-semantic HTML
| Non-semantic | Semantic | Purpose |
|---|---|---|
<div> | <header>, <footer>, <section>, <nav>, <main>, <article> | Defines a structural region |
<span> | <em>, <strong>, <time>, <summary> | Adds inline meaning |
Definition – semantic in programming: the meaning of a piece of code.
In HTML, an <h1> element is semantic because it tells the browser (and screen reader) that the wrapped text is the top-level heading.
Key semantic elements
| Element | Typical use |
|---|---|
<header> | Top of a page/ section — logo, main heading, introductory navigation; consistent across pages |
<nav> | A block of navigation links (e.g., <a> links to other pages) |
<main> | The primary content of the page (should appear only once) |
<section> | Groups related content into logical, reusable blocks |
<article> | A self-contained composition (e.g., a blog post, news item) |
<footer> | Bottom of a page/ section — author info, copyright, links |
<form> | Groups form inputs (already semantic itself) |
<time> | Represents a date or time in a machine-readable way |
Transforming the IIMB Fest page
Walkthrough of adding semantic tags to the example webpage (IIMB Fest). The result has no visual change — all improvements are in the underlying code structure.
Step 1: Wrap top content in <header>
<header>
<img src="..." alt="IIMB Logo">
<h1>IIMB Fest</h1>
<p>Welcome to the annual fest...</p>
</header>
- The three top elements (image, main heading, introductory paragraph) become one logical unit.
Step 2: Wrap primary content in <main>
<main>
<!-- all sections from first <h2> to table end -->
</main>
<main>explicitly marks the central content of the page; only one<main>per page.
Step 3: Split main content into <section>s
Logical grouping:
| Section | Content |
|---|---|
| Section 1 | Instructions (heading + ordered list) |
| Section 2 | Directions (heading + unordered list) |
| Section 3 | Registration form (heading + <form>) |
| Section 4 | Event schedule (heading + <table>) |
<main>
<section>
<h2>Instructions</h2>
<ol>...</ol>
</section>
<hr>
<section>
<h2>Directions</h2>
<ul>...</ul>
</section>
<section>
<h2>Registration</h2>
<form>...</form>
</section>
<section>
<h2>Event Schedule</h2>
<table>...</table>
</section>
</main>
- Sections make code easier to read and reuse; each has a distinct heading.
Step 4: Add semantic table elements
Replace the plain <table> with structure:
<table>
<thead> <!-- group header row -->
<tr>
<th>Event</th>
<th>Date</th>
<th>Time</th>
</tr>
</thead>
<tbody> <!-- group main data rows -->
<tr><td>Inauguration</td><td>Oct 10</td><td>10:00</td></tr>
<tr><td>Workshop</td><td>Oct 11</td><td>09:00</td></tr>
<tr><td>Concert</td><td>Oct 12</td><td>19:00</td></tr>
<tr><td>Closing</td><td>Oct 13</td><td>17:00</td></tr>
</tbody>
<!-- <tfoot> can be added for summary rows -->
</table>
<thead>– row(s) that act as column headers.<tbody>– the main data.<tfoot>– optional footer (e.g., totals, notes).
Exam tip: Semantic table elements (
<thead>,<tbody>,<tfoot>) improve accessibility and are frequently tested. The browser still renders the same visual table, but screen readers can announce header cells properly.
Final structure diagram
flowchart TD
body[<body>] --> header[<header>]
body --> main[<main>]
main --> section1[<section> - Instructions]
main --> section2[<section> - Directions]
main --> section3[<section> - Registration]
main --> section4[<section> - Event Schedule]
section4 --> table[<table>]
table --> thead[<thead>]
table --> tbody[<tbody>]
- No visual change – only code structure improvements.
Key takeaways
- Semantic HTML uses meaningful tags (
<header>,<main>,<section>, etc.) instead of generic<div>. - Benefits: accessibility (screen readers), SEO (better indexing), and code maintainability.
- Common semantic elements:
<header>,<nav>,<main>,<section>,<article>,<footer>,<form>,<time>. - Tables have semantic children:
<thead>(header row),<tbody>(data rows),<tfoot>(footer row). - Adding semantics improves the meaning of the page without changing its appearance.
File Paths
File paths are the addresses that tell a web browser or program where a file (image, CSS, HTML, etc.) lives inside a project. There are two styles: absolute paths (full route from the root) and relative paths (route from the current working file).
Intuition: Directions to a location
- Absolute path – start from the root (e.g., “India” → Karnataka → Bangalore → Bannerghatta Road → IIM Bangalore). Unchanging, works from anywhere.
- Relative path – start from your current location. If you are already in Bangalore: “Bannerghatta Road → IIM Bangalore”. If in Chennai: “Go from Chennai to Bangalore → Bannerghatta Road → IIM Bangalore”. Shorter, flexible.
Absolute vs. Relative Paths
| Attribute | Absolute Path | Relative Path |
|---|---|---|
| Starts from | Root of filesystem (e.g., C:\ on Windows, / on Mac/Linux) | Current file’s directory |
| Example | C:\Users\Desktop\project\image.jpg | ./image.jpg or ../parent-folder/image.jpg |
| Dependency on machine | Tied to one machine’s folder structure | Portable across machines |
| Length | Long, includes full hierarchy | Short, only necessary segments |
| Use in web hosting | May break because server root differs | Works both locally and on any server |
Syntax of Relative Paths
| Special Characters | Meaning | Example |
|---|---|---|
. (single dot) | Current directory | ./image.jpg → file in same folder as the HTML file |
.. (double dots) | Parent directory (one level up) | ../folder/image.jpg → one folder up, then into folder/ |
| No prefix | Also means current directory (but explicit ./ is clearer) | image.jpg works like ./image.jpg |
Worked Example: Referencing images in a project
Given the folder structure:
Desktop/
├── folder-in-parent/
│ └── image-one.jpg
└── website-development/ ← (project folder)
├── 3.17-file-paths.html ← (current file)
├── same-folder-image.jpg
└── images/
└── sub-folder-image.webp
| Target File | Relative Path (from HTML file) | Absolute Path (Windows example) |
|---|---|---|
same-folder-image.jpg | ./same-folder-image.jpg | C:\Users\...\website-development\same-folder-image.jpg |
sub-folder-image.webp | ./images/sub-folder-image.webp | C:\Users\...\website-development\images\sub-folder-image.webp |
image-one.jpg (in parent) | ../folder-in-parent/image-one.jpg | C:\Users\...\Desktop\folder-in-parent\image-one.jpg |
Exam tip: In HTML,
<img src="...">with a relative path is recommended over absolute because it keeps the project portable. Live servers often block access to files outside the project root; absolute paths may fail.
Why the parent-folder image didn’t render in VS Code’s live server?
Live servers (e.g., VS Code’s) restrict access to files outside the project directory for security. The relative path ../ breaks because the server’s root is the project folder, not the desktop. Opening the HTML file directly from the file system (double-click) bypasses this restriction.
Why relative paths are recommended
- Portability – Share the project folder; everyone can use the same paths regardless of their machine’s root structure.
- Flexibility – If the whole project is moved from
Desktop/toDocuments/, relative paths still work (absolute paths would break). - Simplicity – Short, no need to type the full
C:\...for every file. - Web hosting – Relative paths adapt to the server’s root; absolute paths tied to a local drive will not.
Exam tip: The only time you may need an absolute path is when linking external resources from a different domain (URLs like
https://example.com/image.jpg). For local project files, always use relative paths.
Key takeaways
- Absolute path – starts from filesystem root, universal but brittle.
- Relative path – starts from current file, uses
.for current directory and..for parent. - Relative paths are portable, flexible, and server-friendly.
- In live server environments,
..may not be allowed to go above the project root. - Stick to relative paths for all local file references in your HTML.
Multi-Page Websites & Navigation
A multi-page website consists of several HTML files, each serving a distinct purpose (e.g., homepage, events, registration). This replaces the single-page approach used in small projects. Real-world sites like Amazon or Wikipedia use multiple pages to organize content effectively.
Why multi-page?
- Improves content organization (each page has a clear role).
- Enhances user experience (users navigate to relevant pages).
- Essential for professional, scalable websites.
Folder Structure & Relative Paths
All pages are stored in a single folder (or nested sub-folders). Resources (images, videos) are placed in sub-folders (e.g., images/). Relative file paths link pages and resources.
| Path pattern | Meaning | Example |
|---|---|---|
./ | Current folder | ./events.html |
images/filename.jpg | Sub-folder within current | images/dj.jpg |
../ | Parent folder (not used here) | — |
Exam tip: Relative paths keep links functional even when the site is hosted elsewhere. Avoid absolute paths like
C:\...for deployment.
Creating Pages (Home, Events, Register)
- Create a project folder (e.g.,
final-website-multipage/). - Create three HTML files:
home.html,events.html,register.html. - Use the same base HTML (from previous lectures on semantics) for all pages, then remove sections not needed for that page.
Worked example:
- Start with the semantic HTML template from the previous video (header, main with sections, footer).
- For
home.html: keep header, directions/introduction; remove event schedule and registration form. - For
events.html: keep header and event schedule section; remove directions and registration. - For
register.html: keep header and registration form; remove everything else. - Rename
<title>per page: “IIMB Fest – Home”, “IIMB Event Details”, “IIMB – Register”.
Result: three clean, focused web pages that share a consistent header design.
Linking Pages with Anchor Tags
The <a> element (anchor tag) creates clickable links. The href attribute specifies the target page using a relative path.
<a href="./events.html">Click here to see events</a>
<a href="./register.html">Click here to register</a>
- The dot-slash
./explicitly states “same folder as the current page”.
Place these links inside a <nav> element (semantic tag for navigation blocks) within the <header> for consistency.
Navigation flow (conceptual):
flowchart LR
A[home.html] -- a href="./events.html" --> B[events.html]
A -- a href="./register.html" --> C[register.html]
B -- a href="./home.html" --> A
C -- a href="./home.html" --> A
Each page should include a “back to homepage” link so users can return easily.
Navigation Consistency
- Reuse the same header (and footer) across all pages to maintain visual cohesion.
- Place navigation in the same location (inside
<header>) on every page. - Use
<nav>for semantic clarity – it has no visual effect but improves accessibility and code structure.
Exam tip: Navigation must be present on every page, and links should always be functional (check relative paths). A common exam question: “Why did the image not load on the homepage?” → Answer: the relative path to the image folder was wrong (e.g., missing
images/sub-folder).
Key Takeaways
- Multi-page websites group content into separate HTML files for better organization.
- Relative paths (
./filename.html) link pages; resources like images need correct sub-folder references. - Anchor tags
<a href="...">enable navigation; wrap them in<nav>for semantics. - Remove irrelevant sections from each page to avoid duplication while keeping headers/footers the same.
- Always provide a “back to homepage” link on every sub-page.
Hosting Website
Web hosting is the process of making a website accessible to anyone anywhere on the internet. Until hosted, the site exists only on the local computer. Hosting uploads the site's files to a web server – a special computer connected to the internet 24/7. Once hosted, anyone in the world can view it.
Why host?
- Public availability – share with friends, family, or potential employers.
- Accessibility – site is live and can be viewed anytime.
- Impressive – showcases your skills by having a live project.
Pre‑hosting Checklist
| Task | Reason |
|---|---|
| All website files in one folder | Keeps structure clean; required by hosting platforms. |
| Required resources (images, CSS, etc.) inside that same folder | Relative links will work correctly. |
Rename home page to index.html | index.html is the standard name for the main homepage; GitHub (and most servers) expects this file to display the site root. |
Exam tip: Forgetting to rename
home.htmltoindex.htmlis the most common reason GitHub Pages fails to show a site. Always do this before uploading.
After renaming, update any internal links that pointed to the old filename. In the transcript example:
home.htmlbecomesindex.html→ update links inevents.htmlandregister.htmlto redirect back toindex.html.
Hosting with GitHub Pages (step‑by‑step)
GitHub Pages is a free hosting service. The process is:
flowchart TD
A[Create a GitHub account] --> B[Create a new repository]
B --> C[Set repository to PUBLIC]
C --> D[Upload files – not the folder itself]
D --> E[Commit to main branch]
E --> F[Settings > Pages > select main branch /root]
F --> G[Wait 2–3 minutes for deployment]
G --> H[Site live at username.github.io/repo-name]
Detailed steps:
- Log in to GitHub (or create an account).
- Create a new repository – give it a name (e.g.,
IIMB-Fest-website-demo).- Add an optional description.
- Choose Public – free hosting requires public repositories.
- Optionally add a README file (not required).
- Upload files:
- Click Add file → Upload files.
- Important: Do not upload the parent folder. Navigate inside your project folder and upload only the individual files (including
index.htmland theimagessubfolder). - This ensures
index.htmlis at the root of the repository.
- Commit changes – enter a message (e.g., “upload first time”) and commit directly to the
mainbranch. - Enable GitHub Pages:
- Go to Settings → Pages.
- Under Branch, select
mainand leave the folder as/ (root). - Click Save.
- Wait 2–3 minutes – GitHub deploys the site. A green banner will appear with the live URL:
https://<username>.github.io/<repository-name>/.
Exam tip: The URL pattern is always
username.github.io/repo-name. If you see a 404, double‑check thatindex.htmlexists at the root of the repository and that the repository is set to Public.
The final live site will function exactly as it did locally: all internal links and images work because the file structure was preserved.
Key takeaways
- Web hosting makes a site publicly accessible via a web server.
- Rename the main page to
index.htmland update all cross‑references. - Use GitHub Pages for free hosting – repository must be Public.
- Upload the files themselves (not the enclosing folder) so
index.htmlsits at the repo root. - After setting
mainbranch in Settings → Pages, wait ~2–3 minutes for deployment. - The live URL follows the pattern
username.github.io/repo-name.
Resume Website Project
This assignment is your first real-world HTML build: a personal resume website. Its purpose is to apply everything you’ve learned about HTML to create a live, shareable page that tells your professional story. The focus is on planning, meaningful structure, and deployment.
Plan Before You Code
A good website starts with a clear objective. Ask yourself:
- What story do you want to tell? (skills, career goals, personality)
- What sections matter most? (experience, projects, hobbies)
- How will you make it visually appealing and impactful? (layout, content)
Sketch a design plan: decide the layout, section ordering, and content preparation. Good planning is the foundation.
flowchart LR
A[Define your story] --> B[Sketch layout & sections]
B --> C[Prepare content & assets]
C --> D[Code HTML]
D --> E[Deploy to GitHub Pages]
E --> F[Share link]
Required Sections – Minimum Content
Your resume website must include:
| Section | Description |
|---|---|
| Header | Your name and a tagline (e.g., “Web Developer & Designer”) |
| Photo | A picture – “a picture speaks louder than words” |
| Summary / Objective | Describes you and your career goals |
| Work Experience | List each job: company name, job title, duration, key responsibilities/achievements |
| Education | Schools attended, degrees obtained, graduation dates |
| Projects | Cool things you’ve built (even class assignments). For each: title, brief description, technologies/tools used |
| Hobbies / Extracurricular | Optional but encouraged |
Use Semantic HTML
Make your code meaningful. Use the following tags to structure your page:
<header>– for the page header (name + tagline)<section>– to organize each major part (experience, education, etc.)<footer>– for closing notes<article>– for individual job entries or projects (self-contained content)
Exam tip: Semantic tags improve accessibility, SEO, and maintainability. They are a high-yield concept in any HTML assessment.
Go Beyond – Experiment and Extend
- Explore the MDN Web Docs for new tags you haven’t seen in class. (e.g.,
<figure>,<time>,<address>) - Multi-page website: Create a separate page for projects or contact details. Use a
<nav>bar to link pages. - Tables for structured data: e.g., a skills table or a certifications table. Tables add clarity to tabular information (languages, tools, certificates).
Deploy on GitHub Pages
Your resume must be live on the web.
- Host the site using GitHub Pages (as demonstrated in earlier videos).
- Once live, share the link with your instructor/class.
There is no single right way to do this – your website should reflect you: your interests, achievements, and story.
Key takeaways
- Plan your story, layout, and content before coding.
- Required sections: header + tagline, photo, summary/objective, work experience, education, projects, (optional) hobbies.
- Use semantic elements (
<header>,<section>,<article>,<footer>). - Enhance with multi-page, tables, and new tags from MDN.
- Deploy via GitHub Pages and share the link.
Introduction to CSS and Styling
Introduction to CSS
CSS (Cascading Style Sheets) brings a website to life with visual appearance. If HTML is the skeleton of a page, CSS adds the “skin” – colors, fonts, spacing, layout, and overall style. It separates content (HTML) from presentation (how it looks), making code cleaner, maintainable, and scalable.
What “Cascading Style Sheets” means
- Style sheets – A set of rules that define how elements on a webpage should look. Each rule specifies properties (e.g., color, font size, margin) and their values.
- Cascading – Like a waterfall flowing from top to bottom, styles are applied in layers, from the most general to the most specific rules. The cascade determines which rule wins when multiple rules target the same element. (Detailed coverage in a later video.)
The syntax of a CSS rule
A CSS rule consists of a selector and a declaration block:
selector {
property: value;
}
| Part | Role | Example |
|---|---|---|
| Selector | Targets which HTML element(s) to style | h1 |
| Property | The visual characteristic to change | color |
| Value | The specific setting for that property | purple |
Example – The following rule turns the text of every
<h1>element purple:h1 { color: purple; }This is the simplest form; later modules will introduce more powerful selectors and properties.
Why CSS matters
- Without CSS, a webpage is functional but bland – like a colouring book with no colours.
- Early web developers used HTML tags (e.g.,
<font>) for styling, which cluttered code and made large projects unmanageable. - CSS was born in 1996 as a dedicated solution to separate style from structure, enabling efficient, scalable design.
What CSS can do
Think of CSS as adjectives that describe HTML nouns. HTML says “here’s a button”; CSS says “this is a purple, large, rounded button”. Core capabilities covered in this module:
- Selectors – pinpoint any element (or group of elements) on a page.
- Properties – change colours, fonts, sizes, backgrounds, borders, margins, padding, and more.
- The Box Model – how margins, borders, padding, and content combine to form layout.
- Positioning & Alignment – control where elements sit on the screen.
Exam tip: “Cascading” is a key exam concept. Remember: general rules (e.g., body) apply first, then more specific rules (e.g., h1) override them. The cascade answers “which style wins?”.
What’s coming (Modules 4 & 5)
- Module 4: Selectors, basic styling, box model, layout, positioning.
- Module 5: Animations, transitions, responsive design (making pages adjust to different screen sizes).
Key takeaways
- CSS = Cascading Style Sheets – separates content from presentation.
- A rule has a selector and a
{ property: value; }block. - The cascade resolves conflicting styles by order of specificity and source.
- CSS was introduced in 1996 to replace messy HTML styling.
- It controls colours, fonts, spacing, layout, and much more – turning HTML “bones” into polished websites.
Ways to Add CSS to HTML
CSS (Cascading Style Sheets) is applied to HTML documents through three distinct methods. Each serves a different purpose and is chosen based on project scale, reusability, and workflow. The three methods are inline CSS, internal CSS, and external CSS.
Inline CSS
Inline CSS applies styles directly to a single HTML element using the style attribute. The style attribute is a global attribute – it can be added to any opening HTML tag. Inside, you write property–value pairs (e.g., color: blue). This method is quick for testing or making small, one‑off adjustments.
<h1 style="color: blue;">This is the heading</h1>
- Targets only the specific element it is placed on.
- Not reusable – if the same style is needed elsewhere, it must be repeated.
- Best reserved for prototyping, debugging, or overriding other styles temporarily.
Internal CSS
Internal CSS places all styles inside a <style> tag in the <head> section of the HTML file. The CSS rules target elements by selectors (e.g., p for all paragraph elements) and apply consistently across the entire page.
<head>
<style>
p {
color: green;
}
</style>
</head>
- All
<p>elements on the page will have green text. - Keeps styles in the same file but separates them from content.
- Ideal for single‑page websites where no external file is needed.
External CSS
External CSS separates styles into a dedicated .css file. This file is linked to the HTML using a <link> tag in the <head>. The rel attribute must be "stylesheet", and the href attribute points to the file’s path.
<head>
<link rel="stylesheet" href="style.css">
</head>
Contents of style.css:
h2 {
color: red;
}
- Most scalable method – the same
.cssfile can be reused across multiple pages. - Changes in one file update the entire site’s appearance.
- Separates structure (HTML) from presentation (CSS), making code cleaner and easier to maintain.
Comparison & Decision Guide
| Method | Where styles are written | Scope | Use when |
|---|---|---|---|
| Inline | style attribute of an element | Single element | Quick test, one‑off tweak |
| Internal | <style> in <head> | One HTML page | Single‑page site, all styles local |
| External | Separate .css file | Any page that links the file | Multi‑page sites, reusability |
flowchart LR
A[Need to style HTML?] --> B{How many pages?}
B -->|One page, small| C[Internal CSS]
B -->|Multiple pages| D[External CSS]
B -->|One element only| E[Inline CSS]
Exam tip: Inline CSS has the highest specificity – it overrides both internal and external rules for the same property on the same element. However, it is the least maintainable.
Key takeaways
- Three methods: inline (via
style), internal (<style>in<head>), external (.cssfile linked with<link>). - Inline = fastest for a single element, but zero reusability.
- Internal = good for a single page, keeps styles inside the HTML file.
- External = industry standard for multi‑page sites; separates concerns and enables reuse.
- The
<link>tag requiresrel="stylesheet"andhrefpointing to the.cssfile. - Use the appropriate method based on project size and style reusability needs.
Syntax and Selectors
CSS syntax is the formal structure of every CSS rule. It tells the browser which HTML element to style and how to style it. The fundamental pattern:
selector {
property: value;
}
- Selector – identifies the HTML element(s) to style (e.g.,
h2). - Curly braces
{ }– enclose all style declarations for that selector. - Property – the aspect you want to change (e.g.,
color,font-size). - Value – the setting you assign to the property (e.g.,
red,16px). - Semicolon – separates multiple property–value pairs inside the same braces.
Multiple declarations can be added for one selector:
h2 {
color: red;
background-color: green;
}
Exam tip: Every declaration must end with a semicolon. Missing it causes the next rule to fail – a common rookie mistake.
Selector Types
Selectors are how CSS “talks to” HTML. Each type has a specific syntax and use case.
| Selector | Syntax | Targets | Example |
|---|---|---|---|
| Element | tagname | All elements of that tag | p { color: green; } |
| Class | .classname | All elements with that class attribute | .orange { color: orange; } |
| ID | #idname | The single element with that id attribute | #main { color: blue; } |
| Universal | * | Every element in the document | * { margin: 0; } |
| Attribute | element[attribute] or element[attribute="value"] | Elements with a specific attribute (or value) | input[type="text"] { border: 1px solid black; } |
Element Selector
The simplest: write the tag name. It selects all instances of that tag.
h2 {
background-color: green;
}
<h2>Second heading</h2> <!-- styled -->
<p>Sample text</p> <!-- not styled by h2 -->
Class Selector
The class attribute is a global HTML attribute that groups elements together for shared styling. Class names are reusable across different tag types.
CSS syntax: a dot (.) followed by the class name.
<p class="orange">This is orange</p>
<p class="orange">Another orange paragraph</p>
.orange {
color: orange;
font-weight: bold;
}
All elements with class="orange" (regardless of tag) receive the styles.
ID Selector
The id attribute must be unique within a document – it identifies a single element.
CSS syntax: a hash (#) followed by the ID value.
<h1 id="main-element">First heading</h1>
#main-element {
color: blue;
text-align: center;
}
Exam tip: IDs are one-of-a-kind. Using the same ID twice is invalid HTML and may cause unpredictable styling.
Universal Selector
* applies styles to every element. Useful for resetting default browser margins/paddings.
* {
margin: 0;
padding: 0;
}
The universal selector overrides default spacing for all elements (though it can be affected by later, more specific rules – that’s the cascade, covered in another lesson).
Attribute Selector
Targets elements based on the presence of an attribute, or the exact value of that attribute.
| Syntax | Meaning |
|---|---|
element[attr] | Element has the attribute (any value) |
element[attr="value"] | Element has attribute with that exact value |
Example – target by attribute value:
<input type="text" placeholder="Do not enter your name">
<input type="email" placeholder="Enter your email">
input[type="text"] {
border: 5px solid darkmagenta;
}
Only the text input gets the purple border.
Example – target by attribute presence (any value):
<button draggable="true">Click me</button>
button[draggable] {
color: pink;
}
The button is styled because it has the draggable attribute, regardless of its value.
When to Use Class vs. ID
- Class – for reusable styles that apply to multiple elements (teams).
- ID – for a single, unique element (individual).
flowchart LR
A[Need to style multiple elements?] -->|Yes| B[Use class]
A -->|No, one unique element| C[Use ID]
Exam tip: Class selectors are more flexible and recommended for most styling. Reserve IDs for JavaScript hooks or very specific, one-off styling.
Key Takeaways
- CSS syntax:
selector { property: value; }– every declaration ends with a semicolon. - Element selector – targets all elements of a given tag.
- Class selector (
.name) – targets any element with that class attribute; reusable. - ID selector (
#name) – targets a single unique element. - Universal selector (
*) – targets every element; great for resets. - Attribute selector (
[attr]or[attr="val"]) – targets elements by attribute presence or exact value. - Use classes for reusable groups, IDs for unique elements.
Tools and References
CSS is vast — there are dozens of properties just for text (e.g., letter-spacing, line-height, text-transform) and many ways to achieve the same visual effect (e.g., multiple border properties). The goal is not to memorise everything, but to understand the fundamentals and know where to find answers.
Key Resources
| Resource | What it provides | How to use it |
|---|---|---|
| MDN Web Docs (Mozilla Developer Network) | Detailed explanations for every CSS property, with code examples and rendered previews | Search for any property (e.g., box-shadow) and read the complete reference |
| Google (or any search engine) | Quick answers for specific problems, tutorials, and videos | Search phrases like "CSS rounded corners" to find step‑by‑step guides |
| Online CSS generators (e.g., color pickers) | Pre‑written CSS code for common effects (colours, gradients, shadows) | Pick colours, copy the generated rule, and paste into your stylesheet |
Workflow: How to approach a CSS problem
flowchart LR
A[Understand CSS fundamentals] --> B[Stuck on a style?]
B --> C{Know the property?}
C -->|Yes| D[Write it directly]
C -->|No| E[Search MDN or Google]
E --> F[Experiment with examples]
F --> D
B --> G[Use online generator for quick code]
G --> D
D --> H[Build and test]
Exam tip: Interviewers or exams rarely test rote recall of property names. Instead, they assess your ability to find the right property and apply it correctly. Become fluent with MDN’s CSS reference — it’s your primary cheat sheet.
Practical Advice
- Master the basics: Syntax, selectors, the cascade — these never change.
- Look it up when you get stuck: Even professional developers search for properties daily.
- Use tools without guilt: Colour pickers, gradient generators, and shadow tools save time and reduce errors.
- Build often: The more you code, the more familiar the common properties become.
Key takeaways
- CSS has hundreds of properties; memorising all of them is neither expected nor efficient.
- MDN Web Docs is the definitive reference — every property includes syntax, examples, and live previews.
- Google and online CSS generators are legitimate, everyday tools for real‑world development.
- Focus on fundamentals (syntax, selectors, layout) and learn to find the rest on demand.
Colors in CSS
CSS provides multiple ways to define colors to set the foreground (text) color and the background color of elements. Understanding these representations lets you precisely control the visual tone of a webpage.
Color Properties
| Property | Purpose | Example |
|---|---|---|
color | Sets the text color (foreground) | color: blue; |
background-color | Sets the background of the element | background-color: lightblue; |
The shorthand
backgroundproperty can also set gradients and images. Stick tobackground-colorfor solid colors.
Color Representation Methods
CSS accepts three common ways to specify a color:
- Named colors – Simple, browser‑recognised words (e.g.,
red,teal,beige,aqua). - Hexadecimal (hex) codes – A six‑character code preceded by
#(e.g.,#FF5733). - RGB notation –
rgb(red, green, blue)where each value is an integer 0–255 (e.g.,rgb(255, 87, 51)).
| Method | Syntax | Example | Use Case |
|---|---|---|---|
| Named | color: red; | Simple, fast prototyping | |
| Hex | color: #FF5733; | Compact, most common in production | |
| RGB | color: rgb(255, 87, 51); | When you want to adjust numeric values |
How Hex and RGB Relate
The RGB color system is an additive model – red, green, and blue light combine to create colors.
- Zero of all three → black.
- Full (255) of all three → white.
- Equal amounts of red and green → yellow; adding blue → becomes white.
Hexadecimal is just another way to write the same three numbers (0–255 for each channel) in base‑16.
- Digits:
0‑9anda‑f(16 total). - Example: decimal 255 →
FF; decimal 150 →96; decimal 200 →C8. - So a hex code like
#FF5733means R=255, G=87, B=51.
Exam tip: A hex code is exactly an RGB triplet written in base‑16 – no magic! You can convert any RGB value to hex and vice versa.
Color Tools and Palettes
- Color pickers (built into browsers or online) let you visually select a color and copy its hex or RGB value.
- Palette websites (e.g., Color Hunt) provide pre‑matched harmonious color sets. Click to copy a hex code, then paste it into your CSS with a
#.
Worked Examples (from the lecture)
| Element | CSS applied | Effect |
|---|---|---|
<h1> | color: blue; background-color: aqua; | Blue text on light blue background |
<p> | color: #XXXXXX; (hex from palette) | Text color set to palette colour |
<button> | color: rgb(…, …, …); | Greenish text (random numbers) |
<input> | color: red; background-color: #XXXXXX; | Red typed text, custom background inside the box |
<html> | background-color: beige; | Entire page background beige (cascades but can be overridden by specific element backgrounds) |
Notable behaviours demonstrated:
- The
colorproperty on an<input>affects only the typed text, not the placeholder text. - Background colors cascade – adding a background to
<html>shows behind elements that do not have their own background set (but specific background‑color rules override it). This is part of the cascading nature of CSS.
Key Takeaways
colorcontrols text colour;background-colorcontrols the element’s background.- Three main ways to define colors in CSS: named, hex, and RGB.
- Hex codes are compact base‑16 representations of RGB values – no need to memorise conversion, just copy from a picker.
- Use color pickers and palettes (e.g., Color Hunt) to quickly choose harmonious colours.
- Placeholder text inside
<input>is not affected by thecolorproperty – that requires the::placeholderpseudo‑element.
CSS Fonts
Fonts are central to web design — they control readability, tone, and visual hierarchy. CSS offers a suite of properties to adjust typeface, size, thickness, slant, and alignment. Use them to make text both expressive and accessible.
1. Font Size (font-size)
Controls how large or small text appears. Units fall into two categories:
Absolute units — fixed size, unaffected by context.
px(pixels): . Renders identically regardless of device.pt(points): . Common in print; also works on screen.
Relative units — size depends on another element.
em: Multiplied by the parent element’s font-size. If parent is ,2em.rem: Multiplied by the root element’s (<html>) font-size. If root is ,1.5rem.
Named sizes — keywords like small, medium, large. Imprecise; only for prototyping.
Exam tip:
emcompounds when elements are nested (each child multiplies its parent).remstays consistent — always relative to the root. Useremfor predictable, responsive sizing.
Worked example (from the lecture):
| Element | Rule | Parent/Root size | Computed size |
|---|---|---|---|
<h1> | font-size: 60px | — | 60px |
Parent <div> | font-size: 20px | — | 20px |
Child (.em-based) | font-size: 2em | parent = 20px | |
Root <html> | font-size: 30px | — | 30px |
Child (.rem-based) | font-size: 1.5rem | root = 30px |
Table: Font-size units compared
| Unit | Type | Relative to | Use case |
|---|---|---|---|
px | Absolute | — | Fixed, pixel-perfect control |
pt | Absolute | — | Print styling |
em | Relative | Parent’s font-size | Compound scaling (use with care) |
rem | Relative | Root font-size | Consistent, responsive layouts |
| Named | Keyword | Browser default | Quick prototyping only |
2. Font Weight (font-weight)
Controls the thickness of characters.
- Keywords:
normal(400),bold(700),lighter,bolder - Numerical values: 100 (thin) → 900 (heavy). 400 = normal, 700 = bold.
- Not all typefaces support every weight; missing values fall back to the nearest available.
Example:
h1 { font-weight: 800; }
.em-based { font-weight: 500; }
3. Font Family (font-family)
Selects the typeface (e.g., Arial, Times New Roman). Always provide a font stack — a comma‑separated list of fallbacks.
p {
font-family: 'Gill Sans', Calibri, 'Trebuchet MS', sans-serif;
}
The browser tries the first font; if unavailable, moves down the list. End with a generic fallback (serif, sans-serif, monospace).
Google Fonts — load custom fonts via a <link> in the document <head>, then reference the font name in CSS.
Example (from lecture):
<link href="https://fonts.googleapis.com/css2?family=Bokor&display=swap" rel="stylesheet">
h1 {
font-family: 'Bokor', sans-serif;
}
This ensures the same look across browsers and devices.
flowchart LR
A[Request font] --> B{Is 'Bokor' available?}
B -->|Yes| C[Render 'Bokor']
B -->|No| D{Next in stack?}
D -->|Yes| E[Try 'sans-serif' fallback]
D -->|No| F[Browser default]
4. Font Style (font-style)
Controls slanting of text.
normal— upright.italic— uses the italic version of the typeface (if it exists).oblique— artificially slants the upright glyphs. May take an optional angle (e.g.,oblique 15deg).
Use italic for emphasis. Example:
.em-based { font-style: italic; }
5. Text Alignment (text-align)
Horizontal alignment of text within its container.
| Value | Effect |
|---|---|
left | Aligns text to the left edge (default for LTR languages) |
right | Aligns to the right edge |
center | Centers text horizontally |
justify | Stretches each line so both left and right edges are flush (adds or removes space between words) |
Justify creates a clean, book‑like block but can produce awkward gaps on short lines.
Example: p { text-align: justify; }
Key takeaways
font-sizeuses absolute (px,pt) or relative (em,rem) units. Preferremfor responsive design.emscales relative to the parent;remscales relative to the root — avoid nestedemtraps.font-weightuses keywords or numeric values (100–900); 400 = normal, 700 = bold.font-familyshould always include a font stack with a generic fallback.- Google Fonts are loaded via
<link>and referenced by name — they ensure cross‑browser consistency. font-style(italic/oblique) andtext-align(left,center,right,justify) control slant and horizontal alignment.- Font choices affect readability and tone — experiment but always test fallbacks.
CSS Inspection
CSS inspection refers to using the browser’s developer tools to examine, debug, and experiment with CSS in real time. Instead of guessing why a style doesn’t look right, you open the tools and see exactly which rules are applied, which are overridden, and what the final rendered values are.
Opening Chrome Developer Tools
Three equivalent methods:
| Method | Action |
|---|---|
| Menu | Three dots → More Tools → Developer Tools |
| Keyboard | Ctrl+Shift+I (Windows) / Cmd+Option+I (Mac) – also F12 |
| Right-click | Right‑click any element → Inspect (directly shows that element’s HTML) |
The Elements Tab: Styles Panel
Once DevTools is open, the Elements tab shows the HTML structure. Selecting an element (either by clicking in the HTML tree or using the element‑picker icon in the top‑left of DevTools) reveals the Styles panel on the right.
The Styles panel displays:
- All CSS rules that apply to the selected element, in order of specificity.
- The source file and line number for each rule. Clicking a file link jumps directly to the source code.
- Which rules are overridden (shown with a strikethrough). For example,
font-size: 2emcrossed out when a later rule setsfont-size: 60px. - An inline edit capability – you can type a new property (e.g.
color: chocolate) and see the change live on the page.Important: These edits are temporary. They disappear on page refresh and do not modify your source files. Use them for rapid experimentation only.
Computed Tab
The Computed tab (next to Styles) solves the confusion of overridden rules. It aggregates all resolved styles into one clean list, showing the final value for every property after cascading and inheritance. This is the definitive answer to “what value does this element actually get?”
Box Model Visualisation
Both the Styles panel (at the bottom) and the Computed tab display a box model diagram for the selected element. It shows:
┌───── Margin ─────┐
│ ┌── Border ──┐ │
│ │ ┌ Padding ┐ │ │
│ │ │ CONTENT │ │ │
│ │ └─────────┘ │ │
│ └─────────────┘ │
└───────────────────┘
Each region is labelled with its current pixel (or other unit) value. This is invaluable for diagnosing spacing and layout issues.
CSS Overview Tool
A separate, aggregate tool that summarises all CSS used on a page:
- Open DevTools → three‑dot menu (⋮) → More Tools → CSS Overview.
- Click Capture overview.
It reports:
- Colors used (with count)
- Fonts used
- Unused declarations (or other diagnostics)
Useful when reverse‑engineering a design from a live website or auditing your own project for consistency.
Exam tip: The Computed tab is the fastest way to find the final value of a property when multiple rules conflict. Always look there before debugging specificity.
Key takeaways
- Open DevTools with
Ctrl+Shift+I,F12, or right‑click → Inspect. - The Styles panel shows all applied rules, source links, and overridden (strikethrough) values.
- Live editing is temporary – use it to test, then update your source file.
- The Computed tab gives the final resolved values, ignoring overridden rules.
- The box model diagram helps visualise margin, border, padding, and content dimensions.
- CSS Overview captures a summary of colors, fonts, and overall CSS usage on any page.
Box Model
Every element on a webpage is enclosed in an invisible box. The CSS box model defines how the element’s content, padding, border, and margin are sized and how they interact to determine the element’s total space and layout.
flowchart LR
A[Margin] --> B[Border] --> C[Padding] --> D[Content]
- Content – the actual text, image, or inner element.
- Padding – space between content and border; expands the element inward.
- Border – visible or invisible boundary around padding.
- Margin – space outside the border; separates the element from others.
Height & Width
height and width set the dimensions of the content area. Units can be absolute (px) or relative (%, vw, etc.).
| Example | Code | Result |
|---|---|---|
| Fixed size | height: 300px; width: 150px; | Box is exactly 300px × 150px. |
| Percentage width | width: 50%; | Width = 50% of parent container (e.g., <body>). Resizes with viewport. |
Exam tip: Changing
heightorwidthaffects the content area only – padding, border, and margin add extra space.
Border
border adds a boundary around the element. Shorthand: border: <width> <style> <color>;
Styles: solid, dashed, dotted, double, etc.
Individual side controls: border-width, border-style, border-color accept 1, 2, or 4 values.
| Number of values | Applies to |
|---|---|
| 1 | All four sides |
| 2 | Top & bottom (1st), left & right (2nd) |
| 4 | Top, right, bottom, left (clockwise) |
Example (shorthand with 4 values):
border-width: 10px 30px 50px 60px;
border-color: red green blue black;
border-style: dotted double dashed solid;
border-radius rounds the corners.
- 1 value: all corners.
- 2 values: first → top-left & bottom-right, second → top-right & bottom-left.
- 4 values: clockwise from top-left.
Padding
padding creates internal space between content and border.
- Expands the element’s total size outward from the content.
- Same 1/2/4 value rules as border.
Example: padding: 20px; adds 20px on all sides.
Margin
margin creates external space outside the border, separating elements.
- Also uses 1/2/4 value shorthand.
- Margin collapsing: When two adjacent vertical margins meet, they collapse to the larger value (not the sum).
- E.g., element A
margin-bottom: 30px, element Bmargin-top: 20px→ gap = 30px, not 50px.
- E.g., element A
Worked Example: Total Width of an Element
Given the first box from the lecture:
margin: 30px;
border: 10px solid black;
padding: 20px;
width: 150px; /* content width */
Total width (left to right) = margin-left + border-left + padding-left + content width + padding-right + border-right + margin-right
= 30 + 10 + 20 + 150 + 20 + 10 + 30
= 270px.
Exam tip: The box model is additive by default (
box-sizing: content-box). To include padding and border inside the declared width, usebox-sizing: border-box.
Using <div> for Grouping
The <div> element is a generic block-level container. It groups elements so they can be styled as a unit.
.grouping {
border: 20px solid green;
padding: 20px;
text-align: center;
}
This applies the same border, padding, and alignment to all children (e.g., <h1> and <p> inside the div).
Key takeaways
- Box model: content → padding → border → margin (inside-out).
height/widthset content size; use%for responsive layouts.bordershorthand: width, style, color. Use 2 or 4 values for side-specific control.paddingexpands element size;margincreates external spacing; vertical margins collapse.border-radiussoftens corners.<div>groups content for efficient styling.- Inspect elements in DevTools to see the box model visually.
The Cascade
The cascade refers to the order in which CSS rules are applied. When multiple rules target the same element and property, later declarations override earlier ones — "whatever comes later takes priority."
flowchart LR
A[Earlier rule] -->|overridden by| B[Later rule]
Definition: Cascade = waterfall-like flow. In CSS, styles applied later in source order have higher precedence (at the same specificity level).
Demonstration
Consider an <h1> element and two rules in the same stylesheet:
h1 { color: green; } /* line 1 */
h1 { color: brown; } /* line 5 – overrides green */
The heading appears brown. Adding a third rule below (e.g., color: cornflowerblue) overrides both. This principle holds within a single selector (multiple identical properties) and across selectors of equal specificity.
External vs. Internal vs. Inline – Source Order
- External stylesheets linked in
<head>are loaded in order of appearance. - Internal styles (
<style>in<head>) are treated like another stylesheet — they follow the same cascade. - Inline styles (via the
styleattribute) are considered to "come last" in source order for the element itself, but they also carry higher specificity (see below).
When two stylesheets have selectors of equal specificity, the sheet linked lower in the HTML wins.
Exam tip: Cascade only matters when specificity is tied. Always check specificity first – see next section.
Key takeaways
- Cascade: later styles override earlier ones within the same specificity level.
- Applies to both internal and external CSS.
- Source order (position in HTML / within a file) determines precedence when specificity is equal.
Specificity
Specificity is the algorithm CSS uses to decide which rule "wins" when multiple selectors target the same element. Think of it as a ranking: some selectors are inherently more powerful than others.
Selector hierarchy (lowest → highest)
| Selector type | Example | Specificity weight (MDN notation) |
|---|---|---|
| Element / type selector | h1, p, div | (0,0,1) |
| Class / attribute selector | .class-a, [type="text"] | (0,1,0) |
| ID selector | #unique-id | (1,0,0) |
| Inline style (on the element) | style="color: red" | (1,0,0,0) – always wins over external/internal |
!important annotation | color: green !important; | Overrides all of the above (see below) |
- Each higher level overrides any number of lower-level selectors. Ten element selectors cannot beat a single class.
- When two selectors have the same highest weight, cascade (source order) breaks the tie.
Demonstration with <h2 class="class-abc" id="id-abc">
- Element selector wins if only element rules exist; last one in the file applies (cascade).
- Add a class selector (
.class-abc { color: orange; }). Even if it appears before element selectors in the source, the heading turns orange – class is more specific. - Add an ID selector (
#id-abc { color: darkblue; }). Even at the top of the file, it overrides both element and class. - Multiple properties inside the ID selector: cascade still applies —
#id-abc { color: darkblue; color: gray; }→ gray wins (later). - Two external stylesheets each with an ID selector: the sheet loaded second wins because both have the same specificity (1,0,0), so cascade decides.
- Internal style with ID selector: treated as another CSS source. If loaded before the external ID, cascade gives the later one precedence. If moved below (later in the HTML), it overrides.
- Inline style (
style="color: fuchsia") overrides all external and internal ID/class/element rules – inline has the highest specificity (1,0,0,0).
Exam tip: Inline styles are rarely recommended because they break separation of concerns and are difficult to override. Use them only for quick tests.
Worked example: selector conflict
/* external stylesheet 1 (loaded first) */
h2 { color: green; } /* (0,0,1) – overridden */
.class-abc { color: orange; } /* (0,1,0) – overridden */
#id-abc { color: darkblue; } /* (1,0,0) – overridden by later ID */
/* external stylesheet 2 (loaded second) */
h2 { color: blueviolet; } /* (0,0,1) – ignored */
#id-abc { color: khaki; } /* (1,0,0) – wins (higher cascade) */
Result: heading is khaki.
If an inline style is added:
<h2 id="id-abc" class="class-abc" style="color: fuchsia">Heading</h2>
Result: fuchsia – inline specificity of (1,0,0,0) beats any external ID.
Key takeaways
- Specificity: ID > class > element.
- Equal specificity → cascade (source order) decides.
- Inline styles beat all external/internal selectors.
!importantbeats everything (except another!importantwith later source order).
The !important Keyword
Adding !important to a property declaration forces it to override any other rule, regardless of specificity or cascade — except another !important rule later in source order.
h2 { color: green !important; } /* this will win over any other 'color' rule */
- Use sparingly. It makes CSS hard to debug and override.
- If two rules both have
!important, cascade applies again – later one wins.
h2 { color: green !important; }
h2 { color: cornflowerblue !important; } /* wins because later */
Exam tip: Always try to solve style conflicts by adjusting selector specificity before resorting to
!important. Overuse is a code smell.
Putting It All Together – CSS Resolution Order
flowchart TD
A[Conflicting declarations] --> B{Has !important?}
B -->|Yes| C[Highest priority group]
B -->|No| D[Selector specificity]
D --> E{Highest specificity?}
E -->|Tie| F[Cascade: later wins]
E -->|One winner| G[That declaration wins]
C --> H{Multiple !important?}
H -->|Tie| F
H -->|One| G
Complete precedence (from strongest to weakest):
!importantdeclarations (tie → cascade)- Inline styles (no
!important) - ID selectors
- Class / attribute selectors
- Element selectors
- Universal selector, inherited values (not covered here)
Key takeaways
!importantshould be a last resort.- For all other cases: specificity first, then cascade.
- Inline styles are the second-strongest non-
!importantoption (but avoid them). - When two rules have the same specificity and no
!important, the one that appears later in the source order (including style order in HTML) applies.
Combining CSS Selectors
Combining selectors lets you target elements precisely without modifying HTML or adding extra classes/IDs. This keeps styles organized and efficient.
Descendant Selector
Selects elements nested anywhere inside a parent – no matter how deep. Use a space between selectors.
.container p {
color: orange;
}
Targets all <p> elements within any element with class container, including grandchildren, great-grandchildren, etc. The parent div itself is not selected.
Exam tip: Descendant selectors are the default “combination” – if you forget the space, you get chaining (see below). Always double-check the separator.
Child Selector (>)
Selects only direct children – one level deep. Use the > combinator.
.parent > p {
color: green;
}
Only <p> elements that are immediate children of .parent are affected. Nested <p> inside another <div> inside .parent is ignored.
graph TD
A[.parent] --> B[<p> direct child - selected]
A --> C[<div>] --> D[<p> grandchild - NOT selected]
Adjacent Sibling Selector (+)
Selects an element that appears immediately after a specific element, sharing the same parent.
h2 + h3 {
color: blueviolet;
}
Only the first <h3> that directly follows an <h2> gets styled. Subsequent <h3> siblings are ignored.
| Example HTML | Styled? |
|---|---|
<h2>Title</h2><br><h3>Subtitle</h3> | Yes (first <h3> after h2) |
<h2>Title</h2><br><h3>Second</h3><br><h3>Third</h3> | Only the first <h3> |
Common use case: styling a <label> that comes right after a checkbox or radio input.
input[type="checkbox"] + label {
color: dodgerblue;
}
Grouping Selector (,)
Apply the same styles to multiple, unrelated selectors. Separate them with a comma.
#heading4, .heading5class, h6 {
color: indigo;
}
Reduces repetition and keeps CSS concise.
Exam tip: Grouping does not create a relationship between selectors – it’s purely a shorthand. Each selector still targets its own elements independently.
Chaining Selectors
Write selectors without any space to target an element that must satisfy all conditions simultaneously. Good for selecting a specific element that has both a tag and a class/ID.
button.asd {
color: red;
}
This matches only <button> elements that also have class asd. An <input> with class asd or a <button> without the class are left unstyled.
graph LR
A[button] --> B{Has class .asd?}
B -->|Yes| C[Styled red]
B -->|No| D[Not styled]
When chaining, it is best practice to start with the element selector (e.g., button) followed by class/ID selectors (.asd, #menu). This improves readability because class and ID prefixes (. and #) clearly mark the start of each condition.
You can chain multiple classes and an ID:
div.container.main#menu { ... }
/* matches a <div> with classes container AND main, AND id="menu" */
Key Takeaways
- Descendant (space): targets any descendant, any depth.
- Child (
>): targets only direct children. - Adjacent sibling (
+): targets the next immediate sibling. - Grouping (
,): apply same rule to multiple selectors. - Chaining (no space): element must match all selectors in the chain.
- Chaining is ideal for applying a variation to a specific element without extra HTML classes/IDs.
- Always choose the simplest combination that does the job – avoid overspecificity.
Pseudo-Classes and Pseudo-Elements
Pseudo‑class selectors and pseudo‑element selectors target elements based on their state or internal parts without requiring extra HTML markup. They transform static pages into interactive, polished interfaces.
Pseudo‑Class Selectors
A pseudo‑class is a keyword added to a selector (with a single colon :) that specifies a special state of the selected element. Examples: :hover, :active, :nth-of-type(), :checked, :visited, :enabled, :disabled.
:hover
Triggered when the user’s pointer hovers over an element. Commonly used for buttons, links, or any interactive feedback.
button:hover {
color: chocolate;
background-color: lightgreen; /* actual colour used in lecture */
text-decoration: underline;
}
Effect: The button changes colour and gains an underline only while the mouse cursor is over it.
:active
Applies styles when the element is being activated – typically while the mouse button is pressed down.
button:active {
color: aqua;
background-color: black;
}
Sequence: Normal → :hover → :active (on click) → back to normal after release.
:nth-of-type()
Targets elements by their position among siblings of the same type. The argument can be a number, a keyword (odd, even), or an algebraic expression like An+B.
| Argument | Selects |
|---|---|
3 | Only the 3rd element |
2n | Every 2nd element (2, 4, 6, …) |
3n | Every 3rd element (3, 6, 9, …) |
7n | Every 7th element (7, 14, 21, …) |
li:nth-of-type(3n) {
background-color: khaki;
}
Result: List items 3, 6, 9, 18, … get a khaki background.
Exam tip:
:nth-of-type(3)selects only the third element;:nth-of-type(3n)selects every third element. Thenmakes the formula iterative.
Pseudo‑Element Selectors
A pseudo‑element is a keyword added with a double colon :: that lets you style a specific part of the selected element. Examples: ::first-letter, ::first-line, ::selection.
::first-letter
Styles the first letter of a block‑level element (e.g., paragraph, heading).
p::first-letter {
font-size: 60px;
color: blue;
}
Effect: The initial character becomes large and blue, like a drop‑cap.
::first-line
Styles the first line of a block‑level element (the actual line as it wraps in the browser).
p::first-line {
color: cadetblue;
}
Only the text on the first visual line receives the colour; subsequent lines remain unaffected.
::selection
Applies styles to the portion of an element that the user highlights (selects). Can be set globally or scoped to specific elements.
::selection {
background-color: orange;
}
p::selection {
background-color: darksalmon;
text-decoration: underline;
}
Effect: Selecting any text shows an orange background; selecting text inside a <p> uses darksalmon with an underline.
Pseudo‑Class vs. Pseudo‑Element — Quick Comparison
| Aspect | Pseudo‑Class | Pseudo‑Element |
|---|---|---|
| What it targets | A state of the element | A part or fragment of the element |
| Syntax | Single colon : | Double colon :: (legacy single‑colon also works for some) |
| Example | a:visited | p::first-letter |
| Trigger | User interaction or DOM position | Structural part of the element |
Key Takeaways
- Pseudo‑classes (
:hover,:active,:nth-of-type()): style an element based on its state or position. - Pseudo‑elements (
::first-letter,::first-line,::selection): style a specific part of an element. :nth-of-type(An+B)accepts formulas:2n= even,3n= every third, etc. Withoutn, it selects only the nth occurrence.- Pseudo‑elements often use double colons (
::) to distinguish them from pseudo‑classes, though older browsers may accept single colon. - Both require no extra HTML classes or IDs — purely CSS‑driven interactivity and typographic control.
CSS Inheritance
Inheritance is the mechanism by which certain CSS properties are automatically passed from a parent element to its child elements, unless the child has that property explicitly set. Intuitively: set a text color on <body> and every piece of text inside the page picks it up – no extra work needed.
Default inheritance from the nearest defined parent
When a property is inherited, a child element looks for the closest ancestor that has that property defined. If no ancestor has it, the default browser style applies.
Example – given this HTML:
<body>
<h1>Heading</h1>
<section>
<h2>Subheading</h2>
<p>Paragraph text</p>
</section>
<div>
<h3>Div heading</h3>
<input type="text">
<button>Click</button>
</div>
</body>
- Set
color: goldenrodon<body>→ all text inside inherits goldenrod. - Then set
color: blueon<section>→<h2>and<p>inside the section become blue (inherited from the closer parent).<h1>,<h3>,<input>, and<button>remain goldenrod because they still inherit from<body>– the section rule does not affect them.
The paragraph inspects as “inherited from section” (overriding “inherited from body”).
Exam tip: Inheritance doesn’t override explicit styles on the child – it only kicks in when no value is set on the child. Specificity and direct styling still win.
Elements that do not inherit by default
Form elements like <input> and <button> do not inherit text styling (color, font-family) from their parent by default. In the example, the button remained black (default user-agent style) even though <body> had color: goldenrod.
Forcing inheritance with the inherit keyword
You can explicitly tell an element to inherit any property using the inherit keyword.
button {
color: inherit; /* now takes the parent's goldenrod */
}
After adding this rule, the button’s text turns goldenrod. Developers use inherit to make form elements consistent with surrounding text.
Which properties are inherited?
There is no universal rule – you must check each property. The MDN documentation lists “Inherited” in the “Formal definition” section of every property.
| Commonly inherited | Commonly not inherited |
|---|---|
color | margin |
font-family, font-size | border |
letter-spacing | padding |
text-align | width, height |
visibility | background |
Exam tip: The easiest way to know: if a property describes the appearance of text, it’s usually inherited. If it describes the layout or box of the element, it’s usually not inherited.
Recap with a decision tree
flowchart TD
A[Parent property set] --> B{Is it an inherited property?}
B -->|Yes| C{Does child have a direct value?}
C -->|No| D[Child inherits parent value]
C -->|Yes| E[Child uses its own value]
B -->|No| F[Child uses own default or explicit value]
D --> G[Child can override with inherit keyword if property is non-inherited]
F --> G
Key takeaways
- Inheritance allows child elements to automatically get a property’s value from the nearest ancestor that defines it.
- Properties like
color,font-family, andletter-spacingare inherited;margin,border,paddingare not. - The
inheritkeyword forces any property (even non-inherited ones) to take the parent’s computed value – useful for form elements. - Elements inside
<form>(inputs, buttons) often do not inherit by default; useinheritto align them. - MDN’s “Formal definition” section is the authoritative source for a property’s inheritance behavior.
The <span> Element for Inline Styling
The <span> element is an inline container that wraps around a portion of text (or other inline content) without breaking the flow of the document. Unlike a block-level <div> which takes the full width, <span> sits within the line, allowing precise CSS styling of only that fragment.
Intuitively: you want to colour one word red, underline a phrase, or enlarge the first letter – <span> gives you a handle to attach a class or ID and apply styles exactly where you want, without affecting surrounding text.
Comparing <span> and <div>
| Element | Display type | Default behaviour | Use case |
|---|---|---|---|
<span> | Inline | Wraps content; stays within the line | Styling a word, phrase, or inline image |
<div> | Block | Starts on a new line; takes full width | Structuring sections, containers |
Exam tip:
<span>is the go‑to for “I need to style just this bit of text inside a paragraph.” It does not add any line breaks or semantic meaning – it’s purely a styling hook.
Worked example: Highlighting “highlighted heading”
HTML (inside a <h1>):
<h1>This is a <span class="highlight">highlighted heading</span></h1>
CSS:
.highlight {
color: blue;
}
Result: only the words inside the <span> turn blue. The rest of the heading remains its original colour.
Using <span> for word‑ or line‑level styling
| Goal | Approach | CSS applied |
|---|---|---|
| Style the first word of a paragraph | Wrap the first word in <span class="first-word"> | font-size: 2em; color: brown; |
| Style the first few lines | Wrap those lines (including spaces) in <span class="first-lines"> | text-decoration: underline; background-color: aqua; |
Compared to CSS pseudo‑elements like ::first-letter or ::first-line, <span> gives more precise control – you can target arbitrary text fragments, not just the first letter/line.
How it works in practice
flowchart LR
A[HTML text] --> B{Wrap fragment in <span>?}
B -->|Yes| C[Attach class or id]
C --> D[Write CSS rules for .class or #id]
D --> E[Only wrapped fragment gets styled]
No extra markup, no layout shift – the inline flow continues unchanged.
Key takeaways
<span>is an inline, non‑semantic container for styling fragments.- It does not break the text flow or create new lines.
- Use a class or ID on
<span>to target it with CSS. - More flexible than pseudo‑elements for arbitrary text selection (e.g., first word, first two lines).
- Works on any inline content, including images or other elements.
Display Property
The display property controls whether an element behaves as a block or inline box. Intuitively: block elements claim their own horizontal line; inline elements sit next to each other like words. By changing display, you override the default behavior of any element.
Default flow: block vs. inline
By default:
- Block-level elements (e.g.,
<div>,<p>) stack vertically and take up the full available width. - Inline elements (e.g.,
<span>,<a>) flow along the same line as adjacent content.
| Property | Block element | Inline element |
|---|---|---|
| Width | Takes entire parent width | Shrinks to content |
| Stacking | Always new line | Stays on same line |
| Box model | Respects width, height, margin, padding fully | Ignores height, vertical margin; horizontal padding/margin only shift content on that line |
Changing display values
Syntax: display: block | inline | inline-block | none;
Example (from lecture)
HTML: <div class="block">...</div> and <span class="inline">...</span>.
With .block { display: inline; } and .inline { display: block; }:
- The
<div>no longer spans full width — it becomes inline. - The
<span>takes full width — it becomes block.
Key insight: The display property overrides an element’s native behaviour; any element can become any box type.
Box-model behavior: inline vs. block
When adding height, width, padding, margin:
- Block element: all properties are respected. Padding and margin push surrounding content both horizontally and vertically.
- Inline element:
heightandvertical marginare ignored.Paddingis applied visually but does not push content above or below — it only affects that line. This makes inline elements unsuitable for layout control.
Inline-block: the hybrid
A third value, display: inline-block, combines the best of both:
- The element stays inline (it aligns with text and other elements on the same line).
- It respects all box-model properties (
width,height,margin,padding) on every side.
| Value | Stays inline? | Respects width/height? | Respects vertical margin? |
|---|---|---|---|
block | No | Yes | Yes |
inline | Yes | No | No |
inline-block | Yes | Yes | Yes |
Practical example
Three <div> boxes (class box) with height: 100px; width: 100px; margin: 20px;:
display: block→ stacked vertically.display: inline→ side by side but dimensions collapse to content (100px ignored).display: inline-block→ side by side, dimensions respected.
Exam tip: Use
inline-blockfor buttons, badges, or icons that need to sit beside text while having explicit width/height.
Display: none
display: none completely removes the element from the rendered page — it leaves no trace, as if the element never existed (unlike visibility: hidden which still occupies space).
Use case
Hide a button until a user completes an action (e.g., form fill). The button exists in the HTML and can be shown later via JavaScript by switching display to block or inline-block.
<button type="button" class="hidden-btn">Click me</button>
.hidden-btn { display: none; }
Key difference: The element is invisible and does not affect layout; perfect for dynamic toggling.
Key takeaways
displayoverrides an element’s default box type: block, inline, inline-block, or none.- Block elements take full width, stack vertically, and respect all box-model properties.
- Inline elements flow horizontally; they ignore
heightandvertical margin. - Inline-block gives inline flow with full box-model control — ideal for aligned, dimensioned components.
display: nonehides an element completely; it is removed from layout and can be toggled by JavaScript.
Position Property
The position property controls how an element is placed in the document — relative to its normal flow, a parent, the viewport, or the scroll position. It takes one of five values: static, relative, absolute, fixed, or sticky. Together with the offset properties top, right, bottom, left, you can fine-tune placement.
flowchart LR
A[position] --> B{Value?}
B --> C[static]
B --> D[relative]
B --> E[absolute]
B --> F[fixed]
B --> G[sticky]
C --> H[Default; no offset effect]
D --> I[In flow; shifted from original position; space preserved]
E --> J[Removed from flow; positioned relative to closest *positioned* ancestor or initial containing block]
F --> K[Removed from flow; positioned relative to viewport; fixed on scroll]
G --> L[In flow until scroll threshold; then behaves like fixed]
Static (position: static)
Default for all elements. The element follows normal document flow — block elements stack vertically, inline elements flow horizontally. Offset properties (top, left, etc.) have no effect; they are ignored.
MDN: The
staticproperty preventstop,left, etc. from having any effect. The element remains in its natural position.
Relative (position: relative)
The element stays in the normal flow (its original space is preserved), but you can shift it relative to its own original position using offset properties.
top: 50pxmoves the element down by 50px.left: 50pxmoves it to the right by 50px (positive left adds space on the left side).- Negative offsets move in the opposite direction.
The original space remains occupied — other elements do not reflow into the gap.
Example:
A green box with position: relative; top: 50px; left: 50px; appears 50px down and 50px right from where it would have been, while its original footprint stays empty.
Absolute (position: absolute)
The element is removed from normal flow — no space is reserved for it. It is positioned relative to the closest positioned ancestor (an ancestor whose position is not static). If no such ancestor exists, it positions relative to the initial containing block (typically the <html> element).
Offset properties (top, left, etc.) specify the distance from the edges of that containing block.
Key behaviour:
- Other elements ignore the absolute element; they may overlap.
- The containing block must be positioned (e.g.,
relative,absolute,fixed, orsticky) for the absolute child to nest inside it.
Example:
A child div with position: absolute; top: 50px; left: 100px; inside a parent with position: relative; will be offset 50px from the top and 100px from the left of the parent’s content box. Without the parent being positioned, it would be relative to the document root.
Fixed (position: fixed)
The element is removed from normal flow and positioned relative to the viewport. It stays fixed in place even when the page is scrolled.
- Offset properties (
top,left,right,bottom) are relative to the viewport edges. - Commonly used for persistent navigation bars, back-to-top buttons, or sticky headers.
Example:
A fixed element with top: 100px; left: 500px; remains 100px from the top and 500px from the left of the viewport, unaffected by scrolling.
Sticky (position: sticky)
A hybrid: the element behaves as relative until a specified scroll threshold is reached, then becomes fixed relative to the viewport (or its scrolling container). It stays “stuck” as long as its parent container is visible.
- Must have at least one offset property (e.g.,
top: 50px) to define the sticky point. - The element remains in the normal flow and its original space is preserved – when it becomes fixed, it “sticks” but the reserved space remains.
- Important: The element’s parent must contain enough scrollable content for the sticky behaviour to work. If the parent is too short, the element will never reach its sticky point.
Exam tip: Always ensure the sticky element’s parent has overflow content (or sufficient height) that can be scrolled; otherwise,
stickywill appear broken.
Example:
A heading with position: sticky; top: 0; inside a tall scrollable <div> will scroll normally until its top reaches the top of the viewport, then it “sticks” there while the rest of the content scrolls underneath.
Summary Table
| Value | In normal flow? | Offset relative to | Space preserved? | Page scroll effect |
|---|---|---|---|---|
static | Yes | — (offsets ignored) | Yes | Scrolls normally |
relative | Yes | Its own original position | Yes | Scrolls normally |
absolute | No | Closest positioned ancestor (or initial containing block) | No | Scrolls with document (unless in fixed ancestor) |
fixed | No | Viewport | No | Stays fixed |
sticky | Yes, until threshold | Own flow, then viewport | Yes | Scrolls until threshold, then sticks |
Worked Example (Conceptual)
Given three sibling boxes inside a container:
- Box 1:
static(default) → sits at top-left of container. - Box 2:
relative; top: 30px; left: 20px;→ moves down 30px and right 20px from where it would normally be; its original spot remains empty (visible as a gap). - Box 3:
absolute; top: 0; right: 0;→ container must haveposition: relative;otherwise Box 3 would go to document right‑top corner; it sits at top‑right corner of container, overlapping any content.
Key Takeaways
- Use
staticfor default flow; offsets are ignored. relativekeeps the element in flow but lets you nudge it; original space is preserved.absoluteremoves the element from flow; position relative to the nearest positioned ancestor.fixedpins the element to the viewport – stays on screen during scroll.stickytoggles between relative and fixed at a defined scroll threshold; requires a scrollable parent.- The offset properties
top,right,bottom,leftonly work whenpositionis notstatic.
Float and Clear
Float and clear are CSS properties originally designed to wrap text around images—like a newspaper layout. Intuitively: you want an image on the side and let the text flow naturally around it. Float was not intended for overall page layout; use Flexbox or CSS Grid for that. Understanding float/clear, however, builds a solid CSS foundation.
The float Property
- Purpose: Takes an element out of the normal document flow and positions it to the left or right, allowing inline content (e.g., text) to wrap around it.
- Values:
left|right|none(default) - Effect: The floated element stays part of the page but no longer participates in the normal flow—subsequent content “flows” around it.
/* Float an image to the left */
img {
float: left;
}
Common pitfall: Because floated elements are removed from normal flow, they can cause overlapping or collapsed parent containers. This is why float is tricky for layouts.
The clear Property
- Purpose: Applied to a non-floated element (e.g., a paragraph) to prevent it from wrapping around a floated element. It forces the element to start below any floated elements on the specified side.
- Values:
left|right|both|none(default)
| Value | Effect |
|---|---|
left | Clears only left-floated elements; element starts below them. |
right | Clears only right-floated elements. |
both | Clears both left and right floats; element starts on a new line below. |
/* Force a paragraph to appear below any left-floated elements */
#p-other {
clear: left;
}
How they work together
flowchart LR
A[Floated element] -->|float: left/right| B[Element removed from normal flow]
B --> C[Next content wraps around it]
C --> D{Has clear?}
D -->|clear: left/right/both| E[Content starts below the float]
D -->|no clear| F[Content continues wrapping]
Real example (from the lecture)
Given an image floated left and two paragraphs:
- Without
clear: Both paragraphs wrap around the image. - With
clear: lefton the second paragraph: That paragraph starts below the image (on the left side), ignoring the float. - With
clear: both: The element is forced below all floats on either side.
Caveat: float for layout is obsolete
Floated layouts are fragile—elements overlap, containers collapse, and responsive design becomes painful. Modern CSS provides Flexbox and Grid for robust, predictable layouts. Float should only be used for its original purpose: text wrapping around media.
Exam tip: If a question asks about the original purpose of
float, answer wrapping text around images, not layout. And remember thatclearis applied to the following element, not the floated one.
Key takeaways
float: left/rightmoves an element out of normal flow so text wraps around it.clear: left/right/bothforces a non-floated element to start below any floated elements.- Float was designed for newspaper-style text wrapping, not page layout.
- For layout, use Flexbox or Grid.
- Floated elements can cause unpredictable overlapping and container collapse.
Styling a Website with CSS
CSS (Cascading Style Sheets) controls the visual presentation of a web page. The goal is to apply styles consistently while making minimal changes to the HTML structure. Styling begins by inspecting the target design — colours, fonts, and layout — then replicating them through selectors, the box model, and pseudo-classes.
Extracting design specs
Use the CSS Overview tool in Chrome DevTools to capture the design system of a reference website:
- Right-click → Inspect → three-dot menu → More tools → CSS Overview.
- Capture an overview to see lists of text colours, background colours, font families, font sizes, and unused declarations.
Example: the IIMB website uses Times New Roman as font, and specific hex colours (e.g., #72828, #aabbcc).
Exam tip: The CSS Overview tool is not a standard exam requirement, but understanding how to extract colours and fonts from any page is a practical skill often tested in applied coding tasks.
Structuring the header
A header containing a logo image and a heading can be wrapped in a <div> with a class (e.g., main-div). Style it using the class selector (.main-div).
.main-div {
border-bottom: 5px solid #72828;
padding: 20px;
}
To align logo and heading side by side, set the immediate children (image and <h1>) to display: inline-block and use vertical-align: middle.
.main-div > * {
display: inline-block;
vertical-align: middle;
}
Spacing can be added via padding on the <h1>. For centering the header content, use calc() to subtract the logo width from 50%:
.main-div h1 {
padding-left: calc(50% - 400px); /* approximate centering */
}
Exam tip:
calc()is a powerful CSS function; you can combine any units. However, for production layouts, Flexbox or Grid are preferred (covered in the next module).
Global typography
Set a default font for the entire page using the element selector on html or body:
html {
font-family: Times New Roman, serif;
}
Style headings and paragraphs with colour, font-size, and text alignment. Use the descendant selector to target elements after a specific parent (e.g., p immediately after .main-div):
.main-div + p {
font-size: x-large;
text-align: center;
color: #72828;
}
Navigation interactivity
The navigation bar (<nav>) can be centred, padded, and its anchor links styled as buttons.
- Style the
<nav>element:text-align: center; padding: 40px; - Style the
<a>tags inside<nav>usingnav aselector.
nav a {
display: inline-block; /* allows padding */
padding: 20px 10px;
border: 3px solid red;
border-radius: 30px; /* rounded corners */
background-color: #aabbcc;
color: white;
font-weight: bold;
}
Add interactivity with pseudo-class selectors:
| Pseudo-class | Trigger | Example |
|---|---|---|
:hover | Mouse over element | Change background to a lighter colour, text to white |
:active | While element is being clicked | Change background to a darker colour |
nav a:hover {
background-color: lightblue;
color: white;
}
nav a:active {
background-color: darkblue;
}
These styles apply to all pages because the same CSS file is linked to every HTML file, and the selector (nav a) matches all navigation links.
Table styling
Tables use <th> (header cells) and <td> (data cells). Default behaviour shows separate borders with gaps — use border-collapse: collapse on the <table> element to merge them.
table {
border-collapse: collapse;
text-align: center;
width: 100%;
}
th {
border: 2px solid #72828;
background-color: #aabbcc;
color: white;
}
td {
border: 1px solid #72828;
padding: 10px;
}
Exam tip:
border-collapseapplies only to the<table>(or inline-table) element, not to<th>or<td>. Applying it to individual cells will have no effect.
Set column width using width on <th> or <td>, and adjust cell spacing with padding.
Form and button styling
Style <input>, <select>, and <button> elements to match the theme.
- For input fields:
border: 2px solid #72828 - Apply to both
<input>and<select>using a group selector:input, select { ... }
input, select {
border: 2px solid #72828;
}
form {
color: #72828;
}
Style the submit button (<button>):
button {
background-color: #aabbcc;
color: white;
padding: 20px;
border: none;
border-radius: 20px;
font-weight: bold;
}
Add hover and active effects with the same pseudo-class pattern as the navigation links.
Background and layout adjustments
Apply a background colour to the entire page using the body selector. Remove the default margin on body to eliminate white edges.
body {
background-color: #e0e0e0;
margin: 0;
}
To prevent the header from inheriting the background, give the .main-div a white background. Use the main element (already present in HTML) to add padding for content below the header.
.main-div {
background-color: white;
}
main {
padding: 10px;
}
The box model is referenced whenever inspecting sizes in the DevTools – padding, border, and margin can be observed and adjusted directly.
Exam tip: The box model (content → padding → border → margin) is fundamental. When styling, always check the computed dimensions in the Elements panel to debug unexpected spacing.
Key takeaways
- Use CSS Overview in DevTools to extract a design’s colours and fonts.
- Style with class selectors (
.class) and element selectors (e.g.,html,body). - Align elements side-by-side with
display: inline-blockandvertical-align: middle. - Add interactivity via
:hoverand:activepseudo-classes. - Tables require
border-collapse: collapseon the<table>to remove gaps. - Use
calc()for dynamic spacing; prefer Flexbox/Grid in production. - Always check the box model in DevTools to understand padding, border, and margin contributions.
Introduction to Web Development
Introduction to Web Development
This module lays the theoretical foundation for understanding how the internet works and how websites come to life. Before building anything, it is essential to grasp the core concepts: the internet as a global network, the browser as the access tool, the client–server model, DNS (Domain Name System), IP addresses, and the physical infrastructure (underwater cables). The module also introduces the two sides of development – frontend (user-facing) and backend (server-side) – and the broader societal impact of the web.
Tips for Learning Web Development
Effective learning requires a mindset shift. Follow these strategies to build real skill, not just passive knowledge.
- Watch first, then code. Do not write code while watching the video. Focus on understanding the element being taught.
- Pause and try on your own. After watching, pause the video and write the code yourself. If stuck, search your book or online. This builds problem-solving ability.
- Embrace frustration. Getting stuck is normal. Take a break, clear your mind, and return with a fresh perspective.
- Use resources. Search online, read the provided book, ask on forums – do not give up.
- Understand, don’t memorise. Coding is about understanding how elements work together, not memorising every line.
- Troubleshoot independently. Attempt to fix issues on your own before checking the solution.
Exam tip: The single most important habit is pausing and coding from scratch. This trains the same debugging mindset used by professional developers.
What is the Internet?
At its core, the internet is a massive network of wires and connections linking computers worldwide. When a computer in Mumbai sends a message to one in New York, the data travels through these physical wires.
Key Concepts
- Clients and Servers
- Server: A computer that is always online and stores/sends information (e.g., YouTube videos, Instagram reels).
- Client: Your device (phone, tablet, laptop) that requests data from servers.
- IP Address (Internet Protocol address): Every device connected to the internet has a unique numeric address (e.g.,
132.431.53.134). It acts like a home address for computers and servers. - ISP (Internet Service Provider): The company that provides internet access (e.g., Jio, Airtel, BSNL in India). It forwards requests from your browser to the DNS server.
- DNS (Domain Name System): Acts as the internet’s phonebook. Humans use domain names (e.g.,
youtube.com), but browsers use IP addresses. DNS translates domain names into IP addresses.
| Term | Role | Example |
|---|---|---|
| Client | Requests data | Your laptop running Chrome |
| Server | Stores and sends data | YouTube’s server |
| IP Address | Unique identifier for devices | 132.431.53.134 |
| ISP | Provides internet connection | Jio, Airtel, BSNL (in India) |
| DNS | Translates domain names → IPs | youtube.com → server IP |
What Happens When You Load a Website?
- You type
youtube.cominto your browser (e.g., Chrome). - The browser does not know the server’s location → it asks your ISP for help.
- The ISP forwards the request to a DNS server.
- The DNS server looks up the IP address of
youtube.comand sends it back to the browser. - The browser now knows the IP address and can connect directly to YouTube’s server to load the webpage.
flowchart LR
A[Browser: type youtube.com] --> B[ISP]
B --> C[DNS Server]
C --> D[Returns IP address of YouTube server]
D --> A
A --> E[YouTube Server]
E --> A[Loads webpage]
Physical Infrastructure: Underwater Sea Cables
Data travels across oceans through massive underwater sea cables laid on the ocean floor, connecting countries and continents. These cables transmit data at nearly the speed of light, enabling global communication in milliseconds. (A map can be viewed at submarinecablemap.com.)
Key takeaways
- The internet is a global network of physical wires; computers communicate via clients and servers.
- Every device has a unique IP address; servers are always online.
- DNS translates human-friendly domain names into machine-readable IP addresses.
- ISPs and DNS servers are intermediaries that help browsers find the correct server.
- Physical data transfer across continents uses underwater sea cables (speed-of-light latency).
Web Browser
A web browser is any application that fetches and displays web pages, letting you navigate the internet. Popular examples: Chrome, Firefox, Safari, Edge. When you visit a website, the browser sends a request to the server for the files that make up the page — then interprets and renders them into the visual interface you see.
How a web page loads
- User enters a URL (or clicks a link).
- Browser sends a request to the server.
- Server responds with a set of files:
- HTML – structure and content
- CSS – styling and layout
- JavaScript – interactivity and dynamic behaviour
- Other resources – images, fonts, etc.
- Browser processes these files sequentially (HTML first, then CSS and JS, then assets) to construct the final rendered page.
flowchart LR
A[Browser] -- "Requests files" --> B[Server]
B -- "Sends HTML, CSS, JS, images" --> A
A -- "Renders page" --> C[Displayed web page]
Files that form a web page
| File Type | Role |
|---|---|
| HTML | Defines the structure and content (headings, paragraphs, links) |
| CSS | Controls presentation (colours, fonts, spacing, responsive layout) |
| JavaScript | Adds interactivity (animations, form validation, API calls) |
| Other (images, fonts, etc.) | Embedded media and typography resources |
Each file plays a unique role; the browser assembles them in real time to produce the complete page.
Key takeaways
- A web browser is an application for viewing and navigating the internet.
- It loads a website by requesting files from a server.
- The essential file types are HTML, CSS, JavaScript, and additional assets like images and fonts.
- These files are combined and rendered by the browser to create the visual webpage.
HTML, CSS and JavaScript
Web pages are built from three core technologies that work together: HTML, CSS, and JavaScript. Each plays a distinct role — structure, style, and behaviour — and a browser combines them to render a complete, interactive page.
HTML – Structure and Content
HTML (HyperText Markup Language) provides the skeleton of a web page. It defines the content to be displayed (text, images, links) and organises it into a logical hierarchy: headings, paragraphs, lists, sections, and more.
- Think of HTML as the outline the browser uses to understand the page’s structure.
- On a blog, the HTML file holds the article text, titles, and image references — but looks plain on its own, without colours or styling.
CSS – Style and Design
CSS (Cascading Style Sheets) controls the visual presentation of HTML elements. It adds colour, fonts, spacing, layout, background effects, and even animations.
- CSS transforms a raw HTML skeleton into something visually appealing.
- You can target any HTML element (e.g., a text block) and change its colour, boldness, background, or position.
- Styling ranges from small font-size tweaks to the entire page layout.
JavaScript – Interactivity and Logic
JavaScript is a programming language that brings the page to life with dynamic behaviour. While HTML and CSS handle static content and presentation, JavaScript enables:
- Interactivity – e.g., a button that shows a pop-up message when clicked.
- Logic – e.g., an online shopping cart that recalculates the total price as items are added or removed.
- The core idea: “When this, do that” – JavaScript executes functions in response to events.
How the Browser Puts It All Together
When you load a website, the browser receives the HTML, CSS, and JavaScript files from a server. It then stitches them together:
flowchart LR
A[Server] --> B[HTML: structure & content]
A --> C[CSS: style & layout]
A --> D[JavaScript: interactivity & logic]
B --> E[Browser]
C --> E
D --> E
E --> F[Final interactive web page]
The browser processes each file in order — first the HTML to build the document, then CSS to style it, and finally JavaScript to add dynamic features. The result is what you see on your screen.
Exam tip: A common question asks which technology does what. Remember the analogy:
HTML = skeleton, CSS = skin/clothes, JavaScript = muscles that move. Never mix them up.
Key takeaways
- HTML defines the content and structure of a web page.
- CSS handles the visual styling (colours, fonts, layout).
- JavaScript adds dynamic behaviour and logic (click actions, calculations).
- The browser requests all three files, then combines them to display a functional page.
- Each technology is essential; without one, the page would be incomplete (plain, unstyled, or static).
HTTP Request
When you type a URL, your browser must ask a server for files. But browsers and servers are built by different companies, run on different devices. How do they understand each other? They need a common language—a protocol. HTTP (Hypertext Transfer Protocol) is that language for the web. An HTTP request is the formal message your browser sends to the server to initiate this conversation.
What HTTP is
HTTP = Hypertext Transfer Protocol. A set of rules (grammar) that defines how data is formatted and transmitted between browsers and servers. It ensures any browser can talk to any server, regardless of device or network.
How it fits into the request–response cycle
- User types
flipkart.comin the browser. - Browser sends an HTTP request to Flipkart's server.
- Server processes the request and responds with files: HTML, CSS, JavaScript, and other resources.
- Browser interprets these files and renders the webpage.
HTTP is the middleman that makes steps 2 and 3 work universally.
Other protocols – a comparison
HTTP is one of many application-layer protocols. Each serves a specific purpose.
| Protocol | Full Name | Purpose |
|---|---|---|
| HTTP | Hypertext Transfer Protocol | Transfer web pages and data |
| HTTPS | Hypertext Transfer Protocol Secure | Encrypted (secure) version of HTTP |
| FTP | File Transfer Protocol | Transfer files between computers |
| SMTP | Simple Mail Transfer Protocol | Send email messages |
Exam tip: Know that HTTPS is the secure variant of HTTP. The transcript explicitly calls it “the secure version”. Do not confuse FTP (file transfers) with SMTP (email).
Key takeaways
- HTTP is the protocol that governs browser–server communication.
- An HTTP request is the browser’s formal message asking for resources.
- The protocol guarantees interoperability across different devices and networks.
- Other protocols (HTTPS, FTP, SMTP) exist for security, file transfer, and email respectively.
- The request–response cycle: browser requests → server returns HTML/CSS/JS → browser renders page.
Frontend and Backend
The web application is split into two main sides. The frontend is everything the user sees and interacts with in the browser (layouts, buttons, images). The backend is the hidden machinery that stores, processes, and serves data. The two communicate via the request-response cycle using HTTP.
flowchart LR
A[Browser / Frontend] -- HTTP request --> B[Server / Backend]
B -- "retrieve / store data" --> C[(Database)]
C -- data --> B
B -- HTTP response --> A
Frontend (Client‑Side)
- What it is: The user interface (UI) — everything rendered in the browser.
- Technologies: HTML (structure), CSS (styling, colors, fonts, layout), JavaScript (interactivity, dynamic behaviour).
- Goal: Provide an appealing, smooth visual experience. Clicking a button, scrolling, or watching a video all happen on the frontend.
Backend (Server‑Side)
- What it is: Everything that happens behind the scenes — data storage, processing, retrieval, user management, authentication, transaction handling.
- Technologies: Languages like Python, Java, Ruby, or JavaScript‑based frameworks like Node.js. Backend code runs on a server.
- Goal: Power the features the frontend presents to users (e.g., logins, course tracking, personalised feeds).
When a Backend Is Needed
Not every website requires a backend. The need depends on complexity.
| Type | Example | Backend needed? | Reason |
|---|---|---|---|
| Simple static site | IIMB DBE website (info only) | No | Just display text, images, and static content. |
| Dynamic / heavy app | IIMBx e‑learning platform, social media, e‑commerce, Netflix | Yes | User logins, course tracking, personalised data, complex interactions. |
Backend handles:
- Data storage and retrieval (e.g., profiles, uploaded files)
- User authentication and management
- Complex processing (e.g., transactions, recommendations)
Course Focus: Frontend Web Publishing
This course concentrates on web publishing – building and styling static websites using frontend technologies only (HTML, CSS, JavaScript). You will learn to create interactive, attractive sites for blogs, portfolios, small businesses – no backend required.
Exam tip: “Static” = no backend, content fixed; “dynamic” = backend processes data and serves personalised content. Know the difference and examples.
Why learn JavaScript here? JavaScript is the bridge – mastering it in the frontend gives a strong foundation for later exploring backend development (e.g., Node.js).
Key takeaways
- Frontend = browser UI (HTML, CSS, JavaScript); backend = server‑side data processing (Python, Java, Ruby, Node.js).
- The request-response cycle and HTTP connect frontend and backend.
- Simple sites (e.g., information pages) can be purely frontend; dynamic apps (e‑commerce, social media) require a backend.
- This course covers frontend web publishing – no backend; JavaScript learned now prepares you for future backend work.
The Beginning of the Digital Age (Early 1990s)
The modern internet began in the early 1990s with Tim Berners-Lee inventing HTTP and HTML — the foundational technologies that enabled information sharing and browsing. Before this, networks existed only within research institutes and government. Websites were basic, text-based, and static. Early browsers like Netscape Navigator and Internet Explorer let people explore the web, but content was largely one-way.
Businesses recognised the potential and rushed to establish an online presence, sparking the dot-com boom. Venture capitalists invested heavily in any venture with a .com name, assuming every such business would become a global giant (e.g., Peck.com, Boo.com).
Key takeaways
- Tim Berners-Lee introduced HTTP and HTML, enabling the World Wide Web.
- Early websites were static and text-only, accessed via Netscape Navigator or Internet Explorer.
- The dot-com boom was driven by hype and easy venture capital.
The Dot-Com Boom and Bust (Late 1990s–2000)
The rapid growth of internet-based businesses created a bubble. Companies launched websites believing any .com would make money. Around 2000 the dot-com bubble burst, causing a market crash. Businesses built on hype without real substance disappeared. Those with a sound business plan and a unique or well-defined market niche survived and thrived — e.g., Amazon and Google. In India, early players like Rediff (email & news) and Naukri (job search) were part of this wave.
Key takeaways
- The bubble burst eliminated companies with no real business model.
- Survivors (Amazon, Google) had clear value propositions and sustainable plans.
- Indian examples: Rediff and Naukri.
Post-Crash Maturation & Rise of Digital Business (2000s)
After the crash, digital businesses matured, becoming user-focused. Global platforms like Google, Facebook, and YouTube redefined search, social connection, and content sharing. In India:
- MakeMyTrip (founded 2000) transformed travel booking.
- Shaadi.com brought matchmaking online.
- Flipkart (founded 2007) started as an online bookstore and expanded into a full e-commerce platform.
Key takeaways
- Focus shifted from hype to real user value.
- Indian startups addressed local needs (travel, matrimony, e-commerce).
- Flipkart’s growth showed the potential of Indian e-commerce.
Mobile & Social Media Era (2010s)
The launch of the iPhone in 2007 made internet access mobile and always available via apps. In India, Reliance Jio (2016) offered affordable data plans, bringing fast internet to millions and accelerating digital adoption. WhatsApp became India’s primary messaging app; Paytm led digital payments. Social media platforms (Facebook, Instagram, Twitter) connected people in real time, influencing trends, culture, and politics. Businesses used these platforms for direct customer engagement and real-time brand loyalty.
Key takeaways
- Smartphones (iPhone) made internet ubiquitous; apps became the primary interface.
- Reliance Jio dramatically lowered data costs, expanding Indian internet users.
- Social media enabled direct business-to-consumer engagement.
UPI & India’s Digital Payment Revolution
The Unified Payments Interface (UPI), launched in 2016, revolutionised cashless transactions. Apps like PhonePe, Google Pay, and Paytm adopted UPI, making payments quick and seamless. Today UPI processes billions of transactions monthly, positioning India as a global leader in digital payments.
Key takeaways
- UPI made digital payments instant, simple, and interoperable.
- Apps like PhonePe and Google Pay drove mass adoption.
- India became a world leader in digital payment volume.
Cloud Computing, Big Data & the Modern Indian Digital Ecosystem
As digital businesses scaled, cloud computing (AWS, Microsoft Azure, Google Cloud) removed the need for physical servers. Indian startups like Swiggy (food delivery), Zomato, and Ola (cab booking) leveraged cloud and data analytics to deliver real-time services without heavy infrastructure investment. Big data — collected from searches, social media, and transactions over 30+ years — became a crucial resource for training modern AI systems and delivering personalised services.
Key takeaways
- Cloud computing enabled startups to scale without owning servers.
- Big data drives AI and personalisation.
- Indian startups (Swiggy, Zomato, Ola) exemplify cloud-powered local services.
Internet’s Lasting Impact on Businesses & Daily Life
The internet now touches every industry: retail, entertainment, education, finance. Traditional businesses have moved online; digital-first companies like Swiggy, Hotstar (streaming), and Zerodha (stock trading) have created entirely new markets. Digital marketing, e-commerce, and cloud services are essential for all businesses — even small ones need an online presence to reach customers. Since the 1990s, the internet has transformed how people communicate, learn, shop, work, and do business globally and in India.
Exam tip: The dot-com bust is a classic case study: survivorship depended on real business models, not hype. Know the distinction between survivors (Amazon, Google) and failures (Peck.com). Also note UPI as a uniquely Indian innovation that accelerated digital payments.
Key takeaways
- The internet has reshaped every major industry globally and in India.
- Digital-first companies (Swiggy, Hotstar, Zerodha) created new markets.
- Modern businesses require an online presence regardless of size.
JavaScript DOM Manipulation
What is the DOM?
The Document Object Model (DOM) is the bridge between JavaScript and a webpage. It is a structured, object-oriented representation of the HTML content that the browser creates when a page loads. The DOM treats the HTML document as a tree of nodes, where each HTML element becomes a JavaScript object.
Without the DOM, JavaScript would have no way to interact with the page. With the DOM, we can:
- Change text and attributes without reloading
- Show or hide elements based on user actions
- Create animations and effects
- Build interactive components (forms, sliders, etc.)
Examples from real sites — Amazon’s live cart count, social media comment updates, reaction buttons — all rely on JavaScript manipulating the DOM.
Exam tip: The DOM is language-independent (used by Python, Ruby, etc.), but in web development we interact with it purely through JavaScript in the browser.
DOM Tree Structure
Every time an HTML page is loaded, the browser builds a tree of objects. Each HTML element becomes a node; relationships between nodes (parent, child, sibling) define the tree’s hierarchy.
graph TD
document["document (root)"] --> html["html"]
html --> head["head"]
html --> body["body"]
head --> title["title"]
head --> meta["meta"]
body --> h1["h1"]
body --> p["p"]
p --> ol["ol"]
ol --> li1["li"]
ol --> li2["li"]
ol --> li3["li"]
body --> h2["h2"]
body --> p2["p"]
- The document object is the top-level entry point (parent of everything).
- Every node has properties like
children,parentNode,nextSibling. - Each node is a full JavaScript object with its own properties and methods.
The Document Object
The document object is created automatically by the browser when the page loads. It can be accessed directly in the console or in scripts.
console.log(document); // shows the HTML representation
console.dir(document); // shows the JavaScript object with all properties
console.dir(document) reveals a massive object with properties such as:
| Property | Description |
|---|---|
title | The page <title> text |
body | The <body> element object |
children | HTMLCollection of top-level children (usually <html>) |
all | All elements in the document |
URL | Current page URL |
anchors | Collection of anchor (<a>) elements |
head | The <head> element object |
forms | Collection of <form> elements |
These properties themselves are objects that can be drilled into with dot notation:
document.body.children // HTMLCollection of <header>, <main>, <script>, etc.
document.body.children[0] // first child of <body>
document.title // returns the page title string
Navigating the DOM
Because the DOM is a tree, you can traverse it step by step:
document.body.children // direct children of <body>
document.body.children[1] // second child (often <main>)
document.body.children[1].children[0] // first child of <main>
Each node also has properties for relationships:
parentNodefirstChildlastChildnextSiblingpreviousSibling
Exam tip:
childrenreturns only element nodes (ignoring text/whitespace). UsechildNodesto get all node types.
Manipulating Elements (Quick Examples)
Once you have a reference to a DOM node, you can change its content or style in real time.
Change text content:
document.body.children[1].children[0].innerText = "Haha you are hacked!";
Change background color:
document.body.style.backgroundColor = "yellow";
Change inner HTML (includes tags):
element.innerHTML = "<strong>New content</strong>";
These simple manipulations show the power of the DOM: no page reload needed.
Key takeaways
- The DOM is a tree of JavaScript objects representing the HTML structure.
documentis the entry point – everything starts from it.- Every element is an object with properties (e.g.,
title,body,children) and methods (e.g.,style,innerText). - Use
console.dir(document)to explore the live DOM object. - Navigate using dot notation and index-based
children. - Manipulation is immediate – change text, HTML, or CSS on the fly.
Connecting JavaScript to HTML
To manipulate a web page with JavaScript, you must first link the JS code to the HTML document. Without this connection, the browser cannot run your scripts or interact with the DOM.
Three ways to embed JavaScript
| Method | How it works | Best for | Pitfalls |
|---|---|---|---|
| Inline | Code placed directly inside an HTML element’s event attribute, e.g., onclick="alert('Hi')" | Quick tests of single-line actions | Mixes logic with markup; quotation mark conflicts; unreadable as project grows |
| Internal | Code written inside a <script> tag in the HTML file (in <head> or <body>) | Small projects or one-off scripts | Still couples JS with HTML; not reusable across pages |
| External | Code in a separate .js file, linked via <script src="file.js"> | All real-world projects | Requires correct file path and placement |
Exam tip: Never use inline JavaScript in production. It violates separation of concerns, becomes unmanageable, and confuses quote nesting — exactly like mixing inline CSS into HTML.
Where to place the <script> tag
Script placement determines when the JS code runs relative to the HTML elements it needs to interact with.
flowchart TD
A[Script placed in <head>] --> B[JS runs before HTML body loads]
B --> C{Target element exists?}
C -->|No| D[Error: cannot read property of null]
C -->|Yes – e.g. script in <body> after elements| E[Works fine]
F[Script placed at bottom of <body>] --> G[HTML loads first]
G --> H[All elements exist when JS runs]
H --> I[Safe to query and manipulate DOM]
- Best practice: place the
<script>tag just before the closing</body>tag. This ensures all DOM nodes are created before JS tries to access them. - Result: no null-reference errors and faster perceived load time (HTML renders first, JS executes after).
Worked example: script in <head> vs. <body>
Given HTML with <h1>Original</h1> and a script that tries to change it:
<!-- BAD: script in <head> -->
<head>
<script>
document.querySelector('h1').innerText = 'Changed'; // runs before <h1> exists → null error
</script>
</head>
<!-- GOOD: script at bottom of <body> -->
<body>
<h1>Original</h1>
<!-- ... -->
<script>
document.querySelector('h1').innerText = 'Changed'; // works fine
</script>
</body>
Key takeaways
- Inline JS is quick but messy — avoid beyond one-liners.
- External JS (separate
.jsfile) is the cleanest, most reusable method. - Place
<script>at the bottom of<body>to guarantee all elements are loaded. - Placing scripts in
<head>frequently causesnullerrors when the script attempts to access DOM elements that don't exist yet.
Selecting DOM Elements
Before you can modify a web page, you must select the element(s) you want to interact with. JavaScript provides several methods on the global document object to do this.
Old-style selectors (still valid but less flexible)
| Method | Returns | Example | Notes |
|---|---|---|---|
document.getElementById('id') | Single element | document.getElementById('main-paragraph') | IDs must be unique; fast |
document.getElementsByClassName('class') | HTMLCollection (live, array-like) | document.getElementsByClassName('main-div') | Index with [0] to get first |
document.getElementsByTagName('tag') | HTMLCollection | document.getElementsByTagName('li') | Use index to access specific item |
HTMLCollection is a live collection – it updates automatically when the DOM changes. It does not have forEach or other array methods (though you can convert it with Array.from).
Modern, powerful selector: querySelector and querySelectorAll
These methods accept any CSS selector string, making them far more flexible.
| Method | Returns | Example |
|---|---|---|
document.querySelector(selector) | First matching element (or null) | document.querySelector('.main-div') |
document.querySelectorAll(selector) | NodeList (static, array-like) | document.querySelectorAll('li img') |
NodeList is static (does not update when DOM changes) and supports forEach directly.
CSS selector examples (same as in stylesheets)
// By ID (use #)
document.querySelector('#main-paragraph')
// By class (use .)
document.querySelector('.main-div')
// By tag name
document.querySelector('h1')
// Descendant
document.querySelectorAll('.main-div img')
// Complex: image inside an li
document.querySelectorAll('li img')
Exam tip: Prefer
querySelectorandquerySelectorAllover old methods. They are more powerful, easier to remember (use CSS syntax you already know), and cover every selection scenario.
Assigning selections to variables
Once selected, you can store the element reference in a variable and reuse it.
const paragraph = document.getElementById('main-paragraph');
paragraph.innerText = 'Modified text';
paragraph.style.backgroundColor = 'brown';
Why use const for DOM elements?
Variables assigned to objects (including DOM elements) store a reference to the object, not a copy. Using const prevents accidental reassignment of the variable to a different element, but still allows you to change the element's properties.
const arr = [1, 2];
arr[0] = 23; // allowed – array content changes
// arr = [3,4]; // error – cannot reassign a const
const heading = document.querySelector('h1');
heading.innerText = 'New'; // allowed
// heading = somethingElse; // error – keeps reference stable
Key difference: HTMLCollection vs. NodeList
getElementsByClassName/getElementsByTagName→ HTMLCollection (live, noforEach)querySelectorAll→ NodeList (static, hasforEach)
Worked example: changing the first image’s alt text
const images = document.querySelectorAll('img'); // NodeList
images[0].alt = 'ha ha ha'; // change alt of first image
Key takeaways
- Select by ID with
getElementByIdorquerySelector('#id')– always returns a single element. - Select by class/tag with
getElementsByClassName/getElementsByTagNamereturns an HTMLCollection. - Best practice: use
querySelector(first match) andquerySelectorAll(all matches) for any CSS selector. - Store selections in variables – prefer
constfor stability (the element reference is fixed, properties remain changeable). - All selection methods are called on
document(e.g.,document.querySelector()).
DOM Traversing
DOM traversal is the ability to navigate the relationships between elements in the DOM tree — moving to an element's parent, children, or siblings. Think of the DOM as a family tree: each element is a node connected to others. Traversal methods let you target elements based on their position, essential for dynamic web interactions.
Parent Access
parentElement– returns the immediate parent HTML element of the selected element.- Chaining
.parentElementrepeatedly climbs the tree:element.parentElement.parentElementgives the grandparent.
- Chaining
const h2 = document.querySelector('h2');
h2.parentElement; // <section>
h2.parentElement.parentElement; // <main>
Note: The root of the tree is
document; its parent isnull.
Children Access
children– returns a liveHTMLCollectionof only HTML child elements (ignores text nodes, comments).- To get all child nodes including text, use
childNodes(rarely needed for traversal).
- To get all child nodes including text, use
const body = document.querySelector('body');
body.children; // [<header>, <main>, <script>, ...]
firstElementChild– first child element.lastElementChild– last child element.childElementCount– number of child elements (equivalent tochildren.length).
body.firstElementChild; // <header>
body.lastElementChild; // <script>
body.childElementCount; // 3 (example)
Sibling Access
nextElementSibling– the next sibling element (following the same parent).previousElementSibling– the previous sibling element.
Chaining these moves horizontally through the tree.
const divMain = document.querySelector('.main');
divMain.nextElementSibling; // <p>
divMain.nextElementSibling.nextElementSibling; // <button>
divMain.previousElementSibling; // null (if first child)
Visualising Traversal
flowchart TD
A["element"]
A --> B["parentElement"]
A --> C["children"]
A --> D["firstElementChild"]
A --> E["lastElementChild"]
A --> F["nextElementSibling"]
A --> G["previousElementSibling"]
C --> H["childElementCount"]
style A fill:#e1f5fe,stroke:#01579b
style B fill:#fff9c4,stroke:#f57f17
style C fill:#fff9c4,stroke:#f57f17
style D fill:#fff9c4,stroke:#f57f17
style E fill:#fff9c4,stroke:#f57f17
style F fill:#fff9c4,stroke:#f57f17
style G fill:#fff9c4,stroke:#f57f17
style H fill:#f0f4c3,stroke:#827717
Worked Example: Climbing the Tree
Given the HTML structure from the lecture:
<body>
<header>
<div class="main">...</div>
<p>...</p>
<button>...</button>
</header>
<main>
<section>...</section>
<section>...</section>
</main>
</body>
// Start with the first <li> inside a list
const li = document.querySelector('li');
li.parentElement; // <ul>
li.parentElement.parentElement; // <section> or parent container
li.children; // [<br>, <img>] (HTMLCollection)
li.nextElementSibling; // next <li> (if any)
li.previousElementSibling; // previous <li> (if any)
Property Summary
| Property | Returns | Use |
|---|---|---|
parentElement | Single element | Climb one level up |
children | Live HTMLCollection | All child elements |
firstElementChild | Single element | First child |
lastElementChild | Single element | Last child |
childElementCount | Number | Count children |
nextElementSibling | Single element | Move forward |
previousElementSibling | Single element | Move backward |
Exam tip:
childrenreturns only elements, not text nodes. If you need all nodes (including whitespace), usechildNodes. But for traversal, always prefer the element-specific properties — they are robust and what exam questions expect.
Key Takeaways
parentElementclimbs up;children,firstElementChild,lastElementChildgo down.nextElementSibling/previousElementSiblingmove sideways among siblings.childElementCountgives the number of child elements quickly.- Chaining these methods navigates the tree in any direction (up, down, sideways).
- All methods return
nullor empty collections when nothing exists — always check before further chaining.
Modifying Styles and Attributes with JavaScript
JavaScript + the DOM lets you change how a page looks and behaves on the fly — reacting to user actions, time, or any condition. At its core: you grab an element and rewrite its visual presentation or its HTML attributes.
The style Property – Direct Inline Changes
Every DOM element has a .style property that reflects its inline styles. You can read or set any CSS property, but the property names must be written in camelCase (not hyphenated):
| CSS property | JavaScript .style access |
|---|---|
background-color | element.style.backgroundColor |
font-family | element.style.fontFamily |
font-size | element.style.fontSize |
border | element.style.border |
Example – turn the navbar background blue:
const navBar = document.querySelector('nav');
navBar.style.backgroundColor = 'blue';
Values are always strings; include units where needed:
navBar.style.border = '2px solid black';
Limitation:
.styleonly sees and modifies inline styles — it ignores styles from external or internal CSS sheets. If you try to read a property that comes from a stylesheet, you getnull.
Why it’s problematic – Mixes presentation (CSS) with logic (JS), harder to maintain, and cannot read the full computed style of an element.
The classList API – The Right Way to Style
Instead of writing inline styles, define your styles in CSS classes and toggle them with JavaScript. The classList property gives you a DOMTokenList (array-like object) of all classes on an element.
Key methods:
| Method | Effect |
|---|---|
element.classList.add('class-name') | Adds a class |
element.classList.remove('class-name') | Removes a class |
element.classList.toggle('class-name') | Adds if absent, removes if present |
element.classList.contains('class-name') | Returns true/false |
Example workflow:
.sample {
color: green;
background-color: red;
text-decoration: solid;
}
const section = document.querySelector('section');
section.classList.add('sample'); // applies the green/red style
section.classList.remove('sample'); // removes it
section.classList.toggle('sample'); // toggles
console.log(section.classList.contains('sample')); // false (after removal)
Exam tip: Always prefer
classListover.stylefor production code. It keeps styles in CSS, makes debugging easier, and lets you reuse the same class across many elements.
Working with Other Attributes
Every HTML attribute (e.g., href, src, id, alt) can be read or changed using two generic methods:
element.getAttribute('attribute-name')– returns the current value.element.setAttribute('attribute-name', 'new-value')– sets the value (overwrites existing).
Example – change the first link’s href:
const firstLink = document.querySelector('a');
console.log(firstLink.getAttribute('href')); // e.g., "events.html"
firstLink.setAttribute('href', 'https://govind.com');
firstLink.setAttribute('id', 'new-id'); // also works for any attribute
Warning: Using
setAttribute('style', ...)overwrites ALL inline styles – avoid it for styling. UseclassListinstead.
Text Content: innerText , textContent , innerHTML
Three properties control what text (and HTML) lives inside an element. They differ in what they read and how they treat markup.
| Property | What it returns | Security concern | Use case |
|---|---|---|---|
innerText | Visible text only (respects CSS display:none) | Safe | Reading or setting plain visible text |
textContent | All raw text, including hidden text and whitespace | Safe | When you need the full raw string (e.g., for comparison) |
innerHTML | Text plus any nested HTML tags; parses them as elements | Dangerous with user input (XSS) | When you must insert structured HTML (only with trusted content) |
Example – given a list item <li>Only one guest allowed <br> <img src="..."></li>:
const li = document.querySelector('li');
console.log(li.innerText); // "Only one guest allowed" (no br, no image text)
console.log(li.textContent); // "Only one guest allowed \n " (includes newline)
console.log(li.innerHTML); // "Only one guest allowed <br> <img src="...">"
// Setting:
li.innerText = 'Any number of guests'; // Replaces everything (including br/img) with plain text
li.innerHTML = '<span>Hi</span>'; // Inserts a <span> element
Exam tip: Never use
innerHTMLwith user-generated input (comments, search queries). UseinnerTextortextContentto avoid cross-site scripting (XSS) vulnerabilities.
Key takeaways – Styles & Attributes
.stylegives access to inline styles only; property names use camelCase.classListis the preferred way to style via JS –.add(),.remove(),.toggle(),.contains().- Use
getAttribute()andsetAttribute()for any HTML attribute exceptstyle. setAttribute('style', ...)overrides all inline styles – avoid.
Key takeaways – Text Content
innerText– visible text only.textContent– all raw text, including hidden.innerHTML– parses HTML; only use with trusted content.- Setting any of these replaces all children of the element.
DOM Manipulation: Creating, Appending, Removing, and Inserting Elements
DOM manipulation lets you dynamically add, remove, or rearrange elements on a page. Instead of hard‑coding everything in HTML, you use JavaScript to modify the DOM tree at runtime – the engine behind interactive apps and single‑page interfaces.
Creating Elements
Before you can insert an element, you must create it. The method document.createElement(tagName) returns a new, empty DOM node of the given tag (e.g., 'p', 'div', 'span'). It exists only in memory until attached to the page.
Example
const newParagraph = document.createElement('p'); newParagraph.innerText = 'This P was added with JavaScript';
The element is now a node object with an innerText property, but it is not yet visible in the document.
Appending Elements
Once created, an element must be attached to a parent node. Two primary methods exist: appendChild() and the newer, more flexible append().
appendChild(parentNode, childNode)
- Appends one child node to the end of the parent’s children list.
- The child must be a node (e.g., a
pelement created withcreateElement). - Cannot insert text strings directly.
const section1 = document.querySelector('section');
section1.appendChild(newParagraph);
append(parentNode, ...nodesOrStrings)
- Adds one or more children or strings to the end of the parent.
- Strings are converted to text nodes automatically – they are not parsed as HTML.
- More versatile than
appendChild.
const newPara2 = document.createElement('p');
newPara2.innerText = 'Second dynamic paragraph';
section1.append(newPara2, 'Some random text', '<span>this is treated as text, not HTML</span>');
| Method | Accepts multiple children? | Accepts text strings? | Returns |
|---|---|---|---|
appendChild | No (one node at a time) | No | The appended child node |
append | Yes | Yes (as text) | undefined |
Removing Elements
Two ways to delete an element from the DOM: directly on the element itself, or via its parent.
remove() on the Target Element
Simply call element.remove(). No parent reference needed – the element is detached from the DOM.
const listItem1 = document.querySelector('li'); // first <li>
listItem1.remove(); // gone from the page
removeChild() on the Parent Element
Requires both the parent and the child node you want to remove.
const ul = document.querySelector('ul');
const firstChild = ul.firstElementChild;
ul.removeChild(firstChild);
Key difference: remove() is cleaner when you already have a reference to the element; removeChild() forces you to know the parent.
Inserting Elements at Specific Positions
Appending always puts a child at the end. To control exactly where an element appears, use insertBefore() or insertAdjacentElement().
insertBefore(parentNode, newNode, referenceNode)
- Inserts
newNodebeforereferenceNode(which must be a child of the parent). referenceNodeis the sibling before which the new node goes.
const ul = document.querySelector('ul');
const listItem2 = ul.children[1]; // second <li>
const newP = document.createElement('p');
newP.innerText = 'Inserted before second list item';
ul.insertBefore(newP, listItem2);
insertAdjacentElement(position, targetElement, newElement)
- Inserts
newElementat a position relative totargetElement– no parent required. - Four position strings (case‑sensitive):
| Position | Meaning |
|---|---|
'beforebegin' | Before the target element itself (outside) |
'afterbegin' | Inside the target, before its first child |
'beforeend' | Inside the target, after its last child |
'afterend' | After the target element itself (outside) |
flowchart LR
subgraph "targetElement"
direction TB
A1["afterbegin (inside, before first child)"]
A2["content"]
A3["beforeend (inside, after last child)"]
end
B["beforebegin (outside, before target)"]
C["afterend (outside, after target)"]
Example – inserting before and inside:
const li1 = document.querySelector('#adjacent li:first-child');
const pBefore = document.createElement('p');
pBefore.innerText = 'Added beforebegin';
li1.insertAdjacentElement('beforebegin', pBefore);
const li2 = document.querySelector('#adjacent li:nth-child(2)');
const pAfterBegin = document.createElement('p');
pAfterBegin.innerText = 'Added afterbegin';
li2.insertAdjacentElement('afterbegin', pAfterBegin);
Comparison of insertion methods:
| Method | Uses parent? | Positions | Can insert multiple nodes? |
|---|---|---|---|
append / appendChild | Yes | Only end of children | Only append can do multiple |
insertBefore | Yes | Before a specified child | No |
insertAdjacentElement | No (relative to an element) | Four exact positions | No (but call repeatedly) |
Exam tip:
insertAdjacentElementis the most flexible for precise positioning. Remember the four position strings – they are often tested. Note that'beforeend'is inside the element at the end, while'beforebegin'is outside before it.
Key Takeaways
- Use
document.createElement(tagName)to create a new element in memory. appendChild()appends a single node to a parent;append()can add multiple nodes and text strings.element.remove()deletes the element directly;parent.removeChild(child)needs both references.insertBefore(parent, new, ref)places a node before a sibling child.insertAdjacentElement(position, target, new)gives four precise placement options relative to the target element.- Always ensure the target elements exist in the DOM before manipulating them – check for
nullif usingquerySelector.
Event Listeners
Events are signals sent by the browser to JavaScript that something has happened – a user clicked, typed, hovered, or a page finished loading. They are the core mechanism behind interactivity: without events, a webpage is static; with events, JavaScript can react and update the DOM.
How the browser handles events (the flow)
- User triggers an action – e.g., clicks a button, presses a key, scrolls.
- Browser detects the action – creates an event and fires it on the target element.
- JavaScript responds – runs code attached to that event (the listener).
Intuition: Think of events as “when something happens, do something else.” The browser shouts “Hey, button clicked!”, and your JavaScript wakes up and runs the code you wrote for that moment.
Three ways to attach event handlers
| Method | Example | Profile |
|---|---|---|
| Inline HTML (old, messy) | <button onclick="alert('Clicked!')"> | Hard to maintain, mixes HTML & JS, avoid |
| DOM property (better, still not ideal) | button.onclick = function() { … } | Only one handler per event type; overwrites previous |
addEventListener (gold standard) | button.addEventListener('click', handler) | Multiple handlers per event, clean separation, modern |
Exam tip: Interviewers love to ask why
addEventListeneris preferred over the other two. Always mention: it allows multiple listeners, works with all event types uniformly, and doesn’t override existing handlers.
Inline example (don’t use)
<button onclick="alert('I was clicked')">Click me</button>
Property example (not recommended)
const button = document.querySelector('button');
button.onclick = function() {
alert('I was clicked');
};
This works, but if you later assign another onclick, it replaces the first.
addEventListener – the modern way
Syntax:
element.addEventListener(type, listener);
type– a string naming the event (e.g.'click','mouseover','keydown').listener– a callback function that runs when the event occurs. This function automatically receives an event object as its first argument.
Worked example (background colour change)
Given a <button> in the HTML:
<button type="button">Change background</button>
Step 1 – Define the handler function (using classList is best practice):
function changeBg() {
document.body.classList.add('bg-blue');
}
With CSS:
.bg-blue { background-color: blue; }
Step 2 – Attach the listener:
const button = document.querySelector('button');
button.addEventListener('click', changeBg);
Now clicking the button applies the class.
Alternative – anonymous function (also works):
button.addEventListener('click', function() {
document.body.style.backgroundColor = 'cyan';
});
Alternative – arrow function (modern):
button.addEventListener('click', () => {
document.body.style.backgroundColor = 'cyan';
});
Exam tip: Named functions are more readable and reusable; anonymous functions are convenient for one-off logic. Arrow functions do not have their own
this(important for certain contexts like object methods).
The Event Object
When the listener runs, JavaScript automatically passes an event object as the first argument to the callback. You can name it anything (common names: e, event, evt).
button.addEventListener('click', function(e) {
console.log(e); // entire event object (e.g., PointerEvent)
console.log(e.target); // the element that triggered the event
console.log(e.currentTarget); // the element the listener is attached to
});
e.target– the element that was actually clicked (useful if you have nested elements).e.currentTarget– the element the listener is attached to (often the same, but differs with event delegation).
Common event types (selected)
| Category | Events | When fired |
|---|---|---|
| Mouse | click, dblclick, mouseover, mouseout, mousedown, mouseup, contextmenu (right-click) | Cursor interactions |
| Keyboard | keydown, keyup, keypress (deprecated) | Key presses |
| Form | submit, change, input, focus, blur | Form field interactions |
| Document / Window | DOMContentLoaded, load, scroll, resize | Page lifecycle |
| Touch | touchstart, touchend, touchmove | Touchscreen devices |
A full reference is maintained on MDN: Event reference.
Exam tip: For mouse events, remember
click=mousedown+mouseupon the same element. For keyboard events,keydownfires repeatedly while holding a key;keyupfires once on release.
Key takeaways
- An event is a signal that something happened; event listeners let JavaScript react.
- Three attachment methods exist;
addEventListeneris the gold standard. addEventListener(type, listener)–typeis a string,listeneris a callback.- The callback receives an event object providing details (e.g.,
e.target). - Named functions, anonymous functions, and arrow functions all work as listeners.
- Always separate JS from HTML; never use inline
onclickattributes in production.
Painting Website
This project ties together HTML, CSS, and JavaScript (DOM manipulation, events, loops) to build an interactive painting canvas. The goal: hover over a grid of pixel‑divs and color them, but only while holding the Alt key — simulating a brush. The project also demonstrates event delegation for performance when handling thousands of child elements.
1. HTML Structure
Minimal markup: a color input, a paragraph of instructions, and a container <div> that will hold the pixel grid. All pixels are created dynamically with JavaScript.
<h1>Painting Canvas</h1>
<label for="color">Select Color</label>
<input type="color" id="color" value="#000000">
<p>Press Alt + move over canvas to paint</p>
<div class="container"></div>
2. CSS Grid Canvas
The container is turned into a responsive grid. Each grid cell is a “pixel” — a <div> with class .pixel. The grid uses 1fr columns so the canvas scales.
.container {
border: 2px solid black;
display: grid;
grid-template-columns: repeat(150, 1fr);
width: 75vw;
height: 60vh;
}
Why 150 columns? Creates small square cells. With 5000 total pixels, we get about 30 rows.
3. JavaScript: Creating Pixels Dynamically
A loop generates 5000 <div> elements, each with a unique id and class pixel. They are appended to the container.
const canvas = document.querySelector('.container');
for (let i = 0; i < 5000; i++) {
const pixel = document.createElement('div');
pixel.setAttribute('id', i + 1);
pixel.setAttribute('class', 'pixel');
canvas.appendChild(pixel);
}
4. Adding Event Listeners (Inefficient Approach)
The naive way: attach a mouseover listener to every pixel inside the loop. When the event fires, a function runs that:
- Checks if the Alt key was pressed (
event.altKey). - Reads the current value of the color input (
document.querySelector('#color').value). - Sets the
background-colorof the pixel that triggered the event (usingevent.currentTarget).
pixel.addEventListener('mouseover', function(e) {
if (e.altKey) {
const color = document.querySelector('#color').value;
e.currentTarget.style.backgroundColor = color;
}
});
Why
e.currentTarget? It refers to the element on which the listener was attached — in this case, the individual pixel.e.targetwould also work here because there’s no nesting inside the pixel.
5. The Better Way: Event Delegation
Attaching 5000 listeners is wasteful. Instead, use event bubbling — set a single listener on the parent container. Events that occur on any child pixel bubble up to the container. Then inside the handler, use e.target to identify the actual pixel that was hovered.
canvas.addEventListener('mouseover', function(e) {
if (e.altKey && e.target.classList.contains('pixel')) {
const color = document.querySelector('#color').value;
e.target.style.backgroundColor = color;
}
});
Event Bubbling vs. Capturing
flowchart LR
A[Pixel clicked] --> B[Pixel event handler]
B --> C[Container event handler]
C --> D[Body event handler]
style A fill:#ddd
style B fill:#ddd
style C fill:#9cf
style D fill:#9cf
- Events bubble from the target element up through its ancestors.
e.target= the element that originally triggered the event (the pixel).e.currentTarget= the element with the event listener (the container, in the delegation version).
Exam tip: Event delegation is the standard way to handle events on many dynamic children. It saves memory and works even for elements added after the listener is attached.
6. Conditional Painting (Alt Key)
Only color a pixel when the Alt key is held down. This prevents accidental scribbling. The property e.altKey is true if the Alt key was pressed when the event fired.
if (e.altKey) {
// apply color
}
7. Worked Example (Step‑by‑Step Flow)
- User selects a color (e.g., green) from the
<input type="color">. - User holds the Alt key and moves the mouse over the canvas.
- A
mouseoverevent fires on a pixel div. - The event bubbles to the container, which has the listener.
- The handler checks:
e.altKey === trueande.targetis a.pixel. - It reads
document.querySelector('#color').value(which is"#00ff00"at that moment). - It sets
e.target.style.backgroundColor = "#00ff00".
8. Key Concepts Summarised
| Concept | Explanation |
|---|---|
Event object (e) | Contains properties like target, currentTarget, altKey, button. |
e.target | The element on which the event originally occurred (the pixel). |
e.currentTarget | The element on which the listener was attached (container in delegation). |
| Event bubbling | Default behaviour where an event propagates from child to parent elements. |
| Event delegation | Technique of listening on a parent for events that bubble from children, improving performance and allowing dynamic elements. |
9. Connection to Previous Modules
- HTML/CSS: Grid layout, selectors, styling.
- Module 6 (JS Basics): variables, loops (
for), functions, callback functions (used as event handlers). - Module 7: DOM selection (
querySelector), element creation (createElement), attribute setting (setAttribute), appending children, modifying inline styles.
Key Takeaways
- Use a
<div>container with CSS grid to create a pixel canvas. - Generate grid cells dynamically with a loop to avoid hard‑coding HTML.
- Apply color only when a modifier key (e.g., Alt) is held — check
event.altKey. - Event delegation (listener on the parent) is far more efficient than attaching listeners to every child.
e.target(the originated element) vse.currentTarget(the listener’s element) is a common exam distinction.- This project integrates loops, functions, DOM manipulation, and events — typical of interactive web pages.
Overview: The Typewriter Effect
The goal is to display sentences one by one, each typed out character by character, then erased character by character before the next sentence appears. A blinking cursor sits at the end of the typed text. The animation starts automatically when the page loads — no user interaction required.
The key insight: this is a continuous loop that must not block the browser. We achieve it by combining recursive functions (a function calling itself with a delay) and JavaScript’s asynchronous timing methods (setTimeout, setInterval).
The Building Blocks
| Component | HTML Element | Purpose | CSS Class Used |
|---|---|---|---|
| Static prefix | <span> (e.g. "IIMB") | Always visible | — |
| Animated text | <span id="animated"> | Holds the typed/erased string | — |
| Blinking cursor | <span id="cursor"> | Vertical bar (` | `) that toggles visibility |
Delay functions in JavaScript
setTimeout(fn, delay)– Executesfnonce afterdelaymilliseconds.setInterval(fn, delay)– Executesfnrepeatedly everydelaymilliseconds.
Both accept a callback function as an argument. They do not block the main thread — they run asynchronously. Without this, an infinite loop would freeze the page.
Step-by-step Construction
1. Blinking Cursor with setInterval
const cursor = document.querySelector('#cursor');
function toggleCursor() {
cursor.classList.toggle('hidden'); // toggles display: none
}
setInterval(toggleCursor, 500); // blink every 0.5s
- The
.hiddenclass setsdisplay: none. setIntervalkeeps callingtoggleCursor→ cursor appears and disappears.
2. Wait for DOM to be ready
document.addEventListener('DOMContentLoaded', startAnimation);
- The event
DOMContentLoadedfires when the HTML is fully parsed. - Only then do we start the animation (calling
startAnimation, which triggers both cursor blinking and the typewriter).
3. Typewriter Logic: Recursion with setTimeout
The problem: a regular for loop would print all characters instantly — no delay.
Solution: use a recursive function that calls itself via setTimeout.
Data
sentences = ["Lay the foundation to web development.", "The best institute in the world.", "Learn to live your life happily and keep being curious."]sentenceCounter(0..2 → cycles with modulo)charCounter(0..length-1)
State diagram (conceptual)
flowchart TD
A[Add characters] --> B{charCounter < sentence.length?}
B -- Yes --> C[Append next character to animated span]
C --> D[Increment charCounter]
D --> E[setTimeout A, 100ms]
B -- No --> F[Pause 2s, then call Remove characters]
F --> G[Remove characters]
G --> H{charCounter > 0?}
H -- Yes --> I[Slice off last character]
I --> J[Decrement charCounter]
J --> K[setTimeout G, 20ms]
H -- No --> L[Reset charCounter = 0, increment sentenceCounter]
L --> M[setTimeout A, 100ms]
M --> A
Key implementation details
- Printing:
animatedSpan.textContent += sentence[sentenceCounter][charCounter] - Erasing:
animatedSpan.textContent = animatedSpan.textContent.slice(0, -1) textContent(notinnerText) preserves spaces correctly.- Use
setTimeoutinside the recursive call — neversetIntervalfor one-shot steps. The lecture initially usedsetIntervalby mistake, causing infinite rapid re‑calls.
4. Achieving the infinite loop with modulo
When a sentence is fully erased, we need to move to the next sentence:
sentenceCounter = (sentenceCounter + 1) % sentences.length;
%(modulo) keeps the counter within0..2, wrapping back to 0 after the last sentence.
Worked example: First iteration
Initial state: sentenceCounter = 0, charCounter = 0, sentences[0] = "Lay..."
-
addCharactersruns:charCounter (0) < "Lay...".length→ true- Append
sentences[0][0]→"L" charCounter++→ 1setTimeout(addCharacters, 100)
-
After 100ms:
- Append
"a"→"La" charCounter = 2setTimeout(addCharacters, 100)
- Append
… continues until charCounter reaches 37 (length of first sentence).
-
Then:
charCounter >= length→setTimeout(removeCharacters, 2000)→ pause 2 seconds
-
removeCharacters:charCounter = 37> 0- Slice off last char →
"Lay ... developmen" charCounter--→ 36setTimeout(removeCharacters, 20)
… fast removal at 20ms per character until charCounter = 0.
- When
charCounter = 0:sentenceCounter = (0 + 1) % 3 = 1→ next sentencecharCounter = 0setTimeout(addCharacters, 100)
The cycle repeats forever.
Asynchronous behaviour
setTimeoutandsetIntervalare non‑blocking. The JavaScript event loop schedules them; the main thread continues running other code (e.g. user clicks).- Without asynchronous delay, an infinite loop would freeze the browser tab.
Exam tip: The difference between
setTimeout(one‑shot) andsetInterval(repeated) is a common trick question. In recursive animation we usesetTimeoutinside the function to create a controlled delay between steps. Confusing them leads to bugs like the “super fast” loop demonstrated in the lecture.
Connecting the pieces
The final animation runs two independent async loops:
- Cursor blink –
setInterval, simple toggle every 500ms. - Typewriter – recursive
setTimeoutchain for add/erase, with state updated via counters and modulo.
Both are started synchronously inside startAnimation(), triggered by DOMContentLoaded.
Key takeaways
- Typewriter animations are built character‑by‑character using recursive
setTimeout, not synchronous loops. setIntervalis appropriate for repeated actions (blinking);setTimeoutfor one‑shot delays inside recursion.- Modulo arithmetic (
%) elegantly cycles through an array without extra checks. textContentcorrectly handles whitespace;innerTextsometimes omits it.- Asynchronous timing keeps the page responsive — the animation does not block user interactions.
- Professional result achieved with just a few concepts: DOM selection, class toggle, string slicing, counters, and delay functions.