Komplet Begynderguide til HTML, CSS og JavaScript
Velkommen! Denne guide er lavet til dig, som aldrig har skrevet en eneste linje kode før. Måske har du set hjemmesider og tænkt "hvordan pokker laver man det?" – nu får du svaret. Trin for trin. Uden stress.
Tag det roligt. Du behøver ikke lære alt på én gang. Bare læs med, prøv det af, og mærk hvor fedt det er at se dine egne ideer blive til virkelighed på skærmen.
Indholdsfortegnelse
- Hvad er HTML, CSS og JavaScript?
- Hvad skal du bruge?
- Dit første website
- HTML basics
- HTML struktur
- CSS basics
- CSS layout
- CSS frameworks
- JavaScript basics
- DOM manipulation
- Fetch API
- Hosting
- Domæne
- Tips til begyndere
- Næste skridt
- Eksempel-projekt
- HTML & CSS for danske freelancere
1. Hvad er HTML, CSS og JavaScript?
Forestil dig at du bygger et hus.
HTML er skelettet. Det er væggene, taget, dørene og vinduerne. Uden HTML er der ingenting – bare tomhed. HTML bestemmer hvad der er på siden: overskrifter, tekst, billeder, links, knapper.
CSS er tøjet og interiøret. Det er farverne på væggene, møblerne, fonten på skiltene, afstanden mellem rummene. Uden CSS ser dit website ud som et word-dokument fra 1995. CSS gør det pænt.
JavaScript er hjernen. Det er alt der bevæger sig, reagerer og interagerer. Når du klikker en knap og noget sker – det er JavaScript. Når du udfylder en formular og får en fejlmeddelelse – JavaScript. Når et billede skifter automatisk – JavaScript.
Sådan husker du det:
- HTML = struktur ( hvad )
- CSS = design ( hvordan det ser ud )
- JavaScript = opførsel ( hvad der sker )
Du behøver ikke mestre det hele på én gang. De fleste starter med HTML, tilføjer lidt CSS, og så JavaScript når de føler sig klar. Netop denne guide hjælper dig med det.
2. Hvad skal du bruge?
Her er den gode nyhed: du skal ikke bruge penge på noget som helst.
Du skal kun bruge to ting:
1. En kodeeditor
Dette er det program hvor du skriver din kode. Den mest populære (og gratis) er Visual Studio Code (ofte bare kaldet VS Code).
- Download den gratis på code.visualstudio.com
- Den findes til Windows, Mac og Linux
- Den har masser af udvidelser der gør dit liv nemmere
Tip: Når du har installeret VS Code, så installer udvidelsen "Live Server". Den gør at din hjemmeside opdaterer sig automatisk når du gemmer dine filer – super fedt til at se ændringer i realtid!
2. En webbrowser
Du har allerede en. Chrome, Firefox, Edge, Safari – de virker alle sammen. Chrome anbefales fordi den har de bedste udviklerværktøjer (DevTools).
Det var det. Ingen server, ingen database, ingen komplicerede opsætninger. Bare en editor og en browser.
3. Dit første website
Lad os komme i gang med det samme! Følg disse trin:
Trin 1: Opret en mappe
Opret en ny mappe på dit skrivebord eller i dine dokumenter. Kald den mit-første-website.
Trin 2: Opret HTML-filen
Åbn VS Code. Gå til File > Open Folder og vælg den mappe du lige oprettede.
Klik på "New File" ikonet (det ligner et dokument med et plus) og navngiv filen index.html.
Trin 3: Skriv din første kode
Skriv følgende i filen:
<!DOCTYPE html>
<html lang="da">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mit første website</title>
</head>
<body>
<h1>Hej verden!</h1>
<p>Dette er mit allerførste website. Jeg er så stolt!</p>
</body>
</html>
Trin 4: Åbn i browseren
Højreklik på index.html i VS Code og vælg "Open with Live Server" (hvis du installerede udvidelsen). Ellers kan du bare dobbeltklikke på filen i din mappe.
Tillykke! Du har lige lavet dit første website. Det ser måske ikke ud af meget, men du er nu officielt en der kan kode. 🎉
Hvad skete der lige?
Lad os bryde koden ned:
<!DOCTYPE html>fortæller browseren at dette er et HTML5-dokument<html lang="da">er rod-elementet der indeholder alt<head>indeholder metadata (ting browseren skal vide, men ikke vise)<title>er hvad der vises i fanebladet<body>er alt det synlige indhold<h1>er en stor overskrift<p>er et afsnit tekst
4. HTML basics
HTML bruger "tags" til at definere indhold. De ser sådan her ud: <tag>indhold</tag>
De vigtigste tags
Overskrifter: <h1> til <h6>
<h1>Største overskrift</h1>
<h2>Underoverskrift</h2>
<h3>Endnu mindre</h3>
<h4>og så videre...</h4>
<h5>...hele vejen ned til...</h5>
<h6>...den mindste overskrift</h6>
Husk: Brug kun ét h1 per side (det er din hovedoverskrift). Brug h2 til hovedafsnit, h3 til underafsnit osv.
Afsnit: <p>
<p>Dette er et tekstafsnit. Browseren sørger automatisk for mellemrum mellem afsnit.</p>
<p>Dette er et nyt afsnit. Du behøver ikke trykke enter to gange – bare start et nyt p-tag.</p>
Links: <a>
<a href="https://google.com">Klik her for at komme til Google</a>
<a href="om-mig.html">Læs mere om mig</a>
<a href="mailto:hej@example.com">Send mig en mail</a>
Attributten href bestemmer hvor linket fører hen.
Billeder: <img>
<img src="billede.jpg" alt="Et flot billede af min kat">
Bemærk: <img> er et "self-closing" tag – det har ikke en lukke-tag. alt-attributten er vigtig – den beskriver billedet for skærmlæsere og vises hvis billedet ikke kan loades.
Divisions: <div>
<div class="container">
<h2> Overskrift her</h2>
<p>Indhold her</p>
</div>
<div> er en generisk beholder. Den gør ikke noget specielt i sig selv, men den er fantastisk til at gruppere indhold så du kan style det med CSS.
Navigation: <nav>
<nav>
<a href="index.html">Forside</a>
<a href="om.html">Om mig</a>
<a href="kontakt.html">Kontakt</a>
</nav>
Sektioner: <section>
<section>
<h2>Om mig</h2>
<p>Jeg er webudvikler...</p>
</section>
Attributes
Attributes giver ekstra information til tags. De sidder i åbningstagen:
<a href="https://google.com" target="_blank" title="Åbner i nyt faneblad">Google</a>
href= destination for linkettarget="_blank"= åbner i nyt fanebladtitle= tooltip når man holder musen over
Head vs Body
<!DOCTYPE html>
<html>
<head>
<!-- META-data: ting browseren skal vide -->
<!-- Title, charset, links til CSS, osv. -->
</head>
<body>
<!-- SYNligt indhold: overskrifter, tekst, billeder, knapper -->
</body>
</html>
Husk: Alt det pæne (CSS) og kloge (JavaScript) lægger du i <head>. Alt det synlige lægger du i <body>.
5. HTML struktur
Semantisk HTML
"Semantisk HTML" betyder at du bruger de rigtige tags til det rigtige formål. Det gør dit website mere tilgængeligt og lettere at vedligeholde.
I stedet for:
<div class="header">
<div class="nav">...</div>
</div>
<div class="content">...</div>
<div class="footer">...</div>
Så skriv:
<header>
<nav>...</nav>
</header>
<main>...</main>
<footer>...</footer>
Semantiske tags at kende:
<header>– sidehoved<nav>– navigation<main>– hovedindhold<article>– selvstændigt indhold (blogindlæg, nyhedsartikel)<section>– tematisk opdeling<aside>– sideindhold (sidebjælke)<footer>– sidefod
Lists
Punktopstilling (unordered):
<ul>
<li>Æbler</li>
<li>Bananer</li>
<li>Cherry</li>
</ul>
Nummereret (ordered):
<ol>
<li>Først gør du dette</li>
<li>Så gør du dette</li>
<li>Til sidst gør du dette</li>
</ol>
Tables
<table>
<thead>
<tr>
<th>Navn</th>
<th>Alder</th>
<th>By</th>
</tr>
</thead>
<tbody>
<tr>
<td>Maria</td>
<td>28</td>
<td>København</td>
</tr>
<tr>
<td>Peter</td>
<td>34</td>
<td>Aarhus</td>
</tr>
</tbody>
</table>
Forms
Forms er super vigtige – de lader brugeren indtaste data.
<form action="/send" method="POST">
<label for="navn">Dit navn:</label>
<input type="text" id="navn" name="navn" required>
<label for="email">Din email:</label>
<input type="email" id="email" name="email" required>
<label for="besked">Besked:</label>
<textarea id="besked" name="besked" rows="4"></textarea>
<button type="submit">Send</button>
</form>
Vigtige form-elementer:
<form>– selve formen<label>– beskrivelse af feltet (vigtig for tilgængelighed!)<input type="text">– tekstfelt<input type="email">– email-felt (browseren validerer automatisk)<textarea>– større tekstfelt<select>+<option>– rullemenu<input type="checkbox">– afkrysningsfelt<button type="submit">– send-knap
6. CSS basics
CSS (Cascading Style Sheets) er det der får dit website til at se fantastisk ud.
Sådan tilføjer du CSS
Der er tre måder:
1. Inline (ikke anbefalet):
<p style="color: red; font-size: 20px;">Rød tekst</p>
2. Intern (god til små projekter):
<head>
<style>
p {
color: red;
font-size: 20px;
}
</style>
</head>
3. Ekstern fil (bedste praksis):
<head>
<link rel="stylesheet" href="style.css">
</head>
Opret en fil der hedder style.css i samme mappe som dit HTML.
Selectors
Selectors bestemmer hvilke elementer du vil style.
/* Element-selector: alle p-tags */
p {
color: blue;
}
/* Class-selector: alle med class="vigtig" */
.vigtig {
font-weight: bold;
color: red;
}
/* ID-selector: kun det med id="banner" */
#banner {
background-color: yellow;
padding: 20px;
}
Prioritet: ID > Class > Element. Så #banner slår .vigtig som slår p.
Farver
/* Navne */
color: red;
background-color: lightblue;
/* Hex (mest brugt) */
color: #ff0000;
background-color: #00bfff;
/* RGB */
color: rgb(255, 0, 0);
background-color: rgba(0, 191, 255, 0.5); /* med transparency */
Tip: Brug colorpicker.com eller coolors.co til at finde flotte farver.
Fonts
body {
font-family: 'Arial', sans-serif;
font-size: 16px;
line-height: 1.6;
}
h1 {
font-size: 2.5em;
font-weight: bold;
}
Brug Google Fonts for flottere typografi:
- Gå til fonts.google.com
- Vælg en skrifttype
- Kopier link-tagget og sæt det i dit
<head> - Brug den i dit CSS
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600;700&display=swap" rel="stylesheet">
body {
font-family: 'Poppins', sans-serif;
}
Margin og Padding (Box Model)
Forestil dig en æske. Indeni æsken er dit indhold (content). Mellem indholdet og kanten er padding. Uden for kanten er margin.
┌───────────────────────────┐ ← Margin (yderrum)
│ ┌───────────────────────┐ │ ← Padding (indre rum)
│ │ │ │
│ │ DIT INDHOLD │ │
│ │ │ │
│ └───────────────────────┘ │
└───────────────────────────┘
.boks {
/* Indvendigt rum (mellem indhold og kant) */
padding: 20px; /* alle sider */
padding-top: 10px; /* kun top */
padding: 10px 20px; /* top/bund, venstre/højre */
/* Udvendigt rum (mellem denne og andre elementer) */
margin: 20px; /* alle sider */
margin-top: 0; /* kun top */
margin: 0 auto; /* centrerer水平t! */
}
Border
.boks {
border: 2px solid #333;
border-radius: 10px; /* afrundede hjørner */
}
7. CSS layout
Flexbox (det vigtigste at lære!)
Flexbox er en måde at lægge elementer ud på. Det er fantastisk til at centrere ting, lave rækker, og fordele plads.
.container {
display: flex;
justify-content: center; /* vandret centreret */
align-items: center; /* lodret centreret */
gap: 20px; /* mellemrum mellem elementer */
flex-wrap: wrap; /* hop til ny linje ved behov */
}
De vigtigste Flexbox-værdier:
justify-content (vandret):
flex-start– starter fra venstrecenter– centreretflex-end– slutter til højrespace-between– lige mellemrumspace-around– lige mellemrum med kant
align-items (lodret):
flex-start– øverstcenter– centreretflex-end– nederststretch– strækker til fuld højde
Praktisk eksempel – navigation:
nav {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
}
nav ul {
display: flex;
gap: 1.5rem;
list-style: none;
}
Centrering af indhold (den klassiske måde):
.hero {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh; /* fylder hele skærmen */
text-align: center;
}
CSS Grid
Grid er mere avanceret end Flexbox og perfekt til 2D-layouts (rækker OG kolonner).
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr); /* 3 lige brede kolonner */
gap: 20px;
}
@media (max-width: 768px) {
.grid-container {
grid-template-columns: 1fr; /* 1 kolonne på mobil */
}
}
Responsivt design
Responsivt design betyder at dit website ser godt ud på alle enheder – mobil, tablet og computer.
Media Queries er nøglen:
/* Mobil først (standard) */
.container {
padding: 10px;
}
/* Tablet */
@media (min-width: 768px) {
.container {
padding: 20px;
}
}
/* Desktop */
@media (min-width: 1024px) {
.container {
padding: 40px;
max-width: 1200px;
margin: 0 auto;
}
}
Tip: Tænk "mobil først". Skriv CSS til mobil, og tilføj breakpoints til større skærme.
Praktisk eksempel – et responsivt layout
<!DOCTYPE html>
<html lang="da">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Responsivt layout</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
}
header {
background: #333;
color: white;
padding: 1rem;
}
nav {
display: flex;
justify-content: space-between;
align-items: center;
}
.hero {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
text-align: center;
padding: 4rem 1rem;
}
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1.5rem;
padding: 2rem;
}
.card {
border: 1px solid #ddd;
border-radius: 8px;
padding: 1.5rem;
text-align: center;
}
footer {
background: #333;
color: white;
text-align: center;
padding: 1rem;
}
</style>
</head>
<body>
<header>
<nav>
<div class="logo">Mit Website</div>
<ul>
<li><a href="#">Hjem</a></li>
<li><a href="#">Om</a></li>
<li><a href="#">Kontakt</a></li>
</ul>
</nav>
</header>
<section class="hero">
<h1>Velkommen til mit website</h1>
<p>Bygget med ren HTML og CSS</p>
</section>
<div class="cards">
<div class="card">
<h3>Kort 1</h3>
<p>Indhold her</p>
</div>
<div class="card">
<h3>Kort 2</h3>
<p>Indhold her</p>
</div>
<div class="card">
<h3>Kort 3</h3>
<p>Indhold her</p>
</div>
</div>
<footer>
<p>© 2026 Mit Website</p>
</footer>
</body>
</html>
8. CSS frameworks
Tailwind CSS (Utility-First)
Tailwind er et "utility-first" framework. I stedet for at skrive dine egne klasser, bruger du små utility-klasser direkte i HTML.
<div class="bg-blue-500 text-white p-4 rounded-lg shadow-md">
<h2 class="text-xl font-bold">Hej med dig</h2>
<p class="mt-2">Dette er stylet med Tailwind</p>
</div>
Fordele:
- Super hurtigt at bygge med
- IngenCustom CSS at skrive
- Små filstørrelser i produktion
- Meget populært i øjeblikket
Ulemper:
- HTML kan se "rodet" ud
- Læringskurve i starten
- Du skal kende Tailwind's navneord
Bootstrap (Component-Based)
Bootstrap er et ældre og mere etableret framework. Det er "component-baseret" – du bruger færdige komponenter.
<div class="container">
<div class="row">
<div class="col-md-4">
<div class="card">
<div class="card-body">
<h5 class="card-title">Kort titel</h5>
<p class="card-text">Kort tekst</p>
<a href="#" class="btn btn-primary">Læs mere</a>
</div>
</div>
</div>
</div>
</div>
Fordele:
- Nemt at komme i gang
- Masser af dokumentation
- Færdige komponenter (modals, dropdowns, carousels)
- Responsivt out-of-the-box
Ulemper:
- Kan se "standardiseret" ud
- Større filstørrelse
- Mindre fleksibilitet
Hvornår bruger man hvad?
| Situation | Anbefaling |
|---|---|
| Lære CSS grundlæggende | Ingen framework – skriv det selv |
| Hurtigt projekt/poc | Tailwind eller Bootstrap |
| Unikt design | Ingen framework eller Tailwind |
| Komponent-tungt site | Bootstrap |
| Moderne, let site | Tailwind |
Min anbefaling: Lær CSS først. Når du forstår det, så prøv Tailwind. Det vil give dig mere mening.
9. JavaScript basics
JavaScript gør dit website levende.
Variabler
Tænk på variabler som kasser med navne på. I kassen kan du opbevare ting.
// Moderne måde (brug const og let)
const navn = "Anna"; // Kan ikke ændres
let alder = 25; // Kan ændres
const erStuderende = true; // Sandt/falsk
// Ændr en variabel
alder = 26;
// Vis i konsollen (brug DevTools)
console.log("Hej, jeg hedder " + navn);
console.log(`Jeg er ${alder} år`); // Template literal (bedre)
Regel: Brug const som standard. Brug let når du skal ændre værdien. Undgå var.
Funktioner
Funktioner er genbrugelig kode. Skriv den én gang, brug den mange gange.
// Klassisk funktion
function hils(navn) {
return `Hej, ${navn}! Velkommen!`;
}
// Arrow function (moderne)
const hils2 = (navn) => {
return `Hej, ${navn}! Velkommen!`;
};
// Kort arrow function
const hils3 = (navn) => `Hej, ${navn}! Velkommen!`;
// Brug funktionen
console.log(hils("Peter")); // "Hej, Peter! Velkommen!"
If/Else (Betingelser)
const alder = 18;
if (alder >= 18) {
console.log("Du er myndig");
} else {
console.log("Du er ikke myndig endnu");
}
// Flere betingelser
const karakter = "B";
if (karakter === "A") {
console.log("Fremragende!");
} else if (karakter === "B") {
console.log("Rigtig godt!");
} else {
console.log("Fortsæt med at øve dig");
}
Loops
Loops gentager kode.
// For loop
for (let i = 0; i < 5; i++) {
console.log(`Iteration ${i}`);
}
// While loop
let tæller = 0;
while (tæller < 5) {
console.log(`Tæller: ${tæller}`);
tæller++;
}
// forEach (til arrays)
const frugter = ["æble", "banan", "cherry"];
frugter.forEach((frugt, index) => {
console.log(`${index}: ${frugt}`);
});
Arrays
Arrays er lister.
const farver = ["rød", "grøn", "blå"];
console.log(farver[0]); // "rød" (null-baseret!)
console.log(farver.length); // 3
// Tilføj
farver.push("gul");
// Fjern
farver.pop();
// Find
const længde3 = farver.find(f => f.length === 3);
Events (Hændelser)
Events er hvordan JavaScript reagerer på brugerens handlinger.
// Klik på en knap
const knap = document.getElementById("minKnap");
knap.addEventListener("click", function() {
alert("Du klikkede på knappen!");
});
// Formular indsendelse
const form = document.getElementById("minForm");
form.addEventListener("submit", function(event) {
event.preventDefault(); // Forhindrer default opførsel
console.log("Formen blev sendt!");
});
// Musen bevæger sig
document.addEventListener("mousemove", function(event) {
console.log(`Mus: ${event.clientX}, ${event.clientY}`);
});
// Tastatur
document.addEventListener("keydown", function(event) {
console.log(`Tast: ${event.key}`);
});
10. DOM manipulation
DOM (Document Object Model) er hvordan JavaScript ser og ændrer dit HTML.
Find elementer
// Ved ID
const overskrift = document.getElementById("overskrift");
// Ved class (flere elementer)
const paragraffer = document.getElementsByClassName("tekst");
// Ved CSS selector (et element)
const første = document.querySelector(".tekst");
// Ved CSS selector (flere elementer)
const alle = document.querySelectorAll(".tekst");
Ændr indhold
// Tekst
overskrift.textContent = "Ny overskrift";
// HTML (brug med forsigtighed!)
overskrift.innerHTML = "<em>Ny</em> overskrift";
// Attributter
const billede = document.querySelector("img");
billede.src = "nyt-billede.jpg";
billede.alt = "Nyt billede";
Tilføj/fjern CSS-klasser
const element = document.querySelector(".card");
// Tilføj klasse
element.classList.add("aktiv");
// Fjern klasse
element.classList.remove("aktiv");
// Skift klasse (toggle)
element.classList.toggle("aktiv");
Vis/skjul elementer
const popup = document.querySelector(".popup");
// Vis
popup.style.display = "block";
// Skjul
popup.style.display = "none";
// Bedre måde med CSS-klasser
popup.classList.add("skjult");
popup.classList.remove("skjult");
Opret nye elementer
const liste = document.querySelector("ul");
// Opret nyt element
const nytElement = document.createElement("li");
nytElement.textContent = "Nyt punkt";
// Tilføj til siden
liste.appendChild(nytElement);
Praktisk eksempel: Tema-skifter
<!DOCTYPE html>
<html lang="da">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tema-skifter</title>
<style>
body {
font-family: Arial, sans-serif;
padding: 2rem;
transition: background 0.3s, color 0.3s;
}
body.mørk {
background-color: #1a1a1a;
color: white;
}
button {
padding: 0.5rem 1rem;
font-size: 1rem;
cursor: pointer;
}
</style>
</head>
<body>
<h1>Skift tema</h1>
<p>Klik på knappen for at skifte mellem lyst og mørkt tema.</p>
<button id="temaKnap">Skift tema</button>
<script>
const temaKnap = document.getElementById("temaKnap");
temaKnap.addEventListener("click", function() {
document.body.classList.toggle("mørk");
if (document.body.classList.contains("mørk")) {
temaKnap.textContent = "Skift til lyst tema";
} else {
temaKnap.textContent = "Skift til mørkt tema";
}
});
</script>
</body>
</html>
Formularvalidering
const form = document.querySelector("form");
const email = document.querySelector("#email");
form.addEventListener("submit", function(event) {
event.preventDefault();
// Tjek om email er gyldig
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(email.value)) {
alert("Indtast venligst en gyldig email");
return;
}
// Hvis alt er ok
alert("Tak for din besked!");
form.reset();
});
11. Fetch API
Fetch API lader dig hente data fra andre hjemmesider (API'er).
Grundlæggende fetch
fetch("https://jsonplaceholder.typicode.com/users")
.then(response => response.json())
.then(data => {
console.log(data);
// Vis data på din side
})
.catch(error => {
console.error("Der gik noget galt:", error);
});
Med async/await (moderne)
async function hentBrugere() {
try {
const response = await fetch("https://jsonplaceholder.typicode.com/users");
const data = await response.json();
const liste = document.querySelector("#brugerListe");
data.forEach(bruger => {
const li = document.createElement("li");
li.textContent = `${bruger.name} - ${bruger.email}`;
liste.appendChild(li);
});
} catch (error) {
console.error("Fejl:", error);
}
}
hentBrugere();
Praktisk eksempel: Vejr-app
<!DOCTYPE html>
<html lang="da">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vejr-app</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 400px;
margin: 2rem auto;
padding: 0 1rem;
}
.vejr-kort {
border: 1px solid #ddd;
border-radius: 10px;
padding: 1.5rem;
text-align: center;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
input, button {
width: 100%;
padding: 0.75rem;
margin-bottom: 0.5rem;
font-size: 1rem;
border-radius: 5px;
border: 1px solid #ddd;
}
button {
background: #667eea;
color: white;
border: none;
cursor: pointer;
}
button:hover {
background: #5a6fd6;
}
</style>
</head>
<body>
<h1>Vejr-app</h1>
<input type="text" id="by" placeholder="Indtast by (f.eks. København)">
<button onclick="hentVejr()">Hent vejr</button>
<div id="vejrResultat"></div>
<script>
async function hentVejr() {
const by = document.getElementById("by").value;
const resultat = document.getElementById("vejrResultat");
if (!by) {
alert("Indtast venligst en by");
return;
}
try {
// Brug Open-Meteo (gratis, ingen API-nøgle)
const geoUrl = `https://geocoding-api.open-meteo.com/v1/search?name=${by}&count=1&language=da`;
const geoResponse = await fetch(geoUrl);
const geoData = await geoResponse.json();
if (!geoData.results || geoData.results.length === 0) {
resultat.innerHTML = "<p>By ikke fundet</p>";
return;
}
const { latitude, longitude, name } = geoData.results[0];
const vejrUrl = `https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}¤t_weather=true`;
const vejrResponse = await fetch(vejrUrl);
const vejrData = await vejrResponse.json();
const temp = vejrData.current_weather.temperature;
const vind = vejrData.current_weather.windspeed;
resultat.innerHTML = `
<div class="vejr-kort">
<h2>${name}</h2>
<p style="font-size: 3rem; margin: 1rem 0;">${temp}°C</p>
<p>Vind: ${vind} km/t</p>
</div>
`;
} catch (error) {
resultat.innerHTML = "<p>Der gik noget galt. Prøv igen.</p>";
}
}
</script>
</body>
</html>
12. Hosting
Hosting er når du lægger dit website online så alle kan se det.
GitHub Pages (gratis)
Bedst til: Statiske sites, porteføljer, dokumentation.
- Opret en GitHub-konto på github.com
- Installer Git på din computer
- Opret et nyt repository kaldet
dit-brugernavn.github.io - Upload dine filer
- Gå til Settings > Pages
- Vælg "main" branch
- Dit site er live på
https://dit-brugernavn.github.io
Alternativ i Danmark: Du kan også bruge Simply.com eller UnoEuro til at hoste dine statiske sider — begge har dansk support og betaling i DKK.
Netlify (gratis)
Bedst til: Moderne projekter, hurtigere deployment.
- Opret konto på netlify.com
- Træk og slip din mappe ind
- Færdig! Du får et link med det samme
Du kan også forbinde dit GitHub-repository og få automatisk deployment.
Alternativ i Danmark: NordicWay tilbyder statisk webhotel med dansk support og fakturering i DKK.
Vercel (gratis)
Bedst til: React, Next.js, og andre frameworks.
- Opret konto på vercel.com
- Forbind dit GitHub-repository
- Vercel genkender frameworket og bygger automatisk
- Dit site er live med det samme
Alternativ i Danmark: Til Next.js-projekter er Vercel stadig bedst, men du kan også hoste på danske servere via Simply.com's Node.js-hosting.
Tip: For et simpelt HTML/CSS/JS-site er Netlify nemmest. Bare træk og slip din mappe.
13. Domæne
Et domæne er dit hjemmenavn på internettet. F.eks. mitwebsite.dk.
Hvor kan du købe domæner?
- one.com – Dansk, nemt, fra ca. 50 kr/år
- Domæner.dk – Dansk, godt udvalg
- GoDaddy – Internationalt, ofte tilbud
- Namecheap – Billigt, internationalt
Tips til valg af domæne
- Vælg noget kort og nemt at stave
- Undgå bindestreger hvis muligt
.dker bedst til danske sites.comer bedst til internationale sites
Danske forhold
.dkdomæner administreres af DK Hostmaster. Det koster typisk 80-100 kr/år.- Danske domæneregistrarer: DanDomain, One.com, Simply.com, ScanDomain.
- Husk: Dit CVR-nummer skal fremgå på hjemmesiden hvis du driver erhverv.
Sådan sætter du dit domæne op
Når du har købt et domæne, skal du pege det mod din hosting:
- Gå til dit domænes DNS-indstillinger
- Tilføj en "CNAME"-post der peger mod din hosting (f.eks.
your-site.netlify.app) - Vent 24-48 timer på at det udbreder sig
14. Tips til begyndere
1. Giv aldrig op
Alle der kan kode i dag, har engang været completely confused. Det er normalt. Når du sidder fast, så tag en pause, gå en tur, og kom tilbage med friske øjne.
2. Øv dig hver dag
Det behøver ikke være timer hver dag. Bare 15-30 minutters øvelse gør en forskel over tid. Konsistens slår intensitet.
3. Kopier og modificér
Find et website du synes er flot. Prøv at kopiere det. Du lærer enormt meget ved at se hvordan andre har løst problemer. Det er ikke snyd – det er sådan alle lærer.
4. Brug DevTools
Højreklik på ethvert website og vælg "Inspektér" (eller tryk F12). Her kan du se:
- HTML-strukturen
- CSS-reglerne
- Fejl i JavaScript
Du kan endda ændre ting midlertidigt for at eksperimentere!
5. Byg projekter
Teori er fint, men praksis er bedre. Byg ting:
- En personlig hjemmeside
- En opgaveliste
- Et simpelt spil
- En vejr-app
- En omregner
6. Søg hjælp
- Stack Overflow – Det største spørgsmål-svar site for udviklere
- Google – Din bedste ven. Søg på det problem du har
- ChatGPT/AI – Få forklaret ting du ikke forstår
- YouTube – Masser af gratis tutorials
7. Læs andres kode
Gå på GitHub og se hvordan andre har bygget projekter. Du vil opdage nye teknikker og mønstre.
8. Vær tålmodig
Det tager tid at blive god. De fleste siger det tager 6-12 måneder at lære det grundlæggende. Men allerede efter et par uger vil du kunne lave simple ting – og det er super motiverende!
15. Næste skridt
Når du har styr på HTML, CSS og JavaScript grundlæggende, er det tid til at udforske mere.
Frontend Frameworks
Disse frameworks gør det nemmere at bygge store, komplekse applikationer:
React (af Facebook)
- Mest brugt i verden
- Stort jobmarked
- Stor community
- Læringskurve: Middel
Vue.js
- Nemmere at lære end React
- Fantastisk dokumentation
- Perfekt til begyndere der vil have et framework
- Læringskurve: Nem
Svelte
- Nyere og moderne
- Ingen virtual DOM (hurtigere!)
- Meget intuitivt
- Læringskurve: Nem
Min anbefaling: Lær React. Det er det mest efterspurgte på jobmarkedet, og der er flest ressourcer til rådighed.
Backend (hvis du vil bygge hele applikationer)
- Node.js – JavaScript på serveren
- Python – Enkelt og alsidigt
- PHP – Stadig populært (WordPress)
Database
- Firebase – Nemt at komme i gang
- Supabase – Open source alternativ
- MongoDB – populært NoSQL
- PostgreSQL – populært SQL
16. Eksempel-projekt: Personlig portfolio
Lad os samle alt du har lært og bygge et komplet portfolio-site.
Struktur
portfolio/
├── index.html
├── style.css
└── script.js
index.html
<!DOCTYPE html>
<html lang="da">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mit Portfolio - [Dit Navn]</title>
<link rel="stylesheet" href="style.css">
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600;700&display=swap" rel="stylesheet">
</head>
<body>
<header>
<nav>
<div class="logo">[Dit Navn]</div>
<ul>
<li><a href="#hjem">Hjem</a></li>
<li><a href="#om">Om mig</a></li>
<li><a href="#projekter">Projekter</a></li>
<li><a href="#kontakt">Kontakt</a></li>
</ul>
<button id="temaKnap" class="tema-knap">🌙</button>
</nav>
</header>
<section id="hjem" class="hero">
<div class="hero-indhold">
<h1>Hej, jeg er <span class="fremhæv">[Dit Navn]</span></h1>
<p class="hero-tekst">Jeg er [beskriv dig selv f.eks. "webudvikler med passion for pænt design"]</p>
<a href="#projekter" class="knap">Se mine projekter</a>
</div>
</section>
<section id="om" class="sektion">
<h2>Om mig</h2>
<div class="om-grid">
<div class="om-tekst">
<p>Her kan du fortælle om dig selv. Hvad laver du? Hvad er du god til? Hvad brænder du for?</p>
<p>Skriv 2-3 afsnit om dig selv. Vær personlig, men professionel.</p>
</div>
<div class="om-færdigheder">
<h3> Mine færdigheder</h3>
<ul class="færdighedsliste">
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
<li>[Tilføj flere]</li>
</ul>
</div>
</div>
</section>
<section id="projekter" class="sektion mørk">
<h2>Projekter</h2>
<div class="projekt-grid">
<div class="projekt-kort">
<div class="projekt-billede">
<span>Projekt 1</span>
</div>
<div class="projekt-info">
<h3>Projektnavn</h3>
<p>Kort beskrivelse af projektet</p>
<a href="#" class="læs-mere">Læs mere →</a>
</div>
</div>
<div class="projekt-kort">
<div class="projekt-billede">
<span>Projekt 2</span>
</div>
<div class="projekt-info">
<h3>Projektnavn</h3>
<p>Kort beskrivelse af projektet</p>
<a href="#" class="læs-mere">Læs mere →</a>
</div>
</div>
<div class="projekt-kort">
<div class="projekt-billede">
<span>Projekt 3</span>
</div>
<div class="projekt-info">
<h3>Projektnavn</h3>
<p>Kort beskrivelse af projektet</p>
<a href="#" class="læs-mere">Læs mere →</a>
</div>
</div>
</div>
</section>
<section id="kontakt" class="sektion">
<h2>Kontakt mig</h2>
<form id="kontaktForm">
<div class="form-gruppe">
<label for="navn">Navn</label>
<input type="text" id="navn" name="navn" required>
</div>
<div class="form-gruppe">
<label for="email">Email</label>
<input type="email" id="email" name="email" required>
</div>
<div class="form-gruppe">
<label for="besked">Besked</label>
<textarea id="besked" name="besked" rows="5" required></textarea>
</div>
<button type="submit" class="knap">Send besked</button>
</form>
</section>
<footer>
<p>© 2026 [Dit Navn]. Bygget med ❤️ og meget kaffe.</p>
</footer>
<script src="script.js"></script>
</body>
</html>
style.css
/* Reset og grundlæggende */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
font-family: 'Poppins', sans-serif;
line-height: 1.6;
color: #333;
transition: background 0.3s, color 0.3s;
}
body.mørk {
background-color: #1a1a1a;
color: #f0f0f0;
}
/* Navigation */
header {
position: fixed;
top: 0;
width: 100%;
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
z-index: 1000;
transition: background 0.3s;
}
body.mørk header {
background: rgba(26, 26, 26, 0.95);
}
nav {
display: flex;
justify-content: space-between;
align-items: center;
max-width: 1200px;
margin: 0 auto;
padding: 1rem 2rem;
}
.logo {
font-size: 1.5rem;
font-weight: 700;
color: #667eea;
}
nav ul {
display: flex;
list-style: none;
gap: 2rem;
}
nav a {
text-decoration: none;
color: #333;
font-weight: 500;
transition: color 0.3s;
}
body.mørk nav a {
color: #f0f0f0;
}
nav a:hover {
color: #667eea;
}
.tema-knap {
background: none;
border: none;
font-size: 1.5rem;
cursor: pointer;
}
/* Hero sektion */
.hero {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
padding: 2rem;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
.hero h1 {
font-size: 3rem;
margin-bottom: 1rem;
}
.fremhæv {
color: #ffd700;
}
.hero-tekst {
font-size: 1.2rem;
margin-bottom: 2rem;
opacity: 0.9;
}
/* Knapper */
.knap {
display: inline-block;
padding: 0.75rem 2rem;
background: white;
color: #667eea;
text-decoration: none;
border-radius: 50px;
font-weight: 600;
transition: transform 0.3s, box-shadow 0.3s;
}
.knap:hover {
transform: translateY(-3px);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
}
/* Sektioner */
.sektion {
padding: 5rem 2rem;
max-width: 1200px;
margin: 0 auto;
}
.sektion.mørk {
background: #f8f9fa;
max-width: 100%;
}
body.mørk .sektion.mørk {
background: #2a2a2a;
}
.sektion h2 {
text-align: center;
font-size: 2.5rem;
margin-bottom: 3rem;
}
/* Om mig */
.om-grid {
display: grid;
grid-template-columns: 2fr 1fr;
gap: 3rem;
align-items: start;
}
.om-tekst p {
margin-bottom: 1rem;
font-size: 1.1rem;
}
.færdighedsliste {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
list-style: none;
}
.færdighedsliste li {
background: #667eea;
color: white;
padding: 0.5rem 1rem;
border-radius: 20px;
font-size: 0.9rem;
}
/* Projekter */
.projekt-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
}
.projekt-kort {
background: white;
border-radius: 10px;
overflow: hidden;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
transition: transform 0.3s;
}
body.mørk .projekt-kort {
background: #333;
}
.projekt-kort:hover {
transform: translateY(-10px);
}
.projekt-billede {
height: 200px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 1.5rem;
font-weight: 600;
}
.projekt-info {
padding: 1.5rem;
}
.projekt-info h3 {
margin-bottom: 0.5rem;
}
.projekt-info p {
color: #666;
margin-bottom: 1rem;
}
body.mørk .projekt-info p {
color: #aaa;
}
.læs-mere {
color: #667eea;
text-decoration: none;
font-weight: 600;
}
/* Kontaktformular */
#kontaktForm {
max-width: 600px;
margin: 0 auto;
}
.form-gruppe {
margin-bottom: 1.5rem;
}
.form-gruppe label {
display: block;
margin-bottom: 0.5rem;
font-weight: 500;
}
.form-gruppe input,
.form-gruppe textarea {
width: 100%;
padding: 0.75rem;
border: 2px solid #ddd;
border-radius: 5px;
font-family: inherit;
font-size: 1rem;
transition: border-color 0.3s;
}
body.mørk .form-gruppe input,
body.mørk .form-gruppe textarea {
background: #444;
border-color: #555;
color: white;
}
.form-gruppe input:focus,
.form-gruppe textarea:focus {
outline: none;
border-color: #667eea;
}
/* Footer */
footer {
text-align: center;
padding: 2rem;
background: #333;
color: white;
}
script.js
// Tema-skifter
const temaKnap = document.getElementById("temaKnap");
const body = document.body;
// Tjek for gemt præference
if (localStorage.getItem("tema") === "mørk") {
body.classList.add("mørk");
temaKnap.textContent = "☀️";
}
temaKnap.addEventListener("click", function() {
body.classList.toggle("mørk");
if (body.classList.contains("mørk")) {
temaKnap.textContent = "☀️";
localStorage.setItem("tema", "mørk");
} else {
temaKnap.textContent = "🌙";
localStorage.setItem("tema", "lys");
}
});
// Smooth scroll for navigation links
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener("click", function(event) {
event.preventDefault();
const mål = document.querySelector(this.getAttribute("href"));
mål.scrollIntoView({ behavior: "smooth" });
});
});
// Kontaktformular
const form = document.getElementById("kontaktForm");
form.addEventListener("submit", function(event) {
event.preventDefault();
const navn = document.getElementById("navn").value;
const email = document.getElementById("email").value;
const besked = document.getElementById("besked").value;
// Tjek email
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(email)) {
alert("Indtast venligst en gyldig email-adresse");
return;
}
// Simuler sending (erstat med rigtig backend/API)
alert(`Tak for din besked, ${navn}! Jeg vender tilbage hurtigst muligt.`);
form.reset();
});
// Fade-in animation ved scroll
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.style.opacity = "1";
entry.target.style.transform = "translateY(0)";
}
});
}, { threshold: 0.1 });
// Animer sektioner
document.querySelectorAll(".sektion").forEach(sektion => {
sektion.style.opacity = "0";
sektion.style.transform = "translateY(30px)";
sektion.style.transition = "opacity 0.6s, transform 0.6s";
observer.observe(sektion);
});
17. HTML & CSS for danske freelancere
Når du bygger hjemmesider til danske kunder, er der nogle særlige forhold du skal være opmærksom på — både juridisk, teknisk og designmæssigt.
Lovkrav for danske hjemmesider
Hvis du driver erhverv, skal dit CVR-nummer fremgå på hjemmesiden. Har du momsregistrering, skal momsbeløb også fremgå. Du skal desuden have et cookie-samtykke (GDPR) på plads — brug et værktøj som Cookiebot eller Cookie Information til at lave en cookie-popup der overholder dansk lovgivning.
Dansk webdesign
Danske hjemmesider er kendt for et rent, minimalistisk design med fokus på brugervenlighed. Mørk tilstand er populært i Danmark, og de fleste nyere sites understøtter det. Hold layoutet enkelt, med god whitespace og tydelig typografi.
Typografi til dansk
Vælg skrifttyper der understøtter danske tegn (æ, ø, å) ordentligt. Gode valg:
- Public Sans — moderne, open source, designet til brugergrænseflader
- Inter — populær blandt danske udviklere, fremragende læsbarhed
- IBM Plex Sans — professionel og understøtter danske tegn perfekt
Brug Google Fonts eller systemfonts for at undgå forsinkelser.
Hosting og domæner på dansk
Til danske kunder kan du spare penge ved at bruge danske udbydere:
- Simply.com — statisk og Node.js-hosting, dansk support, betaling i DKK
- UnoEuro — stabil dansk hosting til gode priser
- NordicWay — statisk webhotel med dansk support
.dk domæner købes hos DK Hostmaster eller hos danske registrarer som DanDomain, One.com, Simply.com eller ScanDomain.
Tilgængelighed (WCAG 2.1)
WCAG 2.1-kravene gælder også i Danmark, især for offentlige hjemmesider. Brug lang="da" på dit HTML-element, sørg for kontrastfyldte farver, og test med skærmlæsere. Danske brugere forventer at din side fungerer med tastaturnavigation.
Værktøjer til danske freelancere
- Dinero — dansk regnskabsprogram, perfekt til freelancere
- MobilePay — standard til betaling i Danmark
- Airtable — populær CRM blandt danske selvstændige
- Penneo — digital signatur og dokumenthåndtering
Afsluttende ord
Tillykke! Du har lært det grundlæggende i HTML, CSS og JavaScript. Du ved nu hvordan du:
- Opretter og strukturerer indhold med HTML
- Styler dit website med CSS
- Gør det interaktivt med JavaScript
- Lægger det online
- Køber et domæne
Husk: Det handler ikke om at lære alt på én gang. Det handler om at blive bedre lidt efter lidt. Hver gang du byder noget nyt, lærer du lidt mere.
De mest succesfulde udviklere er ikke dem der lærte hurtigst – det er dem der aldrig gav op.
Så hvad venter du på? Åbn VS Code og begynd at bygge noget fantastisk!
Du har det her. 💪
Denne guide blev oprettet i 2026. Teknologier udvikler sig, men grundlæggende HTML, CSS og JavaScript forbliver det samme.
Sidst opdateret: Juni 2026