CSS 101
Your website becomes beautiful! From CSS variables to animations, step by step to a professional MyFirst Site.
Basics first? HTML 101 comes before CSS 101.
Chapter 01
CSS variables
Declare once — use everywhere. The professional trick from the very start!
Change one variable in :root, and every place that uses it changes too.
:root { --primary: … }declare oncevar(--primary)var(--primary)var(--primary):root--namevar()
CSS variables (also called custom properties) are like variables in a programming language. You define a value once — and use it everywhere. If the value changes, everything changes at once!
Because CSS variables keep your work tidy from day one. No more copying and pasting colour codes. No more search-and-replace when you change a colour. Change it once — changed everywhere. That is a professional workflow!
/* :root = the top-level element (html) */ :root { /* Colours */ --primary: #00b4d8; /* Cyan – main colour */ --secondary: #0077b6; /* Dark blue */ --accent: #f72585; /* Pink – accent */ --dark: #03071e; /* Almost black */ --text: #e0e0e0; /* Light text */ /* Fonts */ --font-display: 'Playfair Display', serif; --font-body: 'DM Sans', sans-serif; /* Spacing */ --spacing-sm: 0.5rem; --spacing-md: 1rem; --spacing-lg: 2rem; /* Shadow */ --shadow: 0 4px 20px rgba(0, 180, 216, 0.2); /* Transitions */ --transition: all 0.3s ease; }
body { background: var(--dark); color: var(--text); font-family: var(--font-body); } h1 { color: var(--primary); margin-bottom: var(--spacing-md); } .btn { background: var(--primary); transition: var(--transition); box-shadow: var(--shadow); }
-- (two hyphens). This is mandatory — not optional!- Create a new folder
css/in MyFirst-Site - Create the file
css/style.css - Define CSS variables for colours, fonts and spacing
- Choose your own colours — make it your project!
Chapter 02
Linking CSS
Three ways to bring CSS into your HTML page — plus the reset!
A separate .css file works for every page that links it.
<style>, only this pagestyle.css, the right wayindex.htmlabout.htmlcontact.htmlcss/style.css<link rel="stylesheet">- reset
- Directly in the HTML tag
- Only for this one element
- Hard to maintain
- Fine for quick tests
- In the <style> tag in the <head>
- Only for this one page
- Fine for single pages
- Not reusable
- A separate .css file
- Applies to every page that links it
- Change once → changed everywhere
- The browser caches it → faster!
<!-- 1. Inline CSS – right in the tag --> <p style="color: red; font-size: 1.2rem;">Text</p> <!-- 2. Internal CSS – in the <head> --> <style> p { color: blue; } </style> <!-- 3. External CSS – ✅ THE RIGHT WAY --> <link rel="stylesheet" href="css/style.css">
The CSS reset
Every browser has its own default styles — Chrome, Firefox and Safari show some things slightly differently. The reset wipes the slate clean:
/* ===== RESET ===== */ * { margin: 0; padding: 0; box-sizing: border-box; /* Pro trick! Count spacing INSIDE */ } html { scroll-behavior: smooth; /* Smooth scrolling */ } body { font-family: var(--font-body); background: var(--dark); color: var(--text); line-height: 1.6; }
Without it: width=200px + padding=20px = 240px wide (the browser adds it on)
With box-sizing: border-box: width=200px + padding=20px = still 200px! ✅
That makes layouts much more predictable — so always use it!
Chapter 03
Selectors
You decide exactly which element gets styled — as precise as a surgeon!
The selector aims at elements: all tags of a kind, a class or exactly one element.
p { }all <p>.btn { }all with class="btn"#hero { }the one with id="hero"p .class #id.card p:hover ::after
/* Element selector — all h1 */ h1 { color: white; } /* Class selector — all with class="card" */ .card { background: #1a1a2e; } /* ID selector — the one element with id="hero" */ #hero { min-height: 100vh; } /* Combination — p inside .card */ .card p { font-size: 0.9rem; } /* Pseudo-class — on hover */ .btn:hover { background: var(--accent); } /* Pseudo-element — line after the element */ .nav-link::after { content: ''; display: block; height: 2px; background: var(--primary); }
Class (.btn): Can be used many times. For anything that repeats — buttons, cards, etc.
ID (#hero): Only once per page. For unique elements — hero, header, footer.
Tip: When in doubt, always use classes — more flexible!
Chapter 04
Colours + gradients
HEX, RGB, HSL — and gradients that impress!
The same colour can be written in several ways. Gradients blend two or more.
#00b4d8linear-gradient, radial-gradientcolor backgroundrgba()linear-gradient()
Three ways to specify colours:
#00b4d8 → HEX — the most common. 6 characters (RR GG BB in hex)
rgb(0, 180, 216) → RGB — red, green, blue, each 0-255
rgba(0, 180, 216, 0.5) → RGBA — with transparency (0 = invisible, 1 = solid)
hsl(195, 100%, 42%) → HSL — hue, saturation, lightness
/* Linear Gradient — from A to B */ .hero { background: linear-gradient(135deg, #00b4d8, #f72585); } /* Radial Gradient — from the centre outwards */ .bg-glow { background: radial-gradient(ellipse at center, rgba(0,180,216,0.2), transparent); } /* Gradient Text — the wow effect! */ .gradient-text { background: linear-gradient(135deg, #00b4d8, #f72585); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } /* Combining several gradients */ .complex-bg { background: linear-gradient(rgba(3,7,30,0.9), rgba(3,7,30,0.9)), radial-gradient(ellipse at 20% 50%, rgba(0,180,216,0.15), transparent); }
Chapter 05
Text + Google Fonts
Loading fonts, sizes, weights, spacing — typography like a pro!
Link a font, assign it and set it up so it is easy to read.
<link> in the <head>font-familyassign the fontfont-size in rem, font-weightline-height1.6 reads comfortablyThe browser loads a Google Fonts typeface from someone else's server. Without internet, the fallback font is used.
font-family font-size font-weightline-height letter-spacingtext-align text-transform
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@700;900&family=DM+Sans:wght@300;400;500&display=swap" rel="stylesheet">
Text properties you need:
font-family — typeface
font-size — size (rem recommended!)
font-weight — weight: 300 (light), 400 (normal), 700 (bold), 900 (black)
line-height — line spacing (1.6 is comfortable to read)
letter-spacing — spacing between letters
text-transform — uppercase, lowercase, capitalize
text-align — left, center, right
text-decoration — none (links without underline!)
h1 { font-family: var(--font-display); font-size: clamp(2.5rem, 6vw, 5rem); /* Responsive! */ font-weight: 900; line-height: 1.1; letter-spacing: -0.02em; } p { font-size: 1rem; line-height: 1.6; font-weight: 300; } .nav-link { font-size: 0.9rem; letter-spacing: 0.05em; text-transform: uppercase; text-decoration: none; }
font-size: clamp(2.5rem, 6vw, 5rem)= minimum 2.5rem, preferably 6% of the viewport width, maximum 5rem
→ the text grows and shrinks automatically with the screen!
Chapter 06
Box model
The heart of CSS — everything is a box! Understanding margin, padding and border.
From inside out: content, padding, border, margin.
paddingbordermarginbox-sizing: border-box
Every HTML element is a rectangular box. The box model describes how this box is built:
Text, image, etc.
.card { /* Padding — inner spacing (all sides) */ padding: 2rem; /* Padding — single sides */ padding-top: 1rem; padding-bottom: 1rem; padding-left: 1.5rem; padding-right: 1.5rem; /* Shorthand: top right bottom left */ padding: 1rem 1.5rem; /* top/bottom left/right */ /* Margin — outer spacing */ margin-bottom: 2rem; margin: 0 auto; /* centre horizontally! */ /* Border — frame */ border: 1px solid rgba(0, 180, 216, 0.3); border-radius: 12px; /* rounded corners */ border-radius: 50%; /* perfect circle! */ /* Width + height */ width: 300px; max-width: 100%; /* responsive! */ min-height: 200px; /* Shadow */ box-shadow: 0 4px 20px rgba(0, 180, 216, 0.2); }
Chapter 07
Flexbox + grid
Modern layout without headaches — columns, rows, centring!
One direction: flexbox. Two directions: grid.
flexnavbar, buttons, centringgridcards in columns and rowsdisplay: flexjustify-content align-items gapdisplay: gridgrid-template-columns
Flexbox — for one direction
.navbar { display: flex; justify-content: space-between; /* horizontal */ align-items: center; /* vertical */ gap: 1rem; /* space between children */ } /* Centring — the classic! */ .hero { display: flex; justify-content: center; align-items: center; min-height: 100vh; } /* flex-wrap — allow wrapping */ .btn-group { display: flex; flex-wrap: wrap; gap: 0.5rem; }
Grid — for two directions
/* Fixed number of columns */ .cards-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; /* 3 equal columns */ gap: 1.5rem; } /* Auto-fill — as many columns as fit! */ .tools-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 1rem; } /* Element across several columns */ .card-wide { grid-column: span 2; /* takes 2 columns */ }
Flexbox = one direction (row OR column). Ideal for navbars, button groups, single rows.
Grid = two directions (rows AND columns). Ideal for card layouts and whole page layouts.
Chapter 08
Responsive design
Media queries — your page adapts automatically to phone, tablet and desktop!
Phone first, then extend for bigger screens with media queries.
@media (min-width: …)meta viewport- device view with F12
Mobile first — the recommended way:
Design the phone layout first (one column, large, easy to tap). Then extend it for larger screens with media queries. That is the standard today!
/* BASE — mobile first (no media query needed!) */ .cards-grid { display: grid; grid-template-columns: 1fr; /* one column on phones */ gap: 1rem; } /* TABLET — from 768px */ @media (min-width: 768px) { .cards-grid { grid-template-columns: 1fr 1fr; /* two columns */ } .nav-links { display: flex; /* show navbar */ } } /* DESKTOP — from 1024px */ @media (min-width: 1024px) { .cards-grid { grid-template-columns: 1fr 1fr 1fr; /* three columns */ } } /* Common breakpoints: */ /* 480px → large phones */ /* 768px → Tablets */ /* 1024px → small desktops */ /* 1280px → normal desktops */
Chapter 09
Animations
Transitions, keyframes, hover effects — movement that impresses! All pure CSS.
Transition: a smooth change between two states. Keyframes: a whole sequence.
:hoverMore about this in its own tutorial, CSS Animation 101.
transitiontransform@keyframes
Transitions — smooth changes
.btn { background: var(--primary); transition: all 0.3s ease; /* what, duration, timing */ } .btn:hover { background: var(--accent); transform: translateY(-2px); /* move up */ box-shadow: var(--shadow-hover); } /* Underline animation on hover */ .nav-link { position: relative; } .nav-link::after { content: ''; position: absolute; bottom: -4px; left: 0; width: 0; height: 2px; background: var(--primary); transition: width 0.3s ease; } .nav-link:hover::after { width: 100%; /* underline slides out! */ }
Keyframes — your own animations
/* Fade in from below */ @keyframes fadeInUp { from { opacity: 0; transform: translateY(30px); } to { opacity: 1; transform: translateY(0); } } /* Pulse */ @keyframes pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.05); } } /* Spin */ @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } /* Blink (client request fulfilled! 😄) */ @keyframes blink { 0%, 49% { color: red; } 50%, 100%{ color: green; } } /* Using the animations */ .hero-content { animation: fadeInUp 1s ease 0.3s both; /* name duration timing delay fill */ } .badge { animation: pulse 2s ease-in-out infinite; } .spinner { animation: spin 1s linear infinite; } /* Slide the navbar in from the top */ @keyframes slideDown { from { transform: translateY(-100%); } to { transform: translateY(0); } }
animation: fadeInUp 1s ease 0.3s both;= name | duration | timing | delay | fill mode
both = the animation keeps its end state, even before it has started.
Chapter 10
Styling MyFirst Site
Everything together — your MyFirst Site becomes really beautiful!
css/style.css collects everything, in this order.
:root* { box-sizing }Every page needs the <link> to style.css, otherwise it stays unstyled.
css/style.css- linked on every page
Now you apply everything you have learned to your MyFirst Site. Here is a complete example for css/style.css:
/* ===== VARIABLES ===== */ :root { --primary: #00b4d8; --accent: #f72585; --dark: #03071e; --dark-2: #1a1a2e; --text: #e0e0e0; --white: #ffffff; --gradient: linear-gradient(135deg, #00b4d8, #f72585); --shadow: 0 4px 20px rgba(0,180,216,0.2); --transition:all 0.3s ease; --radius: 12px; } /* ===== RESET ===== */ * { margin: 0; padding: 0; box-sizing: border-box; } html { scroll-behavior: smooth; } body { font-family: 'DM Sans', sans-serif; background: var(--dark); color: var(--text); line-height: 1.6; } /* ===== NAVBAR ===== */ nav { position: fixed; top: 0; left: 0; width: 100%; z-index: 1000; background: rgba(3,7,30,0.95); padding: 1rem 2rem; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid rgba(0,180,216,0.2); animation: slideDown 0.6s ease; } nav a { color: var(--text); text-decoration: none; transition: var(--transition); } nav a:hover { color: var(--primary); } /* ===== HERO ===== */ .hero { min-height: 100vh; display: flex; align-items: center; justify-content: center; text-align: center; padding: 4rem 2rem; background: linear-gradient(135deg, rgba(3,7,30,0.95), rgba(26,26,46,0.9)); } .hero h1 { font-size: clamp(2.5rem, 6vw, 5rem); font-weight: 900; color: var(--white); margin-bottom:1rem; animation: fadeInUp 1s ease both; } /* ===== CARDS ===== */ .cards-grid { display: grid; grid-template-columns: 1fr; gap: 1.5rem; padding: 4rem 2rem; max-width: 1200px; margin: 0 auto; } .card { background: var(--dark-2); border: 1px solid rgba(0,180,216,0.2); border-radius:var(--radius); padding: 2rem; transition: var(--transition); } .card:hover { transform: translateY(-4px); box-shadow: var(--shadow); border-color:var(--primary); } /* ===== RESPONSIVE ===== */ @media (min-width: 768px) { .cards-grid { grid-template-columns: 1fr 1fr; } } @media (min-width: 1024px) { .cards-grid { grid-template-columns: 1fr 1fr 1fr; } } /* ===== ANIMATIONS ===== */ @keyframes fadeInUp { from { opacity: 0; transform: translateY(30px); } to { opacity: 1; transform: translateY(0); } } @keyframes slideDown { from { transform: translateY(-100%); } to { transform: translateY(0); } }
MyFirst Site now looks really professional!
- CSS variables — a professional workflow from the start
- An external CSS file — neatly separated from HTML
- Selectors — as precise as a surgeon
- Colours + gradients — visually impressive
- Google Fonts — typography like a designer
- Box model — the foundation understood
- Flexbox + grid — modern layout
- Responsive design — runs on every device
- Animations — movement that impresses
JS 101 — your page becomes interactive! Buttons that really do something, dynamic content and much more!
→ To JS 101