Center text
Use
text-align: center;
when you want to center text inside an element.
CSS (Cascading Style Sheets) controls how HTML elements look on a webpage. While HTML provides structure, CSS handles layout, spacing, colours, and visual presentation. This page covers everything from the basics through to advanced techniques, with a clear divider marking where things get more complex.
CSS not working?
→ Is the selector correct?
→ Is the rule applied?
→ Is it overridden by another rule?
→ Is the parent controlling layout?
→ Is size causing the problem?
→ Is it losing the specificity battle?
There are three main ways to apply CSS to a webpage.
| Method | Where | Use Case |
|---|---|---|
| Inline | Inside HTML tags | Quick testing (not recommended long term) |
| Internal | <style> in head | Small projects |
| External | Separate .css file | Best practice for real projects |
Best habit:
HTML = structure
CSS = styling
Browsers apply default styles. * is used to reset browser defaults and make layout easier to control.
These default styles are called the User Agent Stylesheet — every browser ships with one. It's why an unstyled page still has margins, font sizes, and bullet points. Always check the User Agent Stylesheet before assuming your CSS rule isn't working.
Common example:
/* Reset - applies to all elements */
* {
margin: 0; /* remove default spacing */
padding: 0; /* remove default spacing */
box-sizing: border-box; /* keeps width predictable */
}
This helps by:
New CSS file starter — copy this to begin:
/* 1. Reset */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* 2. Body defaults */
body {
font-family: sans-serif;
font-size: 1rem;
line-height: 1.5;
color: #333;
background-color: #fff;
}
CSS supports several ways to write colours. They all do the same job — the difference is how readable and flexible they are to work with.
| Format | Example | When to use it |
|---|---|---|
| Named | color: red; | Quick testing only — limited options |
| HEX | color: #3b82f6; | Common in designs and copied from tools like Figma |
| RGB | color: rgb(59, 130, 246); | When you need to work with red, green, blue values directly |
| RGBA | color: rgba(59, 130, 246, 0.5); | Same as RGB but with transparency (0 = invisible, 1 = solid) |
| HSL | color: hsl(210, 75%, 25%); | Best for adjusting colours — easy to make lighter, darker, or more muted |
| HSLA | color: hsla(210, 75%, 25%, 0.8); | HSL with transparency |
HSL breakdown:
hsl( hue, saturation, lightness )
Hue → 0–360 — the colour on the wheel (0 = red, 120 = green, 240 = blue)
Saturation → 0% = grey, 100% = full colour
Lightness → 0% = black, 50% = normal, 100% = white
Why HSL is useful:
→ easy to make a colour lighter: hsl(210, 75%, 40%) → hsl(210, 75%, 60%)
→ easy to make it more muted: hsl(210, 75%, 25%) → hsl(210, 30%, 25%)
→ no need to guess hex codes
Rule:
Use HEX when copying from design tools
Use HSL when you want to adjust colours yourself
Use RGBA / HSLA when you need transparency
CSS controls both text colour and element backgrounds, including images and gradients.
| Property | Description | Example |
|---|---|---|
| color | Text colour | color: #333; |
| background-color | Element background colour | background-color: lightblue; |
| background-image | Image or gradient background | background-image: url("image.jpg"); |
| background-size | Scales background image | background-size: cover; |
| background-position | Aligns background image | background-position: center; |
For most background images use:
background-size: cover;
background-position: center;
background-repeat: no-repeat;
The "C" in CSS stands for Cascading. It means that when multiple rules target the same element, CSS has a system for deciding which one wins. Understanding this saves a lot of confusion.
Three things decide which rule wins:
1. Specificity → more specific selectors beat less specific ones
2. Order → when specificity is equal, the rule written LAST wins
3. Importance → !important overrides everything (use sparingly)
Order example:
p { color: red; }
p { color: blue; }
→ text will be BLUE
→ the second rule comes later so it wins
Practical rule:
If a style is not applying and you can't see why,
scroll down your CSS — a later rule may be overriding it.
| Concept | What it means |
|---|---|
| Cascade | Rules flow down — later rules can override earlier ones |
| Specificity | More targeted selectors win over general ones |
| Inheritance | Some properties (like font-family) pass down to child elements automatically |
| !important | Forces a rule to win — overrides cascade and specificity |
Selectors are used to target HTML elements so CSS can be applied to them.
| Selector | Example | Description |
|---|---|---|
| Element | p | Targets all elements of that type |
| Class | .box | Targets elements with a class |
| ID | #main | Targets a specific element |
If CSS does nothing:
1. Check selector
2. Check class name
3. Check spelling
4. Check if another rule wins
Every element in CSS is treated as a box. Understanding this is key to controlling layout and spacing.
+-------------------------+
| margin |
| +-------------------+ |
| | border | |
| | +-------------+ | |
| | | padding | | |
| | | +---------+ | | |
| | | | content | | | |
| | | +---------+ | | |
| | +-------------+ | |
| +-------------------+ |
+-------------------------+
The box model is made up of content, padding, border, and margin.
Useful:
box-sizing: border-box;
Default behaviour:
width = content only
Padding and border are added on top of width.
border-box:
width = content + padding + border
Use border-box when you want predictable sizing.
Margin controls space outside an element. Padding controls space inside the element between the content and its border.
| Property | Controls |
|---|---|
| margin | Space outside the element |
| padding | Space inside the element |
| gap | Space between flex/grid items |
Padding = inside the box
Margin = outside the box
Gap = between layout items
The display property controls how elements behave in layout.
| Value | Behaviour |
|---|---|
| block | Takes full width and starts on a new line |
| inline | Only takes needed width |
| inline-block | Inline but allows width/height |
| none | Removes element from layout |
| flex | Creates a flex layout container |
| grid | Creates a grid layout container |
Use display to decide:
Does this behave like text?
Or like a layout box?
Use
text-align: center;
when you want to center text inside an element.
A block element must be narrower than its parent before centring becomes visible. Use auto margins to center it horizontally.
Many block elements take up the full available width by default. This can make some alignment changes appear to do nothing.
text-align: center;
→ centers text/content inside an element
margin: auto;
→ centers a narrower block/container horizontally
justify-items / justify-content;
→ centers layout items, not the container itself
Rule:
Ask: Am I centering text, items, or the container?
Always check default styles before assuming your layout rule is wrong.
width
defines how much space an element should take
max-width
sets a ceiling
Images are affected by both their own size and the container they sit inside. If the container is not controlled, the image may not behave as expected.
Common image problems include:
| Property | What it helps control |
|---|---|
| width | How wide the image appears |
| max-width | Stops the image becoming too large |
| height | How tall the image appears |
| object-fit | How the image fits inside its container |
| object-position | Which part of the image stays visible when cropped |
Rule:
control the container first
then control how the image fits inside it
Typography controls how text looks and how easy it is to read. Good typography improves readability and overall layout.
| Property | What it controls |
|---|---|
| font-family | The typeface used on the page |
| font-size | The size of the text |
| font-weight | How bold or light the text appears |
| line-height | Space between lines of text |
| letter-spacing | Space between letters |
| text-transform | Uppercase/lowercase style |
Basic rule:
make text readable first
style it second
Different CSS units are useful in different situations. Some are fixed, others are relative.
| Unit | Meaning | Example |
|---|---|---|
| px | Fixed size | width: 200px; |
| % | Relative to parent | width: 50%; |
| rem | Relative to root font size | padding: 1.5rem; |
| vw / vh | Relative to viewport width/height | height: 50vh; |
Good habit:
use rem for type/spacing
use % for flexible widths
use vw/vh carefully
Flexbox is powerful but can feel confusing at first because layout behaviour depends heavily on the parent container and the chosen direction. Flexbox is one-dimensional — it handles either a row or a column at a time.
flex-direction: row
[ item ][ item ][ item ]
main axis → left ↔ right
cross axis → top ↕ bottom
flex-direction: column
[ item ]
[ item ]
[ item ]
main axis → top ↕ bottom
cross axis → left ↔ right
If alignment feels wrong, the direction is usually the cause.
If spacing is wrong:
check direction first
If items won't move:
check the parent
Nav list recipe:
nav ul {
display: flex;
list-style: none;
gap: 1rem;
}
nav a {
text-decoration: none;
color: inherit; /* inherit = use the parent's colour instead of default link blue */
}
Problem-solving order (learned from Flexbox Froggy level 24):
Don't try to move individual items first — figure out the overall
layout structure before touching individual positioning.
1. flex-direction → which way does the main axis run?
2. flex-wrap → does content wrap onto new lines?
3. justify-content → position along the main axis
4. align-content → position the wrapped lines along the cross axis
(align-items → position items within a single line)
Getting the structure (1-2) right first makes the positioning
properties (3-4) behave the way you'd expect.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ADVANCED CSS
Everything below this point covers advanced concepts
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Pseudo-classes target elements in a specific state, such as when a user hovers over a link or when an element is the first child in a container.
State-based styling
link → normal
:hover → pointer over it
:focus → keyboard focus
:active → being clicked
| Pseudo-Class | Description | Example |
|---|---|---|
| :hover | Applies when the user hovers over an element. | a:hover { color: gold; } |
| :focus | Applies when an element receives keyboard focus. | input:focus { outline: 2px solid white; } |
| :active | Applies when an element is being clicked. | button:active { transform: scale(0.98); } |
| :nth-child() | Selects elements based on their position in a list. | li:nth-child(2) { color: yellow; } |
Pseudo-elements style specific parts of an element, such as the first letter or content inserted before or after an element.
Part-based styling
::before → before content
::after → after content
::first-letter → first letter
::selection → selected text
| Pseudo-Element | Description | Example |
|---|---|---|
| ::before | Inserts content before an element. | h2::before { content: "★ "; } |
| ::after | Inserts content after an element. | h2::after { content: " ★"; } |
| ::first-letter | Styles the first letter of text. | p::first-letter { font-size: 2rem; } |
| ::selection | Styles text when selected by the user. | ::selection { background: gold; } |
Positioning controls how elements are placed on the page. It is essential for building complex layouts and UI components.
RELATIVE → keeps its space
ABSOLUTE → removed from flow
FIXED → attached to viewport
STICKY → relative until stuck
| Position Type | Description | Example |
|---|---|---|
| static | Default positioning, follows normal document flow. | div { position: static; } |
| relative | Positioned relative to its normal position. | div { position: relative; top: 10px; } |
| absolute | Positioned relative to the nearest positioned ancestor. | div { position: absolute; right: 0; } |
| fixed | Stays fixed to the viewport when scrolling. | nav { position: fixed; top: 0; } |
| sticky | Scrolls normally until reaching a threshold, then sticks. | h2 { position: sticky; top: 0; } |
CSS backgrounds allow you to control images, gradients, and positioning for decorative or structural design.
Common background image trio:
background-size: cover;
background-position: center;
background-repeat: no-repeat;
| Property | Description | Example |
|---|---|---|
| background-image | Sets an image or gradient as the background. | background-image: url(bg.png); |
| background-size | Controls how the background image scales. | background-size: cover; |
| background-position | Sets the starting position of the background. | background-position: center; |
| background-repeat | Controls whether the image repeats. | background-repeat: no-repeat; |
Advanced ideas:
gradient + image layering
blend modes
fixed backgrounds
Shadows add depth and emphasis to elements, improving visual hierarchy.
box-shadow → around element
text-shadow → behind text
| Type | Description | Example |
|---|---|---|
| box-shadow | Adds shadow around an element's box. | box-shadow: 0 4px 6px rgba(0,0,0,0.3); |
| text-shadow | Adds shadow behind text. | text-shadow: 1px 1px 2px black; |
Transitions allow smooth changes between property values, improving interactivity and user experience.
Normal:
button
Hover:
button changes smoothly
| Property | Description | Example |
|---|---|---|
| transition-property | Specifies which property will animate. | transition-property: background-color; |
| transition-duration | Controls how long the change takes. | transition-duration: 0.3s; |
| transition-timing-function | Controls animation speed curve. | transition-timing-function: ease; |
| transition-delay | Waits before the transition starts. | transition-delay: 0.1s; |
| transition | Shorthand for all transition settings. | transition: all 0.3s ease; |
CSS variables let you define a value once and reuse it everywhere. This makes your stylesheet much easier to update and maintain.
Why variables matter:
Without variables — changing your brand colour means hunting through every line:
button { background-color: #3b82f6; }
a { color: #3b82f6; }
.header { border-bottom: 2px solid #3b82f6; }
.badge { background-color: #3b82f6; }
With variables — change it in one place, it updates everywhere:
:root { --color-primary: #3b82f6; }
button { background-color: var(--color-primary); }
a { color: var(--color-primary); }
.header { border-bottom: 2px solid var(--color-primary); }
.badge { background-color: var(--color-primary); }
| Use | Description | Example |
|---|---|---|
| Colours | Keep palette consistent. | --brand-blue: #3498db; |
| Spacing | Reuse spacing values. | --space-md: 1rem; |
| Themes | Update many styles from one place. | background: var(--surface); |
Colour palette starter:
:root {
--color-primary: #3b82f6;
--color-secondary: #64748b;
--color-accent: #f59e0b;
--color-bg: #ffffff;
--color-text: #1e293b;
}
body {
background-color: var(--color-bg);
color: var(--color-text);
}
a { color: var(--color-primary); }
To retheme the whole site:
update :root — not every selector
Relative and advanced units make CSS more flexible and responsive.
| Unit | Description | Example |
|---|---|---|
| em | Relative to parent font-size. | padding: 2em; |
| rem | Relative to root font-size. | font-size: 1.2rem; |
| vw / vh | Relative to viewport width and height. | height: 50vh; |
| vmin / vmax | Relative to the smallest or largest viewport side. | font-size: 5vmin; |
| ch | Based on the width of the "0" character. | width: 60ch; |
| calc() | Allows simple math in CSS. | width: calc(100% - 40px); |
| clamp() | Sets a min, preferred, and max value. | font-size: clamp(1rem, 2vw, 2rem); |
Use advanced units when:
fixed px becomes too rigid
Animations create movement over time using keyframes.
Transition = simple state change
Animation = full motion sequence
| Part | Description | Example |
|---|---|---|
| @keyframes | Defines the animation stages. | @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } |
| animation | Applies the animation. | .box { animation: fadeIn 1s ease-in-out forwards; } |
Specificity determines which CSS rule wins when multiple rules target the same element. The more specific the selector, the higher it scores.
| Selector Type | Specificity Value | Example |
|---|---|---|
| Inline Styles | 1000 | <div style="color:red"> |
| ID Selectors | 100 | #header { } |
| Class / Attribute / Pseudo-class | 10 | .box { } |
| Element Selectors | 1 | p { } |
If a rule will not apply:
→ it may be losing the specificity battle
→ or a later rule in the cascade is overriding it
→ check both before reaching for !important
If CSS does nothing:
→ check selector
If layout feels wrong:
→ check parent
If spacing feels wrong:
→ check margin / padding / gap
If image looks wrong:
→ check container first
If alignment feels wrong:
→ check flex direction
If one rule wins unexpectedly:
→ check specificity
→ check rule order in your file
State change? → pseudo-class
Part of element? → pseudo-element
Move in layout? → positioning
Smooth change? → transition
Motion sequence? → animation
Reuse values? → variables
Rule not applying?→ specificity or cascade