Step-by-Step Guide to Building a Simple Flashcard App with HTML, CSS, and JavaScript

In this tutorial, we will explore how to create a Simple Flashcard Application using HTML, CSS, JavaScript (JS), and jQuery. This step-by-step guide is designed to help you build an interactive and user-friendly flashcard app that can be used for studying, quizzes, or learning new concepts effectively.

What is a Flashcard App?

A Flashcard App is a digital tool designed to help users learn and memorize information efficiently. It mimics the traditional flashcard learning method, where each card contains a question or term on one side and the corresponding answer or explanation on the other. Flashcard apps are widely used for studying, language learning, and mastering various topics due to their interactive and engaging approach.

Here, we will build a Flashcard Application with a focus on simplicity and essential functionality. This application will include key features such as the ability to add and remove flashcards and flip flashcards to view either the question or the answer side. These core features make it an excellent starting point for creating an interactive and customizable learning tool.

Let's Begin the Coding Side

Step 1: Creating the Main Elements

First, let's create the HTML file for our Flashcard Application. This file will include the essential elements such as the form fields for adding new flashcards and the display area for viewing the flashcards. The structure is designed to ensure functionality and ease of use. Check out the script below for detailed insights into this step.

index.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3.     <meta charset="UTF-8">
  4.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  5.     <title>Simple Flashcard using HTML, CSS , annd JS</title>
  6.     <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,[email protected],100..700,0..1,-50..200" />
  7.     <link rel="stylesheet" href="style.css">
  8.     <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
  9. </head>
  10.     <div id="main-container">
  11.         <h1 id="app-title">Simple Flashcard using HTML, CSS, and JS</h1>
  12.         <div class="flashcard-action">
  13.             <button id="btn-new-flashcard">
  14.                 <span class="material-symbols-outlined">add</span>
  15.                 Add New Flashcard
  16.             </button>
  17.         </div>
  18.         <div class="flashcards"></div>
  19.     </div>
  20.     <div id="form-modal">
  21.         <div class="form-modal-backdrop">
  22.             <div class="form-modal-dialog">
  23.                 <button class="form-modal-close dynapuff-font">X</button>
  24.                 <h4 class="form-modal-title dynapuff-font"><strong>Add New Flashcard</strong></h4>
  25.                 <form action="" id="flashcard-form">
  26.                     <input type="hidden" id="fc_id">
  27.                     <div class="form-group">
  28.                         <label for="question" class="form-label">Flashcard Question:</label>
  29.                         <textarea id="question" name="question" class="form-control" rows="3"></textarea>
  30.                     </div>
  31.                     <div class="form-group">
  32.                         <label for="answer" class="form-label">Flashcard Answer:</label>
  33.                         <textarea id="answer" name="answer" class="form-control" rows="3"></textarea>
  34.                     </div>
  35.                     <div class="form-group-action">
  36.                         <button class="btn-form-action">Save</button>
  37.                     </div>
  38.                 </form>
  39.             </div>
  40.         </div>
  41.     </div>
  42.     <script src="script.js"></script>
  43. </body>
  44. </html>

Step 2: Desiging the Elements

Next, let's create the Cascading Stylesheet (CSS) for the Flashcard Application. This CSS file will include the style rules that define the visual appearance of the application's elements, such as layout, colors, and typography. Additionally, it will include animations and transitions to enhance the interactivity and user experience when flipping the flashcards. Check out the style script below for more details.

