CSS controls how a web page looks: colour, spacing, fonts and layout. This course starts with how a rule is written and builds up to modern layout with Flexbox, Grid and responsive design.
It works best if you already know basic HTML, but each lesson explains what it needs. Keep a page open in your browser and change the values as you read; seeing the page react is the fastest way to understand CSS.
1. What is CSS? (start here)
The language that makes web pages look good.
In the HTML course you learned that HTML describes what is on a page: headings, paragraphs, images. Without anything else, those elements look plain: black text on a white background, in a default font.
CSS (Cascading Style Sheets) controls how it looks: colours, fonts, sizes, spacing, borders, layout, even animations. The same HTML can look completely different just by changing the CSS.
An easy comparison is a house. HTML is the building: walls, doors, windows. CSS is the paint, the furniture, and where everything is placed.
<h1>Hello</h1>Plain HTML on its own
.title {
color: rebeccapurple;
text-align: center;
font-size: 48px;
}The same heading with three lines of CSS: purple, centred and big
"Cascading"
The word cascading means styles flow down and combine. If one rule says "all text is grey" and another says "this heading is red", the heading ends up red because the more specific rule wins. You will learn exactly how in the lesson on the cascade.
What you will learn in this course
- How a CSS rule is written
- Colours, text, and sizes
- The box model: how every element is a box with space around it
- Borders, rounded corners and shadows
- Spacing with margin
- Flexbox: lining things up and centring them
title) and a paragraph (class note). Whatever CSS you write is applied to them, so you see every change at once.- CSS controls the look of an HTML page.
- HTML is the structure, CSS is the style.
- The same HTML can look totally different with different CSS.
2. How CSS meets HTML
Where to write your CSS, and what a rule looks like.
There are three ways to add CSS to a page. You will mostly use the third.
<p style="color: tomato;">Red text</p>1. Inline: a style attribute on one element (avoid for anything big)
<head>
<style>
p { color: tomato; }
</style>
</head>2. Internal: a style element inside the head of the page
<head>
<link rel="stylesheet" href="style.css">
</head>3. External: a separate .css file, linked from the head (best for real websites)
An external file keeps your style in one place, and many pages can share it. Change the file once and every page updates.
The shape of a CSS rule
Every piece of CSS is a rule:
selector {
property: value;
property: value;
}The anatomy of a rule
- The selector says which elements to style. For example
pmeans "every paragraph". - Inside curly braces
{ }are one or more declarations. - A declaration is a property (what to change, like
color) then a colon, then a value (what to change it to, liketomato), and ends with a semicolon;.
.title {
color: tomato;
}A real rule: make the title tomato red
: and the semicolon ;. A missing semicolon is the number one cause of "my CSS stopped working".- CSS can be inline, internal (style element), or external (a .css file).
- A rule = selector + { property: value; }.
- Always end each declaration with a semicolon.
3. Selectors and colours
Choosing what to style, and painting it.
A quick word on selectors
A selector decides which elements a rule applies to. The two you need first:
- A type selector is just an element name:
p,h1,button. It matches every element of that type. - A class selector starts with a dot:
.titlematches every element that hasclass="title".
Classes are the main tool, because you can put the same class on many elements, and one element can have several classes.
Text colour
The color property sets the text colour. You can write colours in several ways:
.title {
color: tomato; /* a colour name */
}
.note {
color: #8b5cf6; /* hex code */
}Two ways to write a colour: a name and a hex code
- Names:
red,tomato,rebeccapurple,navyand about 140 others. - Hex codes:
#rrggbb. Each pair is the amount of red, green and blue from00(none) toff(full).#ff0000is pure red,#000000is black,#ffffffis white.#fa0is a short form of#ffaa00. - rgb():
rgb(255, 99, 71)is the same tomato, with each number from 0 to 255. - hsl():
hsl(9, 100%, 64%)describes a colour by hue, saturation and lightness. Many people find it the easiest to tweak.
Background colour
background-color (or the short background) paints behind the element.
.title {
color: white;
background-color: #1e293b;
}Colour and background together
- A selector chooses elements. .name picks everything with that class.
- color sets text colour; background-color sets the paint behind.
- Colours can be names, hex codes, rgb() or hsl().
4. Selectors in more depth
Picking exactly the elements you want.
Selectors are the "aim" of CSS. Here are the ones you will use all the time.
p { color: #334155; } /* every paragraph */
.note { color: tomato; } /* anything with class="note" */
#hero { color: navy; } /* the one element with id="hero" */Type, class, id
- Type selector:
p,h1. Matches by element name. - Class selector:
.note. Reusable. This is your everyday tool. - ID selector:
#hero. Matches the single element with that id. Because ids are unique, they are less flexible than classes.
Grouping
If several selectors share the same declarations, list them with commas.
.title, .note {
font-family: Georgia, serif;
}One rule for two selectors
Descendant selector
Two selectors separated by a space mean "the second one, but only inside the first".
nav a {
color: white;
}Only links that are inside a nav
Pseudo-classes
A pseudo-class is a state of an element. It starts with a colon. The most common is :hover, which applies while the mouse is over the element.
.note:hover {
background: #fde68a;
}The note turns yellow when the mouse is over it
Which should I use?
Use classes for almost everything. Use type selectors for page-wide defaults (like body or p). Avoid ids for styling.
- Type (p), class (.note), id (#hero).
- Commas group selectors; a space means "inside".
- :hover and other pseudo-classes style a state.
5. Text alignment and text style
Where text sits, and how it looks.
text-align controls how text lines up inside its box: left (the default), right, center, or justify (stretch lines to the full width).
.title {
text-align: center;
}Centre the title
More text properties
font-weight:normal,bold, or a number like600.font-style:italicornormal.font-family: the typeface. List fallbacks in order:font-family: Georgia, serif;. The browser uses the first one that is available.line-height: the space between lines.1.5means one and a half times the font size. It makes paragraphs much easier to read.text-decoration:underline,line-through, ornone(the way to remove the underline from links).text-transform:uppercase,lowercaseorcapitalize.letter-spacing: space between letters.
.note {
font-family: Georgia, serif;
font-weight: bold;
line-height: 1.6;
text-transform: uppercase;
letter-spacing: 1px;
}Several text properties together
One thing to know
text-align aligns the text inside the box. It does not move the box itself. Moving the box is done with margin or flexbox, which come later.
- text-align: left, right, center, justify.
- font-weight, font-family, line-height and text-decoration shape the text.
- text-align moves text inside its box, not the box.
6. Units and text size
Making things bigger or smaller.
font-size sets how big text is. Every size needs a unit after the number.
.note {
font-size: 22px;
}A 22 pixel note
The units you need
px(pixels): an exact size. One pixel is one dot on the screen (more or less). Easy to understand.rem: relative to the page's base font size, which is usually 16px.1rem= 16px,1.5rem= 24px,2rem= 32px. It respects the user's browser settings, so it is the best choice for text.em: relative to the parent element's font size. Handy but trickier.%: a percentage of something else, often the parent's size.vw/vh: 1% of the browser window's width or height.
.title {
font-size: 2.5rem; /* 40px by default */
}
.note {
font-size: 1.25rem; /* 20px by default */
}rem scales with the user's settings
Which unit when?
- Text:
rem. - Borders, shadows, tiny details:
px. - Widths that should adapt to the screen:
%orvw.
font-size: 20;) is invalid, and the browser ignores it. The only exception is 0, which needs no unit.- Every size needs a unit: px, rem, em, %, vw, vh.
- rem is based on the base font size (16px by default). Great for text.
- A number without a unit is ignored.
7. The box model
Every element is a box.
This is the most important idea in CSS. Every element on a page is a rectangular box, and every box has four layers, from the inside out:
- Content: the text or image itself.
- Padding: space inside the box, between the content and the border.
- Border: a line around the padding.
- Margin: space outside the border, pushing other boxes away.
Picture a framed photo on a wall. The photo is the content. The white card around it is the padding. The frame is the border. The gap to the next frame on the wall is the margin.
.note {
background: #fef3c7;
padding: 16px;
}Padding and a background colour make a card
The background colour fills the content and the padding (up to the border). That is why padding is the quickest way to make something look like a card: the colour gets room to breathe around the text.
Writing padding
padding: 16px; /* all four sides */
padding: 8px 24px; /* top and bottom 8px, left and right 24px */
padding: 4px 8px 12px 16px; /* top, right, bottom, left (clockwise) */
padding-left: 20px; /* one side only */Padding shorthand
Width and the box
By default, width sets only the content width. Padding and border are added on top, so a width: 200px box with padding: 20px is really 240px wide. Many developers switch this off with a rule that makes width include padding and border:
* {
box-sizing: border-box;
}A common reset
- Content, padding, border, margin: from inside to outside.
- Padding is inside the border; margin is outside.
- Background colour covers content and padding.
- box-sizing: border-box makes width include padding and border.
8. Borders and rounded corners
Outlines and soft shapes.
A border is a line drawn around an element. It needs three values: width, style and colour.
.note {
border: 2px solid orange;
}A 2px solid orange border
- Width:
1px,2px,4px... - Style:
solid,dashed,dotted,double, ornone. - Colour: any colour value.
If you set a border style of none (which is the default), the border is not drawn at all. That is why you must always include the style when you use the long form.
Single sides
border-bottom: 3px solid navy; draws a line on one side only. There are also border-top, border-left and border-right.
Rounded corners
border-radius softens the corners. Larger numbers mean rounder corners.
.note {
border: 2px solid #f59e0b;
border-radius: 12px;
}Soft corners with a visible border
border-radius: 8px;a gentle curve, great for cards.border-radius: 50%;on a square makes a circle.border-radius: 999px;on a button makes a "pill" shape.
- border: width style colour.
- Without a style (solid, dashed...) the border does not show.
- border-radius rounds corners; 50% on a square makes a circle.
9. Shadows
Depth for cards and buttons.
box-shadow draws a soft shadow behind an element so it looks lifted off the page.
.note {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}A soft shadow below the note
The values, in order:
- x offset: how far the shadow moves right (negative moves left).
0means no sideways shift. - y offset: how far it moves down (negative moves up).
4pxpushes it down. - blur: how soft the edge is. Bigger is softer.
- colour: usually a transparent black.
rgba(0, 0, 0, 0.2)is black at 20% opacity.
rgba and transparency
rgba(red, green, blue, alpha) is like rgb() with a fourth number from 0 (invisible) to 1 (solid). Semi-transparent shadows look natural because the background shows through.
Tips for good shadows
- Subtle looks better: low opacity (0.1 to 0.25) and generous blur.
- Use more than one shadow by separating them with a comma.
- A shadow does not take up space. It never pushes other elements around.
.note {
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2), 0 8px 24px rgba(0, 0, 0, 0.15);
}Two shadows: a sharp small one and a soft big one
- box-shadow: x y blur colour.
- Use rgba() for a see-through colour.
- Shadows do not affect layout.
10. The cascade, inheritance and specificity
Why a style wins or loses.
Sometimes you write a rule and nothing happens. Usually another rule won. CSS decides in this order.
1. Inheritance
Some properties pass down from parent to child automatically. If you set color on body, every paragraph inside it gets that colour too. Text properties (color, font-family, line-height) are inherited. Box properties (margin, padding, border, background) are not.
body {
font-family: Georgia, serif;
color: #1e293b;
}Set once on body; everything inside inherits it
2. Specificity
When two rules target the same element and property, the more specific selector wins. From weakest to strongest:
- type selector (
p) - class selector (
.note) - id selector (
#hero) - inline
styleattribute
p { color: blue; }
.note { color: red; }The class beats the type, so the note is red
3. Order
If two rules are equally specific, the later one wins.
.note { color: red; }
.note { color: green; }Same specificity: the last rule wins, so green
Debug it
In your browser's Inspect tool, select the element. The Styles panel lists every rule that touches it and shows overridden ones crossed out.
!important. It forces a rule to win, but it makes your CSS hard to change later.- Text properties are inherited; box properties are not.
- More specific selectors win: type < class < id < inline.
- Equal specificity: the later rule wins.
11. Margin: space between boxes
Pushing elements apart.
padding is the space inside a box. margin is the space outside it, and it pushes neighbouring boxes away.
.note {
margin-top: 24px;
}Push the note 24px away from the title above it
You can set each side, or use the shorthand just like padding:
margin: 16px; /* all sides */
margin: 8px 24px; /* top and bottom, then left and right */
margin: 0 auto; /* no vertical margin, centre horizontally */
margin-top: 24px;
margin-bottom: 0;Margin shorthand
Centring a block
If a block has a fixed width, setting its left and right margins to auto centres it horizontally in its parent.
.note {
width: 300px;
margin: 0 auto;
}A centred box 300px wide
Margin collapse
When the bottom margin of one block touches the top margin of the next, the browser does not add them. It uses the larger of the two. This is called margin collapse, and it is why a 20px bottom margin above a 30px top margin makes a gap of 30px, not 50px.
Padding or margin?
Ask: is the space inside the thing (between its edge and its content)? Use padding. Is it the space between things? Use margin.
- margin is space outside the border; it pushes neighbours away.
- margin: 0 auto centres a block that has a width.
- Vertical margins between blocks collapse to the larger one.
12. Block, inline and width
How elements flow on the page.
Every element has a display type. It decides how the element behaves in the flow of the page.
- block: takes the full width available and starts on a new line.
div,p,h1,ulare block. You can setwidth,height, and all margins. - inline: flows within a line of text, only as wide as its content.
span,a,strong,emare inline.widthandheightdo not apply. - inline-block: flows like inline, but you can set width, height and vertical margins.
- flex: the element becomes a flexible container for its children (next lesson).
- none: the element disappears completely.
a {
display: inline-block;
padding: 8px 16px;
}Make a normally inline element act like a box
Width and height
Block elements stretch to fit their container unless you set a width. Use max-width to say "as wide as needed, but never wider than this", which is perfect for readable text columns and works on small screens.
.article {
max-width: 680px;
margin: 0 auto;
}A readable column that shrinks on phones
- Block elements fill the row; inline elements flow in text.
- inline-block is inline with box powers.
- display: none removes an element. max-width is great for responsive layouts.
13. Flexbox: lining things up
Centre and arrange with one rule.
Putting things side by side or centring them used to be painful. Flexbox solves it. You turn a parent element into a flex container, and its direct children become flex items that line up along a direction.
body {
display: flex;
flex-direction: column;
align-items: center;
}The page body becomes a centred column
Three ideas:
display: flexon the parent switches flexbox on.flex-directionchooses the main axis:row(left to right, the default) orcolumn(top to bottom).align-itemsaligns the items on the cross axis (the other direction):flex-start,center,flex-end,stretch.
In our example the direction is a column, so the main axis is vertical, the cross axis is horizontal, and align-items: center centres the items horizontally. If the direction were row, the same align-items: center would centre them vertically.
The golden rule
Flex properties like flex-direction and align-items go on the parent, not on the items.
display: flex is on the parent. Without it, the other flex properties are ignored.- display: flex on the parent starts flexbox.
- flex-direction sets the main axis; align-items aligns across it.
- Flex properties go on the parent container.
14. Flexbox: gaps, spacing and rows
A few more flex tools.
Once display: flex is on, these properties do most of the work.
justify-contentspreads items along the main axis:flex-start,center,flex-end,space-between,space-around.align-itemsaligns them across the cross axis.gapadds space between items (no margins needed).flex-wrap: wraplets items drop onto the next line when there is not enough room.
body {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
gap: 16px;
min-height: 100vh;
}Items in a row, centred both ways, with a gap
A classic: centre anything on the screen
To centre a box both horizontally and vertically in the window, use a flex container that is as tall as the window, and centre both axes: display: flex; justify-content: center; align-items: center; min-height: 100vh;.
A navigation bar
nav {
display: flex;
justify-content: space-between;
align-items: center;
}A row with the logo on the left and links on the right
- justify-content works on the main axis, align-items on the cross axis.
- gap adds spacing between flex items.
- flex-wrap: wrap lets items move to a new line.
15. Hover effects and transitions
Making things respond.
Pages feel alive when things react. You already met :hover. Add transition to make the change smooth instead of instant.
.note {
background: #fef3c7;
padding: 16px;
border-radius: 12px;
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.note:hover {
transform: translateY(-4px);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2);
}A note that lifts and brightens on hover
transition: property duration timingtells the browser to animate changes smoothly. Put it on the normal state.transform: translateY(-4px)moves the element up by 4 pixels without affecting layout.- Useful transforms:
scale(1.05)to grow slightly,rotate(3deg)to tilt.
Other states
:focusapplies when a form field or button has keyboard focus. Always keep a visible focus style: keyboard users depend on it.:activeapplies while a button is being pressed.
- :hover styles the mouse-over state.
- transition on the normal state animates the change.
- transform moves, scales or rotates without changing layout.
16. Making a page work on phones
One page, every screen size.
People view pages on phones, tablets and big monitors. Responsive design means your CSS adapts to the screen.
Step 1: the viewport tag
Add this line to the head of your HTML so phones do not zoom out and shrink the page:
<meta name="viewport" content="width=device-width, initial-scale=1">In the head of your HTML
Step 2: flexible sizes
Prefer max-width, percentages and rem over fixed pixel widths.
Step 3: media queries
A media query applies CSS only when a condition is true, usually about the screen width.
.cards {
display: flex;
gap: 16px;
}
@media (max-width: 600px) {
.cards {
flex-direction: column;
}
}Stack the layout on small screens
Read it as: "when the screen is 600 pixels wide or narrower, make the cards stack in a column."
Mobile first
Many developers write the small-screen styles first, then use min-width queries to add features for bigger screens. It keeps phone pages light and simple.
- Add the viewport meta tag.
- Use flexible units; add media queries for changes at certain widths.
17. Fixing CSS that does not work
A checklist for when nothing changes.
Every developer asks "why is my CSS not working?" every week. Walk through this list from top to bottom.
- Typo. Is the property name spelled right?
backrounddoes nothing and gives no error. - Missing semicolon, colon or brace. One mistake can break the following rules too.
- Wrong selector. Does the element really have the class you used? Is it
.notewith a dot, notnote? - Another rule wins. Check specificity and order (see the cascade lesson).
- Wrong target. Flex properties go on the parent.
marginhas no effect on some inline elements. - No unit.
font-size: 20is ignored. Use20px. - Cache. Hard-refresh the page (Ctrl+Shift+R) if you changed a linked file.
Use the Inspect tool
Right-click the element and choose Inspect. In the Styles panel you can:
- See every rule that applies, with overridden ones crossed out.
- Tick or untick a declaration to test it instantly.
- Edit values live and see the page change.
Once you find the fix, copy it back into your real file.
- Check spelling, punctuation, selector, specificity and units.
- The Inspect tool shows which rules apply and which lose.
- Test changes live in the browser before editing your file.