How to Create Typing Speed Test
with HTML,CSS and JavaScript
In the event that you're as of now acquainted with JavaScript and have fabricated projects in it, you could undoubtedly grasp the codes of this game yet on the off chance that you are too novice at this and didn't construct a task before then you might experience issues to understanding the codes and ideas of this Composing Velocity Test Game.
To make this Composing Velocity Test Game in JavaScript. To begin with, you want to make four Records: HTML, CSS and JavaScript Documents. In the wake of making these records simply glue the accompanying codes into your document. You can likewise download the source code documents of this Composing Pace Test Game from the given download button.
Video Tutorial of Typing Speed Tester
Typing Speed Test [Source Codes]
To Create Typing Speed Test with HTML,CSS and JavaScript, follow the given steps line by line:
Create a folder. You can name this folder whatever you want, and inside this folder, create the mentioned files.
Create an index.html file. The file name must be index and its extension .html
Create a style.css file. The file name must be style and its extension .css
Create a script.js file. The file name must be style and its extension .js
Create a paragraphs.js file. The file name must be style and its extension .js
Once you create these files, paste the given codes into the specified files. If you don’t want to do these then scroll down and download the source code by clicking download button.
First, paste the following codes into your index.html file
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="utf-8">
- <title>Typing Speed Testing</title>
- <link rel="stylesheet" href="style.css">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- </head>
- <body>
- <div class="wrapper">
- <input type="text" class="input-field">
- <div class="content-box">
- <div class="typing-text">
- <p></p>
- </div>
- <div class="content">
- <ul class="result-details">
- <li class="time">
- <p>Time Left:</p>
- <span><b>60</b>s</span>
- </li>
- <li class="mistake">
- <p>Mistakes:</p>
- <span>0</span>
- </li>
- <li class="wpm">
- <p>WPM:</p>
- <span>0</span>
- </li>
- <li class="cpm">
- <p>CPM:</p>
- <span>0</span>
- </li>
- </ul>
- <button>Try Again</button>
- </div>
- </div>
- </div>
- <script src="js/paragraphs.js"></script>
- <script src="js/script.js"></script>
- </body>
- </html>
Now paste the following codes into your style.css file
- *{
- margin: 0;
- padding: 0;
- box-sizing: border-box;
- font-family: 'Open Sans', 'Open Sans Regular', sans-serif;
- }
- body{
- display: flex;
- padding: 0 10px;
- align-items: center;
- justify-content: center;
- min-height: 100vh;
- background: #282A35;
- }
- ::selection{
- color: #fff;
- background: #f12020;
- }
- .wrapper{
- width: 800px;
- padding: 37px;
- background: #d9d9d9;
- border-radius: 8px;
- }
- .wrapper .input-field{
- opacity: 0;
- z-index: -999;
- position: absolute;
- }
- .wrapper .content-box{
- padding: 14px 19px 0;
- border-radius: 8px;
- border: 1px solid #606060;
- }
- .content-box .typing-text{
- overflow: hidden;
- max-height: 260px;
- }
- .typing-text::-webkit-scrollbar{
- width: 0;
- }
- .typing-text p{
- font-size: 24px;
- text-align: justify;
- letter-spacing: 1px;
- word-break: break-all;
- }
- .typing-text p span{
- position: relative;
- }
- .typing-text p span.correct{
- color: #56964f;
- }
- .typing-text p span.incorrect{
- color: #f12020;
- outline: 1px solid #fff;
- background: #ffc0cb;
- border-radius: 4px;
- }
- .typing-text p span.active{
- color: green;
- }
- .typing-text p span.active::before{
- position: absolute;
- content: "";
- height: 2px;
- width: 100%;
- bottom: 0;
- left: 0;
- opacity: 0;
- border-radius: 5px;
- background: #17A2B8;
- animation: blink 1s ease-in-out infinite;
- }
- @keyframes blink{
- 50%{
- opacity: 1;
- }
- }
- .content-box .content{
- margin-top: 17px;
- display: flex;
- padding: 12px 0;
- flex-wrap: wrap;
- align-items: center;
- justify-content: space-between;
- border-top: 1px solid #bfbfbf;
- }
- .content button{
- outline: none;
- border: none;
- width: 105px;
- color: #fff;
- padding: 8px 0;
- font-size: 16px;
- cursor: pointer;
- border-radius: 5px;
- background: #bfbfbf;
- transition: transform 0.3s ease;
- }
- .content button:active{
- transform: scale(0.97);
- }
- .content .result-details{
- display: flex;
- flex-wrap: wrap;
- align-items: center;
- width: calc(100% - 140px);
- justify-content: space-between;
- }
- .result-details li{
- display: flex;
- height: 20px;
- list-style: none;
- position: relative;
- align-items: center;
- }
- .result-details li:not(:first-child){
- padding-left: 22px;
- border-left: 1px solid #bfbfbf;
- }
- .result-details li p{
- font-size: 19px;
- }
- .result-details li span{
- display: block;
- font-size: 20px;
- margin-left: 10px;
- }
- li span b{
- font-weight: 500;
- }
- li:not(:first-child) span{
- font-weight: 500;
- }
- @media (max-width: 745px) {
- .wrapper{
- padding: 20px;
- }
- .content-box .content{
- padding: 20px 0;
- }
- .content-box .typing-text{
- max-height: 100%;
- }
- .typing-text p{
- font-size: 19px;
- text-align: left;
- }
- .content button{
- width: 100%;
- font-size: 15px;
- padding: 10px 0;
- margin-top: 20px;
- }
- .content .result-details{
- width: 100%;
- }
- .result-details li:not(:first-child){
- border-left: 0;
- padding: 0;
- }
- .result-details li p,
- .result-details li span{
- font-size: 17px;
- }
- }
- @media (max-width: 518px) {
- .wrapper .content-box{
- padding: 10px 15px 0;
- }
- .typing-text p{
- font-size: 18px;
- }
- .result-details li{
- margin-bottom: 10px;
- }
- .content button{
- margin-top: 10px;
- }
- }
Now paste the following codes into your script.js file
- const typingText = document.querySelector(".typing-text p"),
- inpField = document.querySelector(".wrapper .input-field"),
- tryAgainBtn = document.querySelector(".content button"),
- timeTag = document.querySelector(".time span b"),
- mistakeTag = document.querySelector(".mistake span"),
- wpmTag = document.querySelector(".wpm span"),
- cpmTag = document.querySelector(".cpm span");
-
- let timer,
- maxTime = 60,
- timeLeft = maxTime,
- charIndex = mistakes = isTyping = 0;
-
- function loadParagraph() {
- const ranIndex = Math.floor(Math.random() * paragraphs.length);
- typingText.innerHTML = "";
- paragraphs[ranIndex].split("").forEach(char => {
- let span = `<span>${char}</span>`
- typingText.innerHTML += span;
- });
- typingText.querySelectorAll("span")[0].classList.add("active");
- document.addEventListener("keydown", () => inpField.focus());
- typingText.addEventListener("click", () => inpField.focus());
- }
-
- function initTyping() {
- let characters = typingText.querySelectorAll("span");
- let typedChar = inpField.value.split("")[charIndex];
- if(charIndex < characters.length - 1 && timeLeft > 0) {
- if(!isTyping) {
- timer = setInterval(initTimer, 1000);
- isTyping = true;
- }
- if(typedChar == null) {
- if(charIndex > 0) {
- charIndex--;
- if(characters[charIndex].classList.contains("incorrect")) {
- mistakes--;
- }
- characters[charIndex].classList.remove("correct", "incorrect");
- }
- } else {
- if(characters[charIndex].innerText == typedChar) {
- characters[charIndex].classList.add("correct");
- } else {
- mistakes++;
- characters[charIndex].classList.add("incorrect");
- }
- charIndex++;
- }
- characters.forEach(span => span.classList.remove("active"));
- characters[charIndex].classList.add("active");
-
- let wpm = Math.round(((charIndex - mistakes) / 5) / (maxTime - timeLeft) * 60);
- wpm = wpm < 0 || !wpm || wpm === Infinity ? 0 : wpm;
-
- wpmTag.innerText = wpm;
- mistakeTag.innerText = mistakes;
- cpmTag.innerText = charIndex - mistakes;
- } else {
- clearInterval(timer);
- inpField.value = "";
- }
- }
-
- function initTimer() {
- if(timeLeft > 0) {
- timeLeft--;
- timeTag.innerText = timeLeft;
- let wpm = Math.round(((charIndex - mistakes) / 5) / (maxTime - timeLeft) * 60);
- wpmTag.innerText = wpm;
- } else {
- clearInterval(timer);
- }
- }
-
- function resetGame() {
- loadParagraph();
- clearInterval(timer);
- timeLeft = maxTime;
- charIndex = mistakes = isTyping = 0;
- inpField.value = "";
- timeTag.innerText = timeLeft;
- wpmTag.innerText = 0;
- mistakeTag.innerText = 0;
- cpmTag.innerText = 0;
- }
-
- loadParagraph();
- inpField.addEventListener("input", initTyping);
- tryAgainBtn.addEventListener("click", resetGame);
Now paste the following codes into your paragraphs.js file
- const paragraphs = [
- "The Lost Key:Searching frantically, Sarah found the old key under the wilting flower pot. Memories flooded as it unlocked a dusty chest, revealing letters from her late grandmother, imparting wisdom and love.",
- "Moonlit Serenade:In a quiet town, a mysterious musician played haunting melodies under the moon. His music carried an inexplicable sadness, touching the hearts of all who heard, leaving them with a sense of longing.",
- "The Puzzle Piece:Sam found a lone puzzle piece on a park bench. Curiosity led him to complete the puzzle, revealing an image of his childhood home. It rekindled forgotten memories, guiding him back to where he belonged.",
- "Echoes of Laughter:Abandoned amusement parks hold echoes of laughter. Sarah stumbled upon one, reliving its lively past through faded rides and deserted paths. She felt the joy of forgotten days, whispering among the rustling leaves.",
- "The Unseen Artist:Graffiti paintings mysteriously appeared overnight, captivating the town. No one knew the artist's identity, but their vibrant creations transformed mundane walls into galleries, sparking conversations and igniting imaginations.",
- "The Shadow's Tale:A lone figure cast elongated shadows on the wall. Each night, it danced to an invisible melody, leaving behind a story of sorrow and longing—a silent performance captivating all who dared to watch.",
- "The Time Capsule:Unearthing a forgotten time capsule, Emma discovered letters and trinkets capturing a bygone era. As she explored its contents, she felt a connection to the past, understanding the dreams and aspirations of those before her.",
- "The Mirror's Secret:Behind an antique mirror, a hidden passage awaited discovery. Lucy stepped through, finding herself in a magical garden untouched by time. She wandered, encountering mystical creatures, and returned forever changed.",
- "Whispers in the Attic:Exploring the attic, Jake stumbled upon an old journal. Its pages revealed secrets of a previous owner, painting a vivid picture of their life. The whispers of the past echoed, connecting Jake to a forgotten history.",
- "The Melancholic Rain:Rain poured relentlessly, a melancholic symphony. Amidst the downpour, two strangers found shelter. They shared stories, forming an unexpected bond, finding solace in the midst of nature's lament."
- ];
If you face any difficulties while creating yourTyping Speed Tester or your code is not working as expected, you can download the source code files by clicking download button.