style.css

  1. @import url('https://fonts.googleapis.com/css2?family=DynaPuff:[email protected]&family=Ubuntu:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap');
  2.  
  3. * {
  4.     box-sizing: border-box;
  5.     font-family: "Ubuntu", serif;
  6.     font-weight: 300;
  7.     font-style: normal;
  8. }
  9.  
  10. .dynapuff-font {
  11.     font-family: "DynaPuff", serif;
  12.     font-optical-sizing: auto;
  13.     font-style: normal;
  14.     font-variation-settings:
  15.         "wdth" 100;
  16. }
  17.  
  18. b,
  19. strong {
  20.     font-family: "Ubuntu", serif;
  21.     font-weight: 700;
  22.     font-style: normal;
  23. }
  24.  
  25. i {
  26.     font-family: "Ubuntu", serif;
  27.     font-weight: 400;
  28.     font-style: italic;
  29. }
  30.  
  31. html,
  32. body {
  33.     margin: unset;
  34.     padding: unset;
  35.     height: 100%;
  36.     min-height: 100%;
  37.     width: 100%;
  38.     min-width: 100%;
  39.     overflow: auto;
  40. }
  41.  
  42. body {
  43.     display: flex;
  44.     flex-flow: column wrap;
  45.     justify-content: center;
  46.     align-items: center;
  47.     background-color: #ebedee;
  48.     background-image: linear-gradient(120deg, #fdfbfb 0%, #ebedee 100%);
  49. }
  50.  
  51. #main-container {
  52.     width: 100%;
  53.     max-height: 100%;
  54.     max-width: 700px;
  55.     padding: 15px 15px;
  56. }
  57.  
  58. #app-title {
  59.     font-weight: 700;
  60.     text-align: center;
  61. }
  62.  
  63. .flashcards {
  64.     width: 100%;
  65.     display: inline-grid;
  66.     gap: 1rem;
  67.     grid-template-columns: repeat(auto-fit, calc((100% - 2rem) / 3));
  68.     align-items: center;
  69.     justify-content: center;
  70.     padding: 15px 0;
  71. }
  72.  
  73. @media (max-width: 700px) {
  74.     div.flashcards {
  75.         grid-template-columns: repeat(auto-fit, calc((100% - 1rem) / 2));
  76.     }
  77. }
  78.  
  79. @media (max-width: 400px) {
  80.     div.flashcards {
  81.         grid-template-columns: 1fr;
  82.     }
  83. }
  84.  
  85. .flashcards:empty:before {
  86.     display: block;
  87.     position: relative;
  88.     content: "No Flashcard Listed Yet";
  89.     width: 100%;
  90.     text-align: center;
  91.     font-style: italic;
  92.     color: #c8c5c5;
  93. }
  94.  
  95. .flashcards .card {
  96.     background-color: transparent;
  97.     width: 100%;
  98.     height: 300px;
  99.     /* border: 1px solid #f1f1f1; */
  100.     perspective: 1000px;
  101.     cursor: pointer;
  102. }
  103.  
  104. .flashcards .card.active .card-container {
  105.     transform: rotateY(180deg);
  106. }
  107.  
  108. .flashcards .card .card-container {
  109.     position: relative;
  110.     width: 100%;
  111.     height: 100%;
  112.     text-align: center;
  113.     transition: transform 0.8s;
  114.     transform-style: preserve-3d;
  115. }
  116.  
  117. .flashcards .card .card-front,
  118. .flashcards .card .card-back {
  119.     position: absolute;
  120.     display: flex;
  121.     flex-flow: column wrap;
  122.     width: 100%;
  123.     height: 100%;
  124.     -webkit-backface-visibility: hidden;
  125.     backface-visibility: hidden;
  126.     overflow: hidden;
  127.     border-radius: 5px;
  128.     box-shadow: 3px 3px 4px #00000087;
  129.     padding: 15px 5px;
  130. }
  131. .flashcards .card .card-front-title,
  132. .flashcards .card .card-back-title{
  133.     letter-spacing: 1px;
  134. }
  135.  
  136. .flashcards .card .card-front-text,
  137. .flashcards .card .card-back-text{
  138.     flex-grow: 1;
  139.     display: flex;
  140.     align-items: center;
  141.     justify-content: center;
  142.     padding: 5px;
  143.     font-size: 12px;
  144.     letter-spacing: 1px;
  145. }
  146.  
  147. .flashcards .card .card-front {
  148.     background-color: #2E5077;
  149.     color: #fff;
  150. }
  151.  
  152. .flashcards .card .card-back {
  153.     background-color: #A5BFCC;
  154.     color: white;
  155.     transform: rotateY(180deg);
  156. }
  157.  
  158. button.card-action {
  159.     background: #F95454;
  160.     color: #fff;
  161.     border: unset;
  162.     outline: unset;
  163.     cursor: unset;
  164.     border-radius: 3px;
  165. }
  166.  
  167. button.card-action:hover, button.card-action:active{
  168.     background: #b22d2d;
  169. }
  170.  
  171. div#form-modal {
  172.     position: fixed;
  173.     display: none;
  174.     width: 100%;
  175.     height: 100%;
  176.     top: 0;
  177.     left: 0;
  178.     opacity: 0;
  179.     transition: all .5s ease-in-out;
  180. }
  181.  
  182. div#form-modal.shown {
  183.     display: block;
  184.     opacity: 1;
  185. }
  186.  
  187. div#form-modal .form-modal-backdrop {
  188.     display: flex;
  189.     width: 100%;
  190.     height: 100%;
  191.     background: #000000c2;
  192.     backdrop-filter: blur(2px);
  193.     align-items: center;
  194.     justify-content: center;
  195. }
  196.  
  197. div#form-modal .form-modal-dialog {
  198.     position: relative;
  199.     width: 100%;
  200.     max-width: 350px;
  201.     background: #fff;
  202.     border-radius: 10px;
  203.     padding: 15px 10px;
  204. }
  205.  
  206. div#form-modal .form-modal-dialog .form-modal-title {
  207.     margin: unset;
  208. }
  209.  
  210. button.form-modal-close {
  211.     background: transparent;
  212.     border: unset;
  213.     cursor: pointer;
  214.     position: relative;
  215.     float: right;
  216. }
  217. .form-group {
  218.     position: relative;
  219.     width: 100%;
  220.     padding: 5px 0px;
  221. }
  222. label.form-label {
  223.     display: block;
  224.     width: 100%;
  225.     font-weight: 400;
  226.     color: #434343;
  227.     margin-bottom: 5px;
  228.     font-size: 14px;
  229. }
  230.  
  231. .form-control {
  232.     width: 100%;
  233.     resize: none;
  234.     border-color: #848383;
  235.     border-radius: 2px;
  236.     outline: unset;
  237. }
  238.  
  239. .form-group-action {
  240.     position: relative;
  241.     width: 100%;
  242.     padding: 5px 0px;
  243.     display: flex;
  244.     align-items: center;
  245.     justify-content: center;
  246. }
  247.  
  248. button#btn-new-flashcard {
  249.     display: flex;
  250.     align-items: center;
  251.     justify-content: center;
  252.     background: #0556be;
  253.     color: #fff;
  254.     padding: 5px 25px;
  255.     border: unset;
  256.     border-radius: 3px;
  257.     font-weight: 500;
  258.     cursor: pointer;
  259.     float: right;
  260. }
  261.  
  262. button.btn-form-action {
  263.     background: #0556be;
  264.     color: #fff;
  265.     padding: 5px 25px;
  266.     border: unset;
  267.     border-radius: 3px;
  268.     font-weight: 500;
  269.     cursor: pointer;
  270. }
  271.  
  272. button.btn-form-action:hover, button.btn-form-action:active{
  273.     background: #247df0;
  274. }

