logo CoderDojo

Web - Maak je eigen flashcardtrainer

Met flashcards kun je woorden, sommen en andere dingen oefenen. Op de voorkant staat een vraag. Draai de kaart om en je ziet het antwoord.

In deze instructie bouw je jouw eigen flashcardtrainer met HTML, CSS en JavaScript. Je geeft de kaarten een eigen ontwerp en laat ze echt omdraaien.

Je kunt de trainer bijvoorbeeld gebruiken om woordjes voor Engels te oefenen. Op de voorkant zet je apple en op de achterkant zet je appel. Je kunt hem ook vullen met tafels, topografie of vragen voor een proefwerk.

Een flashcard met een voor- en achterkant

Dit ga je maken

Aan het einde kun je:

Werk rustig van boven naar beneden. Test je website na iedere stap.

Wat heb je nodig?

Een computer met een browser, bijvoorbeeld Firefox, Chrome of Edge.

Visual Studio Code, vaak afgekort tot VS Code, is een programma waarin je code kunt schrijven. Het is gratis en werkt op Windows, macOS en Linux.

Downloaden

Tijdens de dojo kun je het installatiebestand sneller downloaden van de CoderDojo-server:

download

Je kunt VS Code ook downloaden van de officiële website: Download Visual Studio Code.

Kies de download die bij jouw computer past:

  • Windows: kies bij voorkeur de User Installer. Daarvoor heb je meestal geen beheerderswachtwoord nodig.
  • macOS: download het bestand voor macOS. De Universal-versie werkt op Macs met een Intel-processor en op nieuwere Macs met Apple silicon.
  • Linux: kies het pakket voor jouw Linux-versie. Voor Ubuntu en Debian is dat meestal het bestand dat eindigt op .deb.

Weet je niet welke versie je nodig hebt? Vraag dan een mentor om mee te kijken.

Installeren op Windows

  1. Open het gedownloade bestand. De naam begint meestal met VSCodeUserSetup en eindigt op .exe.
  2. Volg de stappen van het installatieprogramma.
  3. Start Visual Studio Code na de installatie.

Een uitgebreide uitleg staat in de officiële Windows-handleiding.

Installeren op macOS

  1. Open het gedownloade bestand dat eindigt op .dmg.
  2. Sleep Visual Studio Code.app naar de map Applications of Programma's.
  3. Open Visual Studio Code vanuit die map.

Een uitgebreide uitleg staat in de officiële macOS-handleiding.

Installeren op Linux

Op Ubuntu of Debian kun je meestal dubbelklikken op het gedownloade .deb-bestand. Het softwarecentrum helpt je dan met de installatie.

Gebruik je een andere Linux-versie of lukt de installatie niet? Vraag een mentor om hulp of bekijk de officiële Linux-handleiding.

Een projectmap openen

In een projectmap bewaar je alle bestanden die bij jouw programma horen.

  1. Start Visual Studio Code.
  2. Kies in het menu File → Open Folder…. In een Nederlandse versie heet dit Bestand → Map openen….
  3. Zoek de projectmap die je voor de instructie hebt gemaakt.
  4. Kies Select Folder of Open.

Links in VS Code staat de Explorer. Daar zie je de projectmap en de bestanden die erin staan.

Vraagt VS Code of je de makers van de bestanden vertrouwt? Bij een map die je zelf hebt gemaakt, kun je kiezen dat je de makers vertrouwt.

Een bestand maken

  1. Beweeg met de muis over de naam van de projectmap in de Explorer.
  2. Klik op het pictogram New File. Dat ziet eruit als een vel papier met een plusteken.
  3. Typ de volledige bestandsnaam uit de instructie, bijvoorbeeld index.html.
  4. Druk op Enter.

Klik op een bestandsnaam in de Explorer om het bestand te openen. In het grote vlak in het midden kun je de code typen of plakken.

Bewaar je werk regelmatig met Ctrl+S op Windows en Linux, of Cmd+S op macOS. Een witte stip naast de bestandsnaam betekent dat er nog onopgeslagen wijzigingen zijn.

VS Code kan vragen of je wilt inloggen of AI-functies wilt gebruiken. Dat is voor de CoderDojo-instructies niet nodig. Je kunt zo’n vraag sluiten.

Maak een nieuwe map met de naam flashcards. Maak daarin deze drie bestanden:

1
2
3
4
flashcards
├── index.html
├── style.css
└── script.js

Let op: controleer goed of de namen precies hetzelfde zijn. style.css.txt is bijvoorbeeld niet hetzelfde als style.css.

Open daarna de map flashcards in Visual Studio Code zoals hierboven is uitgelegd. Maak de drie bestanden met de knop New File.

Stap 1: de pagina maken met HTML