Step 3: Creating the App Functionality

Lastly, let's create the JavaScript file for the Flashcard Application. This file is the backbone of the application's functionality, enabling features such as storing and loading flashcard data, opening the flashcard creation form modal, flipping cards to reveal the answer, and other interactive behaviors. By implementing these functionalities, we can create a dynamic and user-friendly flashcard application. Check out the script below for details.

script.js

  1. // Flashcard item element
  2. const flashcard_item = $(`<div class="card">
  3. <div class="card-container">
  4.     <div class="card-front">
  5.         <h4 class="card-front-title dynapuff-font">Question</h4>
  6.         <div class="card-front-text dynapuff-font">Sample only 123</div>
  7.         <div class="card-back-action"><button class="card-action"><span class="material-symbols-outlined">delete</span></button></div>
  8.         </div>
  9.     <div class="card-back">
  10.         <h4 class="card-back-title dynapuff-font">Answer</h4>
  11.         <div class="card-back-text dynapuff-font">Sample only 123</div>
  12.     </div>
  13. </div>
  14. </div>`)
  15.  
  16. // Flashcard Items Container
  17. const flashcardContainer = $(`.flashcards`)
  18. // Flashcard Form Modal
  19. const flashcardModal = $(`#form-modal`)
  20. // Flashcard Form
  21. const FCForm = $(`#flashcard-form`)
  22. // New Flashcard Item Button
  23. const newFCButton = $(`#btn-new-flashcard`)
  24. // Flashcard Modal Close Button
  25. const FCCloseButton = $(`#form-modal .form-modal-close`)
  26. // Stored Flashcard Data
  27. var FCData = localStorage.getItem('fc_data') || '[]';
  28. FCData = JSON.parse(FCData);
  29.  
  30. // New Flashcard Button Click Event Listener
  31. newFCButton.click(function (e) {
  32.     e.preventDefault();
  33.     FCForm[0].reset();
  34.     $('#fc_id').val("")
  35.     flashcardModal.addClass("shown");
  36. })
  37.  
  38. // Flashcard Modal Close Button Click Event Listener
  39. FCCloseButton.click(function (e) {
  40.     e.preventDefault()
  41.     FCForm[0].reset();
  42.     $('#fc_id').val("")
  43.     if (flashcardModal.hasClass("shown"))
  44.         flashcardModal.removeClass("shown");
  45. })
  46.  
  47. // Generate New Flashcard Item ID
  48. function generateNewID() {
  49.     var id = 0;
  50.     if (FCData.length > 0) {
  51.         for (var i = 0; i < FCData.length; i++) {
  52.             if (id < FCData[i].id) {
  53.                 id = FCData[i].id;
  54.             }
  55.         }
  56.     }
  57.     id++;
  58.     return id;
  59. }
  60.  
  61. // New Flashcard submit event
  62. FCForm.submit(function (e) {
  63.     e.preventDefault();
  64.     var id = $('#fc_id').val()
  65.     if (id == "") {
  66.         id = generateNewID();
  67.         FCData.push({ id: id, question: $(`#question`).val(), answer: $(`#answer`).val() });
  68.     } else {
  69.         for (var i = 0; i < FCData.length; i++) {
  70.             if (id == FCData[i].id) {
  71.                 FCData[i] = { id: id, question: $(`#question`).val(), answer: $(`#answer`).val() };
  72.             }
  73.         }
  74.     }
  75.  
  76.     FCForm[0].reset();
  77.     $('#fc_id').val("")
  78.     localStorage.setItem("fc_data", JSON.stringify(FCData));
  79.     load_flashcards();
  80.     if (flashcardModal.hasClass("shown"))
  81.         flashcardModal.removeClass("shown");
  82. })
  83.  
  84. // Load Flashcard Items
  85. function load_flashcards() {
  86.     flashcardContainer.html("")
  87.     for (var i = 0; i < FCData.length; i++) {
  88.         var data = FCData[i];
  89.         var fc_item = flashcard_item.clone(true);
  90.         fc_item.find(`.card-front-text`).text(data.question)
  91.         fc_item.find(`.card-back-text`).text(data.answer)
  92.         fc_item[0].dataset.id = data.id
  93.         flashcardContainer.append(fc_item)
  94.  
  95.         // Flashcard item card flip event to view answer
  96.         fc_item.click(function (e) {
  97.             e.preventDefault()
  98.             var buttonHtml = new RegExp(($(this).find("button.card-action")[0].outerHTML), "i");
  99.  
  100.             if ($.contains($(this).find("button.card-action")[0], e.target) || $(this).find("button.card-action")[0] == e.target)
  101.                 return;
  102.             if ($(this).hasClass("active")) {
  103.                 $(this).removeClass("active")
  104.             } else {
  105.                 $(this).addClass("active")
  106.             }
  107.         })
  108.  
  109.         // Flashcard item card delete button event
  110.         fc_item.find("button.card-action").click(function (e) {
  111.             e.preventDefault()
  112.             var id = $(this).closest(".card")[0].dataset.id
  113.             if (confirm(`Are you sure to delete this Flashcard Item`)) {
  114.                 for (var z = 0; z < FCData.length; z++) {
  115.                     if (id == FCData[z].id) {
  116.                         delete FCData[z];
  117.                         FCData = FCData.filter(elm => elm)
  118.  
  119.                         localStorage.setItem("fc_data", JSON.stringify(FCData));
  120.                         load_flashcards();
  121.                     }
  122.                 }
  123.             }
  124.         })
  125.     }
  126. }
  127.  
  128. $(document).ready(function () {
  129.     // Load flashcards
  130.     load_flashcards();
  131. })

Snapshots

Here are the following snapshots of the Flashcard Application source code that I provided above.

App's Whole Page

Simple Flashcard App with HTML, CSS, and JavaScript

Flashcard's Question Side

Simple Flashcard App with HTML, CSS, and JavaScript

Flashcard's Answer Side

Simple Flashcard App with HTML, CSS, and JavaScript

New Flashcard Item Form Modal

Simple Flashcard App with HTML, CSS, and JavaScript

And that's it! The complete source code for the Simple Flashcard Application created in this tutorial is available as a downloadable zip file. Feel free to download it and customize the code to suit your specific needs or incorporate it into your own projects. This source code serves as a flexible foundation for building a more advanced and personalized flashcard application.

I hope this Flashcard Application Tutorial using HTML, CSS, and JavaScript has provided you with valuable insights and will help you in your future web application projects. Feel free to explore more content on this website, where you'll find additional Tutorials, Free Source Codes, and Articles covering a wide range of programming languages and frameworks.

Happy Coding =)

Add new comment