HTML bepaalt wat er op een webpagina staat. Open index.html en zet deze code erin:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!DOCTYPE html>
<html lang="nl">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Mijn flashcardtrainer</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <h1>Mijn flashcardtrainer</h1>
  <p>Klik op de kaart om het antwoord te bekijken.</p>

  <div class="kaart">
    <div class="kaart-binnenkant">
      <div class="kaart-voorkant">
        <h2>Vraag</h2>
        <p>Wat is de hoofdstad van Frankrijk?</p>
      </div>

      <div class="kaart-achterkant">
        <h2>Antwoord</h2>
        <p>Parijs</p>
      </div>
    </div>
  </div>

  <script src="script.js"></script>
</body>
</html>

Bewaar index.html en open het bestand daarna vanuit de map flashcards in de browser. Je ziet nu tekst, maar het lijkt nog niet op een echte kaart. Dat veranderen we met CSS.

Na een wijziging bewaar je het bestand in VS Code en vernieuw je de pagina in de browser. Zo controleer je steeds wat jouw code doet.

Stap 2: de kaart opmaken met CSS

CSS bepaalt hoe de pagina eruitziet. Open style.css en begin met de pagina:

1
2
3
4
5
6
body {
  font-family: Arial, sans-serif;
  background-color: #fff4cc;
  color: #17324d;
  text-align: center;
}

Sla het bestand op en vernieuw de pagina. De achtergrond en de letters zijn nu veranderd.

Zet onderaan in style.css ook de vorm van de kaart:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
.kaart {
  width: 320px;
  height: 210px;
  margin: 40px auto;
}

.kaart-voorkant,
.kaart-achterkant {
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  padding: 30px;
  border: 5px solid #176b87;
  border-radius: 20px;
  background-color: #dafffb;
}

Probeer het zelf

Verander steeds één ding en kijk wat er gebeurt:

Op htmlcolorcodes.com/color-names vind je namen en codes van kleuren.

Stap 3: een voor- en achterkant maken

De twee kanten staan nu nog onder elkaar. Met extra CSS leggen we ze op elkaar.

De twee kanten liggen op elkaar

Vervang de CSS van .kaart door:

1
2
3
4
5
6
7
.kaart {
  width: 320px;
  height: 210px;
  margin: 40px auto;
  perspective: 1000px;
  cursor: pointer;
}

Zet daarna deze nieuwe regels onderaan in style.css:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
.kaart-binnenkant {
  position: relative;
  width: 100%;
  height: 100%;
  transition: transform 0.6s;
  transform-style: preserve-3d;
}

.kaart-voorkant,
.kaart-achterkant {
  position: absolute;
  backface-visibility: hidden;
}

.kaart-achterkant {
  background-color: #ffd6e0;
  transform: rotateY(180deg);
}

De voor- en achterkant liggen nu precies op elkaar. De achterkant is alvast een halve slag gedraaid en daardoor verborgen.

Sommige CSS in dit stukje ziet er misschien ingewikkeld uit. Je hoeft nog niet alles uit je hoofd te kennen. De regels zorgen samen voor het draaieffect.

Stap 4: de kaart omdraaien

We maken eerst in CSS een regel voor een omgedraaide kaart. Zet deze regel onderaan in style.css:

1
2
3
.kaart.omgedraaid .kaart-binnenkant {
  transform: rotateY(180deg);
}

JavaScript bepaalt wat er gebeurt wanneer je op de kaart klikt. Open script.js en voeg deze functie toe:

1
2
3
4
function draaiKaartOm() {
  const kaart = document.querySelector(".kaart");
  kaart.classList.toggle("omgedraaid");
}

Een functie is een klein programma met een naam. Deze functie zet de class omgedraaid aan of uit.

De functie moet nog worden gestart wanneer je op de kaart klikt. Verander in index.html deze regel:

1
<div class="kaart">

in:

1
<div class="kaart" onclick="draaiKaartOm()">

Sla alle bestanden op en klik op de kaart. Draait hij om?

Probeer het zelf

In deze regel bepaalt 0.6s hoe lang de draai duurt:

1
transition: transform 0.6s;

Probeer bijvoorbeeld 0.2s en 2s. Welke snelheid vind jij prettig?

Stap 5: meer vragen toevoegen

Nu staat de vraag nog vast in de HTML. We gaan de vragen bewaren in JavaScript.

Vervang alles in script.js door:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const kaarten = [
  {
    vraag: "Wat is de hoofdstad van Frankrijk?",
    antwoord: "Parijs"
  },
  {
    vraag: "Hoeveel is 8 × 7?",
    antwoord: "56"
  },
  {
    vraag: "Welk dier is het snelst op het land?",
    antwoord: "De cheeta"
  }
];

let huidigKaartnummer = 0;

function draaiKaartOm() {
  const kaart = document.querySelector(".kaart");
  kaart.classList.toggle("omgedraaid");
}

function toonHuidigeKaart() {
  const kaart = kaarten[huidigKaartnummer];
  document.querySelector("#vraag").textContent = kaart.vraag;
  document.querySelector("#antwoord").textContent = kaart.antwoord;
}

toonHuidigeKaart();

De rechte haken [ en ] maken een lijst. Ieder onderdeel van de lijst bevat een vraag en een antwoord.

Maak een eigen kaart

Verander één van de vragen en antwoorden. Of zet voor de laatste ]; een extra kaart. Vergeet de komma na de vorige kaart niet:

1
2
3
4
  {
    vraag: "Hoeveel dagen heeft een week?",
    antwoord: "7"
  }

Vernieuw de pagina. De eerste vraag uit JavaScript staat nu op de kaart.

We kunnen de nieuwe kaarten nog niet bekijken. Daarvoor moeten we eerst door naar stap 6.

Stap 6: naar de volgende kaart

JavaScript zoekt straks de teksten op met een id. Verander in index.html het volgende:

1
<p>Wat is de hoofdstad van Frankrijk?</p>

wordt:

1
<p id="vraag">Hier komt de vraag</p>

en:

1
<p>Parijs</p>

wordt:

1
<p id="antwoord">Hier komt het antwoord</p>

Zet in index.html, direct onder de kaart, een knop:

1
<button onclick="toonVolgendeKaart()">Volgende kaart</button>

Geef de knop onderaan in style.css een duidelijke vorm:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
button {
  padding: 12px 20px;
  border: 0;
  border-radius: 10px;
  background-color: #176b87;
  color: white;
  font-size: 18px;
  cursor: pointer;
}

button:hover {
  background-color: #0f4c5c;
}

Zet deze nieuwe functie in script.js, boven toonHuidigeKaart();:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
function toonVolgendeKaart() {
  huidigKaartnummer = huidigKaartnummer + 1;

  if (huidigKaartnummer === kaarten.length) {
    huidigKaartnummer = 0;
  }

  const kaart = document.querySelector(".kaart");

  if (kaart.classList.contains("omgedraaid")) {
    const binnenkant = document.querySelector(".kaart-binnenkant");
    binnenkant.addEventListener("transitionend", toonHuidigeKaart, {
      once: true
    });
    kaart.classList.remove("omgedraaid");
  } else {
    toonHuidigeKaart();
  }
}

De functie telt één op bij het kaartnummer. Na de laatste kaart begint hij weer bij de eerste. Als het antwoord zichtbaar is, wacht JavaScript op transitionend: het einde van de draai. Pas daarna komen de teksten van de volgende kaart in beeld. Met once: true wacht de browser maar één keer op het einde van deze draai.

Test de knop. Zie je alle vragen langskomen?

Stap 7: zelf een kaart toevoegen

We maken een formulier. Zet deze HTML onder de knop:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<section class="nieuwe-kaart">
  <h2>Maak een nieuwe kaart</h2>

  <label for="nieuwe-vraag">Vraag</label>
  <input id="nieuwe-vraag" type="text">

  <label for="nieuw-antwoord">Antwoord</label>
  <input id="nieuw-antwoord" type="text">

  <button onclick="voegKaartToe()">Kaart toevoegen</button>
  <p id="melding"></p>
</section>

Maak het formulier overzichtelijk met CSS:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
.nieuwe-kaart {
  max-width: 420px;
  margin: 50px auto;
  padding: 24px;
  border-radius: 16px;
  background-color: white;
  text-align: left;
}

label,
input {
  display: block;
  box-sizing: border-box;
  width: 100%;
}

label {
  margin-top: 14px;
  font-weight: bold;
}

input {
  margin: 6px 0 18px;
  padding: 10px;
  border: 2px solid #176b87;
  border-radius: 8px;
  font-size: 16px;
}

Zet deze functie in script.js, weer boven toonHuidigeKaart();:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
function voegKaartToe() {
  const vraag = document.querySelector("#nieuwe-vraag").value;
  const antwoord = document.querySelector("#nieuw-antwoord").value;

  if (vraag === "" || antwoord === "") {
    document.querySelector("#melding").textContent =
      "Vul een vraag én een antwoord in.";
    return;
  }

  kaarten.push({
    vraag: vraag,
    antwoord: antwoord
  });

  document.querySelector("#nieuwe-vraag").value = "";
  document.querySelector("#nieuw-antwoord").value = "";
  document.querySelector("#melding").textContent = "Je kaart is toegevoegd.";
}

push() stopt de nieuwe kaart achteraan in de lijst. Voeg een kaart toe en zoek hem daarna op met de knop Volgende kaart.

Stap 8: kaarten bewaren

Je zelfgemaakte kaarten verdwijnen nog wanneer je de pagina opnieuw laadt. De browser heeft een klein geheugen voor websites: localStorage.

Verander bovenaan script.js:

1
const kaarten = [

in:

1
const standaardKaarten = [

Zet direct na de lijst met standaardkaarten deze regel:

1
let kaarten = laadKaarten();

Voeg daarna twee nieuwe functies toe:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
function bewaarKaarten() {
  const tekst = JSON.stringify(kaarten);
  localStorage.setItem("flashcards", tekst);
}

function laadKaarten() {
  const tekst = localStorage.getItem("flashcards");

  if (tekst === null) {
    return standaardKaarten;
  }

  return JSON.parse(tekst);
}

JSON.stringify() pakt de kaarten in als tekst. JSON.parse() pakt die tekst later weer uit.

Laat de browser de kaarten bewaren na het toevoegen. Zoek in voegKaartToe() dit stukje op:

1
2
3
4
  kaarten.push({
    vraag: vraag,
    antwoord: antwoord
  });

Zet er direct onder:

1
  bewaarKaarten();

De grote geheugentest

  1. Voeg een zelfgemaakte kaart toe.
  2. Vernieuw de pagina.
  3. Klik door de kaarten heen.

Is je nieuwe kaart er nog? Dan werkt het geheugen van je trainer.

Extra uitdaging: kaarten downloaden

Met deze uitbreiding kun je jouw kaarten meenemen naar een andere computer. Maak eerst in index.html, onder het formulier voor een nieuwe kaart, een tweede paneel:

1
2
3
4
5
6
<section class="bestandskaart">
  <h2>Kaarten bewaren en meenemen</h2>
  <p>Download jouw kaarten als een bestand.</p>
  <button onclick="downloadKaarten()">Download mijn kaarten</button>
  <p id="bestandsmelding"></p>
</section>

Zoek in style.css deze regel op:

1
.nieuwe-kaart {

en verander hem in:

1
2
.nieuwe-kaart,
.bestandskaart {

Het nieuwe paneel krijgt daardoor dezelfde witte achtergrond en afgeronde hoeken als het formulier.

Zet deze functie in script.js:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
function downloadKaarten() {
  const tekst = JSON.stringify(kaarten, null, 2);
  const bestand = new Blob([tekst], { type: "application/json" });
  const link = document.createElement("a");

  link.href = URL.createObjectURL(bestand);
  link.download = "mijn-flashcards.json";
  link.click();
  URL.revokeObjectURL(link.href);
  document.querySelector("#bestandsmelding").textContent =
    "Je kaarten zijn gedownload.";
}

Klik op de knop. Je browser downloadt het bestand mijn-flashcards.json.

Deze functie gebruikt een paar nieuwe browsercommando’s. Je hoeft ze niet uit je hoofd te leren. Probeer het gedownloade bestand eens te openen in je codeprogramma. Herken je jouw vragen en antwoorden?

Extra uitdaging: kaarten inladen

Vervang het paneel .bestandskaart in index.html door deze uitgebreidere versie:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<section class="bestandskaart">
  <h2>Kaarten bewaren en meenemen</h2>
  <p>Download jouw kaarten als een bestand.</p>
  <button onclick="downloadKaarten()">Download mijn kaarten</button>

  <label for="kaartbestand">Kies een kaartbestand</label>
  <input
    id="kaartbestand"
    type="file"
    accept=".json"
    onchange="uploadKaarten(event)"
  >
  <p id="bestandsmelding"></p>
</section>

Voeg daarna deze functie toe aan script.js:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
function uploadKaarten(event) {
  const bestand = event.target.files[0];

  if (bestand === undefined) {
    return;
  }

  const lezer = new FileReader();

  lezer.addEventListener("load", function verwerkBestand() {
    const ingeladenKaarten = JSON.parse(lezer.result);
    kaarten = ingeladenKaarten;
    huidigKaartnummer = 0;
    bewaarKaarten();
    toonHuidigeKaart();
    document.querySelector("#bestandsmelding").textContent =
      "Je kaarten zijn ingeladen.";
  });

  lezer.readAsText(bestand);
}

Kies het bestand mijn-flashcards.json dat je eerder hebt gedownload. De trainer bewaart de ingeladen kaarten ook meteen in de browser.

Let op: kies alleen een flashcardbestand dat met deze trainer is gemaakt. Bij een ander bestand kan de trainer een foutmelding geven.

Nog meer ideeën

Kies een uitbreiding die bij jou past:

Klaar

Je hebt een website gebouwd met drie talen:

Je kunt de trainer vullen met Engelse woorden, tafels, topografie of iets anders dat jij wilt oefenen.