Creating Engaging Captchas with HTML, CSS, and JavaScript

Faraz

By Faraz -

Explore six innovative Captcha ideas using HTML, CSS, and JavaScript. Enhance web security and user experience with creative user verification techniques.


Creating Engaging Captchas with HTML, CSS, and JavaScript.jpg

Table of Contents

  1. Project Introduction
  2. HTML Code
  3. CSS Code
  4. JavaScript Code
  5. Preview
  6. Conclusion

In this blog post, we will delve into the world of web security and user verification by exploring six innovative Captcha ideas. These Captchas will be created using the trifecta of web development: HTML, CSS, and JavaScript. As we venture through each idea, we'll provide you with detailed steps, code snippets, and explanations to help you implement them effectively.

CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart) is a security feature often used on websites to differentiate between human users and automated bots. While their primary purpose is to protect websites from malicious activities, they also play a crucial role in ensuring a seamless and user-friendly online experience.

Join us on this journey as we introduce you to creative and interactive Captcha designs that not only bolster your website's security but also engage your users in exciting ways. Whether you're a seasoned web developer or just starting, this guide will empower you to enhance your web security arsenal while delighting your audience.

Let's start making engaging Captchas using HTML, CSS, and JavaScript step by step.

Join My Telegram Channel to Download the Project Source Code: Click Here

Prerequisites:

Before starting this tutorial, you should have a basic understanding of HTML, CSS, and JavaScript. Additionally, you will need a code editor such as Visual Studio Code or Sublime Text to write and save your code.

Source Code

Step 1 (HTML Code):

To get started, we will first need to create a basic HTML file. In this file, we will include the main structure for our Captchas.

After creating the files just paste the following codes into your file. Make sure to save your HTML document with a .html extension, so that it can be properly viewed in a web browser.

Here's a breakdown of the code:

1. <!DOCTYPE html>: This declaration defines the document type and version of HTML being used, which is HTML5 in this case.

2. <html lang="en">: This is the opening tag for the HTML document. It specifies that the document's primary language is English.

3. <head>: This section contains metadata and links to external resources used by the webpage but is not visible to the user.

  • <title>: This sets the title of the webpage that appears in the browser tab.
  • <meta charset="UTF-8" />: Specifies the character encoding for the document as UTF-8, which supports a wide range of characters.
  • <meta name="viewport" content="width=device-width" />: Helps in making the webpage responsive to various screen sizes.
  • <link>: Links to external CSS stylesheets and fonts, including Google Fonts.

4. <body>: This is the main content area of the webpage.

5. <h1>: A heading that introduces the page's content.

6. Several <div> elements with the class "captcha-wrapper." Each of these represents a different CAPTCHA challenge:

  • Meme CAPTCHA (meme)
  • Bear Survival CAPTCHA (bear)
  • Tic Tac Toe CAPTCHA (tic-tac-toe)
  • Emoji Selection CAPTCHA (which-emoji)
  • Solo Cups CAPTCHA (solo-cups)
  • Window Cleaning CAPTCHA (window-cleaning)

7. Inside each "captcha-wrapper" div, there are:

  • An instruction describing the challenge.
  • A "well" containing the CAPTCHA challenge elements.
  • Various HTML elements specific to each CAPTCHA type, such as questions, options, and feedback.
  • A "name" indicating the name of the CAPTCHA challenge.

8. Finally, at the bottom of the <body>, there are two <script> tags. These include references to external JavaScript files (script.js) and jQuery library (jquery.min.js) used to provide interactivity and functionality to the CAPTCHA challenges.

This is the basic structure of our Captchas using HTML, and now we can move on to styling it using CSS.

Step 2 (CSS Code):

Once the basic HTML structure of the Captchas is in place, the next step is to add styling to the Captchas using CSS.

Next, we will create our CSS file. In this file, we will use some basic CSS rules to create our Captchas. Let's break down what each part of the code does:

1. Body Styles:

  • background: Sets the background color of the entire page to a light greenish color (#f1fccc).
  • display, flex-wrap, justify-content, and align-items: These properties are used to create a centered layout for the page content. The content is displayed as a flex container, and items inside it are centered both horizontally and vertically.
  • text-align: Sets the text alignment to center.
  • font-family: Specifies the font used for text on the page.
  • font-size: Sets the default font size to 24 pixels.
  • color: Sets the default text color to a dark gray (#454a56).
  • line-height: Defines the line height for text.

2. Header 1 (h1) Styles:

  • width: Sets the width of h1 to 100%.
  • background: Sets the background color of h1 to a dark gray (#454a56).
  • color: Sets the text color of h1 to a light gray (#ededed).
  • padding: Adds padding to h1 to create spacing around the text.

3. Paragraph (p) Styles:

  • margin-bottom: Adds bottom margin to paragraphs for spacing.

4. Button Styles:

  • Styles buttons and elements with the class .button.
  • font: Specifies font properties for buttons.
  • text-transform: Converts text to uppercase.
  • padding: Adds padding inside buttons.
  • border-radius: Rounds the corners of buttons.
  • min-width: Sets a minimum width for buttons.
  • border: Adds a border to buttons.
  • background: Sets the background of buttons to transparent.
  • cursor: Changes the cursor to a pointer when hovering.
  • transition: Adds a smooth transition effect on hover and other state changes.

5. Hidden and Disabled Styles:

  • .hidden: Sets the visibility of elements with this class to hidden.
  • .disabled: Reduces the opacity of elements with this class and disables pointer events.

6. Styles for a "Well" Container:

  • Styles for a container with the class .well, which includes background color, border-radius, padding, and box shadow.
  • Media queries adjust the padding for .well when the viewport width is greater than 600 pixels.

7. Styles for Radio Buttons and Labels:

  • Styles for radio inputs and their labels.
  • Hides the radio inputs with display: none.
  • Styles labels with padding, cursor pointer, and custom radio button indicators.

8. Captcha Wrapper Styles:

  • Styles for a container with the class .captcha-wrapper, which includes background colors.
  • Media queries adjust padding for different screen sizes.

9. Styles for Solo Cups and Animations:

  • Styles for animated cups, including cups, lids, and balls.
  • Keyframe animations for cup movements.

10. Styles for a Tic-Tac-Toe Game Board:

  • Styles for a tic-tac-toe game board, including the grid and game pieces.

11. Styles for "Meme" and "Bear" Sections:

  • Styles specific to sections with the classes .meme and .bear.
  • Uses custom CSS variables (e.g., --color) and conditional styles based on input selection.

12. Styles for Window Cleaning:

  • Styles for a window cleaning simulation, including windows and background images.

13. Styles for Emoji Selection:

  • Styles for selecting emojis, with hover and selection effects.

14. Styles for a Sidebar (Context):

  • Styles for a sidebar (aside) containing context information.

This will give our Captchas an upgraded presentation. Create a CSS file with the name of styles.css and paste the given codes into your CSS file. Remember that you must create a file with the .css extension.

body {
  background: #f1fccc;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  text-align: center;
  font-family: "Nunito", sans-serif;
  font-size: 24px;
  color: #454a56;
  line-height: 1.4;
}

h1 {
  width: 100%;
  background: #454a56;
  color: #ededed;
  padding: 2rem;
}

p {
  margin-bottom: 1.2rem;
}

button, .button {
  font: 700 20px "Nunito", sans-serif;
  text-transform: uppercase;
  padding: 0.7rem 2rem;
  display: inline-block;
  margin: auto;
  border-radius: 10rem;
  min-width: 10rem;
  border: 3px solid;
  color: #607D8B;
  background: transparent;
  cursor: pointer;
  transition: 0.2s ease;
  text-decoration: none;
  position: relative;
  z-index: 5;
}
button:hover, .button:hover {
  color: #454a56;
}
button:active, button:focus, .button:active, .button:focus {
  background: #454a56;
  border-color: #454a56;
  color: #ededed;
}

.hidden {
  visibility: hidden;
}

.disabled {
  opacity: 0.5;
  pointer-events: none;
}

.well {
  background: #fff;
  border-radius: 0.8rem;
  padding: 1.5rem;
  position: relative;
  width: 90%;
  max-width: 40rem;
  margin: 2rem auto 0;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
  border-top: 5px solid var(--color);
}
@media (min-width: 600px) {
  .well {
    padding: 2rem 3rem;
  }
}
.well .feedback {
  position: absolute;
  left: 0;
  top: 95%;
  width: 100%;
}
.well .question {
  font-weight: 700;
  margin-bottom: 1rem;
}

input[type=radio] {
  display: none;
}
input[type=radio] + label {
  display: block;
  text-align: left;
  padding: 0.5rem 0.5rem 0.5rem 2.4rem;
  position: relative;
  cursor: pointer;
}
input[type=radio] + label:before {
  border: 3px solid var(--color);
  width: 1.3rem;
  height: 1.3rem;
  border-radius: 50%;
  left: 0;
  top: 0.7rem;
}
input[type=radio] + label:after {
  width: 1rem;
  height: 1rem;
  top: 1rem;
  left: 0.35rem;
  border-radius: 50%;
  transition: 0.4s ease-in-out;
  background-size: 200% 100%;
  background-image: linear-gradient(to right, transparent 50%, var(--color) 50%);
}
input[type=radio]:checked + label:after {
  background-position: -100% 0;
}

.captcha-wrapper {
  flex: 1 1 100%;
  min-height: 100vh;
  display: flex;
  align-content: flex-start;
  align-items: stretch;
  justify-content: center;
  flex-wrap: wrap;
  overflow: hidden;
  position: relative;
  padding: 1.5rem;
}
@media (max-width: 700px) {
  .captcha-wrapper.meme, .captcha-wrapper.bear {
    padding-bottom: 16rem;
  }
}
.captcha-wrapper:nth-child(2) {
  background: #fcccec;
}
.captcha-wrapper:nth-child(3) {
  background: #fcf3cc;
}
.captcha-wrapper:nth-child(4) {
  background: #f1fccc;
}
.captcha-wrapper:nth-child(5) {
  background: #fceccc;
}
.captcha-wrapper:nth-child(6) {
  background: #ccdbfc;
}
.captcha-wrapper:nth-child(7) {
  background: #e0ccfc;
}
@media (min-width: 600px) {
  .captcha-wrapper {
    padding: 5rem;
    min-height: 100vh;
  }
}
@media (min-width: 1240px) {
  .captcha-wrapper {
    flex: 1 1 calc(100% / 2);
    padding: 4rem;
  }
}
.captcha-wrapper .feedback {
  width: 100%;
  display: none;
  margin: 3rem auto 0;
  font-size: 90%;
  font-style: italic;
}
.captcha-wrapper .instruction {
  width: 100%;
  margin: 0 auto 0.5rem;
}
.captcha-wrapper .name {
  width: 80%;
  font-weight: 700;
  font-size: 20px;
  position: absolute;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  bottom: 15px;
  right: 15px;
  text-align: right;
}

* {
  box-sizing: border-box;
}
*:before, *:after {
  content: "";
  position: absolute;
}

.solo-cups .cup-wrapper {
  position: relative;
  flex: 1 1 30%;
  min-height: 25vh;
  display: flex;
  justify-content: center;
  transition: 0.3s ease;
}
.solo-cups__group {
  display: flex;
  width: 100%;
  margin-top: 0.8rem;
}
.solo-cups .cup {
  bottom: 0;
  border-top: 90px solid #f44336;
  border-left: 15px solid transparent;
  border-right: 15px solid transparent;
  height: 3px;
  position: absolute;
  width: 80px;
  cursor: pointer;
  transform: rotate(180deg);
  transition: 0.2s cubic-bezier(0.42, 0.5, 0.58, 1);
}
.solo-cups .cup:before {
  box-shadow: 0 -10px 0 0px rgba(39, 39, 39, 0.1), 0px -20px 0 0px rgba(39, 39, 39, 0.1);
  border-radius: 3px;
  overflow: hidden;
  background: rgba(39, 39, 39, 0.1);
  width: 120%;
  left: -5px;
  height: 4px;
  top: -40px;
}
.solo-cups .cup .lid {
  position: absolute;
  width: 90px;
  height: 8px;
  border-radius: 20px;
  background: #efefef;
  bottom: 86px;
  left: -20px;
}
.solo-cups .cup .lid:after {
  background: #efefef;
  width: 48px;
  height: 5px;
  left: 50%;
  margin-left: -24px;
  top: 94px;
  border-radius: 0 0 3px 3px;
}
.solo-cups .cup-2 .cup {
  transform: translate(30%, -70%) rotate(200deg);
}
.solo-cups .ball {
  width: 2.5rem;
  height: 2.5rem;
  background: #f9f9f9;
  box-shadow: inset 0 -3px 0 0 #c6c5c5;
  border-radius: 50%;
  position: absolute;
  bottom: -3px;
  left: 50%;
  transform: translateX(-50%);
}
.solo-cups.active .cup-2 {
  animation: move-cup-2 2s 0.3s forwards;
}
.solo-cups.active .cup-2 .cup {
  animation: start-cups 0.2s forwards;
}
.solo-cups.active .cup-1 {
  animation: move-cup-1 2s 0.3s forwards;
}
.solo-cups.active .cup-3 {
  animation: move-cup-3 2s 0.3s forwards;
}

@keyframes start-cups {
  100% {
    transform: rotate(180deg);
  }
}
@keyframes move-cup-1 {
  20% {
    transform: translateX(100%);
  }
  40% {
    transform: translateX(200%);
  }
  60% {
    transform: translateX(200%);
  }
  80% {
    transform: translateX(100%);
  }
  100% {
    transform: translateX(0);
  }
}
@keyframes move-cup-2 {
  20% {
    transform: translateX(-100%);
  }
  40% {
    transform: translateX(-100%);
  }
  60% {
    transform: translateX(0);
  }
  80% {
    transform: translateX(100%);
  }
  100% {
    transform: translateX(100%);
  }
}
@keyframes move-cup-3 {
  20% {
    transform: translateX(0);
  }
  40% {
    transform: translateX(-100%);
  }
  60% {
    transform: translateX(-200%);
  }
  80% {
    transform: translateX(-200%);
  }
  100% {
    transform: translateX(-100%);
  }
}
.tic-tac-toe .board {
  display: grid;
  grid: repeat(3, 80px)/repeat(3, 80px);
  position: relative;
  margin: 3rem auto 0;
}
.tic-tac-toe .board:before {
  width: 6px;
  height: 100%;
  background: #333;
  border-radius: 50px;
  left: 77px;
  box-shadow: 80px 0 0 0px #333;
}
.tic-tac-toe .board:after {
  width: 100%;
  height: 6px;
  left: 0;
  top: 77px;
  background: #333;
  border-radius: 50px;
  box-shadow: 0 80px 0 0px #333;
}
.tic-tac-toe .circle {
  width: 55%;
  height: 55%;
  border-radius: 50%;
  border: 4px solid #222;
  margin: auto;
}
.tic-tac-toe .cross {
  width: 4px;
  height: 60%;
  border-radius: 30px;
  background: #222;
  margin: auto;
  position: relative;
  transform: rotate(45deg);
}
.tic-tac-toe .cross:before {
  width: 36px;
  height: 3px;
  top: calc(50% - 1.5px);
  left: -16px;
  border-radius: inherit;
  background: inherit;
}
.tic-tac-toe .free {
  cursor: pointer;
}
.tic-tac-toe .winning-line {
  width: 4px;
  height: 0;
  transition: 0.2s ease 0.2s;
  background: #60b169;
  border-radius: 50px;
  left: calc(50% - 2px);
  top: 5%;
  position: absolute;
}

.meme {
  --color: #b16096;
}
.meme #option-1:checked ~ .feedback.negative {
  display: block;
}
.meme #option-1:checked ~ .feedback.positive {
  display: none;
}
.meme #option-2:checked ~ .feedback.positive {
  display: block;
}
.meme #option-2:checked ~ .feedback.negative {
  display: none;
}

.bear {
  --color: #da9f23;
}
.bear #option-11:checked ~ .negative-1 {
  display: block;
}
.bear #option-11:checked ~ .positive,
.bear #option-11:checked .negative-2 {
  display: none;
}
.bear #option-12:checked ~ .negative-2 {
  display: block;
}
.bear #option-12:checked ~ .negative-1,
.bear #option-12:checked .positive {
  display: none;
}
.bear #option-13:checked ~ .positive {
  display: block;
}
.bear #option-13:checked ~ .negative-1,
.bear #option-13:checked .negative-2 {
  display: none;
}

.window-cleaning .windows {
  height: 40vh;
  width: 45%;
  box-shadow: 0px 4px 0 0 #eee;
  position: relative;
  background: #fff;
  padding: 15px 15px 11px;
  margin: 2rem auto 1rem;
}
.window-cleaning .windows__wrapper {
  display: grid;
  background: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/567707/skyline.png) top center/cover;
  width: 100%;
  height: 100%;
  grid: repeat(3, 1fr)/repeat(3, 1fr);
  position: relative;
  overflow: hidden;
}
.window-cleaning .windows__wrapper:before, .window-cleaning .windows__wrapper:after {
  width: 120%;
  height: 25px;
  background: rgba(255, 255, 255, 0.3);
  bottom: 35%;
  transform: rotate(-25deg);
  left: -10%;
  z-index: 1;
}
.window-cleaning .windows__wrapper:after {
  height: 15px;
  bottom: 22%;
}
.window-cleaning .windows__sill {
  width: 120%;
  left: -10%;
  background: #fff;
  height: 16px;
  top: calc(100% + 4px);
  position: absolute;
}
.window-cleaning .windows .window {
  cursor: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/567707/soap.png"), auto;
  background: rgba(0, 0, 0, 0.2);
  position: relative;
  z-index: 2;
}
.window-cleaning .windows .window.clean {
  background: transparent;
}

.which-emoji img {
  width: 100%;
  max-width: 260px;
  border: 6px solid #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
.which-emoji .feedback {
  font-style: normal;
}
.which-emoji .image {
  grid-column: span 2;
}
.which-emoji__main {
  display: grid;
  grid-template-columns: max-content min-content;
  grid-gap: 0.7rem;
}
.which-emoji .emoji {
  padding: 0.6rem;
  font-size: 1.2rem;
  background: rgba(255, 255, 255, 0.3);
  border-radius: 6px;
  margin: 8px;
  border: 2px dashed;
  flex: 1;
  cursor: pointer;
}
.which-emoji .emoji.chosen {
  background: #e99f2a;
  border: 2px solid #e99f2a;
}
.which-emoji .emoji-choices {
  display: flex;
}

aside.context {
  text-align: center;
  color: #333;
  line-height: 1.7;
}
aside.context a {
  text-decoration: none;
  color: #333;
  padding: 3px 0;
  border-bottom: 1px dashed;
}
aside.context a:hover {
  border-bottom: 1px solid;
}
aside.context .explanation {
  max-width: 700px;
  margin: 6em auto 0;
} 

Step 3 (JavaScript Code):

Finally, we need to create a function in JavaScript. Let's break down each section:

1. $(".js-verify-cups").on("click", function () {...}): This code attaches a click event handler to elements with the class "js-verify-cups." When an element with this class is clicked, it adds the "active" class to elements with the class "solo-cups" and hides the clicked element.

2. $(document).on("click", ".solo-cups.active .cup-wrapper", function () {...}): This code attaches a click event handler to elements with the class "cup-wrapper" that are descendants of elements with both "solo-cups" and "active" classes. When one of these elements is clicked, it performs several actions like transforming a nested element with the class "cup," adjusting pointer events, and showing or hiding feedback elements based on the presence of the "cup-2" class.

3. $(".js-try-again").on("click", function () {...}): This code attaches a click event handler to elements with the class "js-try-again." When an element with this class is clicked, it resets various styles and classes to their initial state, allowing the user to try the interaction again.

4. $(".tic-tac-toe .free").on("click", function () {...}): This code attaches a click event handler to elements with the class "free" that are descendants of elements with the class "tic-tac-toe." When one of these elements is clicked, it adds the "cross" class, disables pointer events on a ".board" element, and shows or hides feedback elements based on the presence of the "free-2" class.

5. $('.tic-tac-toe .js-try-again').on('click', function() {...}): This code attaches a click event handler to elements with the class "js-try-again" that are descendants of elements with the class "tic-tac-toe." When an element with this class is clicked, it resets the game state to its initial condition.

6. $(".window").mouseover(function () {...}): This code attaches a mouseover event handler to elements with the class "window." When a mouse hovers over such an element, it adds the "clean" class to it. If there are more than 8 elements with the "clean" class, it shows positive feedback.

7. $('.windows__wrapper').mouseenter(function(){...}): This code attaches a mouseenter event handler to elements with the class "windows__wrapper." When the mouse enters this element, it waits for 4 seconds and then checks if there are fewer than 9 elements with the "clean" class. If so, it shows negative feedback and disables pointer events on ".windows__wrapper."

8. $('.window-cleaning .js-try-again').on('click', function(){...}): This code attaches a click event handler to elements with the class "js-try-again" that are descendants of elements with the class "window-cleaning." When an element with this class is clicked, it resets the cleaning state, hides feedback elements, and re-enables pointer events on ".windows__wrapper."

9. $(document).on("click", ".emoji", function () {...}): This code attaches a click event handler to elements with the class "emoji." When an element with this class is clicked, it toggles the "chosen" class on and off.

10. $('.js-submit-emoji').on('click', function(){...}): This code attaches a click event handler to elements with the class "js-submit-emoji." When an element with this class is clicked and two emoji elements with the "chosen" class are selected, it checks if specific emojis ("🐢" and "πŸ—") are among the chosen ones and displays corresponding feedback. It also disables further interaction until the page is reset.

11. $('.which-emoji .js-try-again').on('click', function(){...}): This code attaches a click event handler to elements with the class "js-try-again" that are descendants of elements with the class "which-emoji." When an element with this class is clicked, it resets the emoji selection, hides feedback, and re-enables emoji selection and submission.

Create a JavaScript file with the name script.js and paste the given codes into your JavaScript file and make sure it's linked properly to your HTML document so that the scripts are executed on the page. Remember, you’ve to create a file with .js extension.

$(".js-verify-cups").on("click", function () {
	$(".solo-cups").addClass("active");
	$(this).addClass('hidden');
});

$(document).on("click", ".solo-cups.active .cup-wrapper", function () {
	$(this).find('.cup').css('transform', 'translate(30%,-70%) rotate(200deg)');
	$('.cup-wrapper').css('pointer-events', 'none');
	if ($(this).hasClass("cup-2")) {
		$(this).find('.cup').css('animation','none');
		$(".solo-cups .feedback.positive").show();
		$(".solo-cups .feedback.negative").hide();
	} else {
		
		$(".solo-cups .feedback.positive").hide();
		$(".solo-cups .feedback.negative").show();
	}
});

$(".js-try-again").on("click", function () {
	$('.cup').attr('style', '')
	$('.solo-cups').removeClass('active');
	$('.cup-wrapper').css('pointer-events', 'auto');
	$('.js-verify-cups').removeClass('hidden');
	$(".solo-cups .feedback").hide();
});

$(".tic-tac-toe .free").on("click", function () {
	$(this).addClass("cross");
	$(".board").css('pointer-events','none');
	if ($(this).hasClass("free-2")) {
		$(".tic-tac-toe .feedback.negative").hide();
		$(".tic-tac-toe .feedback.positive").show();
		$(".winning-line").css("height", "92%");
	} else {
		$(".tic-tac-toe .feedback.negative").show();
		$(".tic-tac-toe .feedback.positive").hide();
	}
});

$('.tic-tac-toe .js-try-again').on('click', function() {
	$(".board").css('pointer-events','auto');
	$('.free').removeClass('cross');
	$(".tic-tac-toe .feedback").hide();
});

$(".window").mouseover(function () {
	$(this).addClass("clean");
	if ($(".window.clean").length > 8) {
		$(".window-cleaning .feedback.positive").show();
		$(".window-cleaning .feedback.negative").hide();
	}
});

$('.windows__wrapper').mouseenter(function(){
	setTimeout(function(){
		if ($(".window.clean").length < 9) {
			$(".window-cleaning .feedback.positive").hide();
			$(".window-cleaning .feedback.negative").show();
			$('.windows__wrapper').css('pointer-events', 'none');
		}
	},4000);
});

$('.window-cleaning .js-try-again').on('click', function(){
	$('.window:not(:last-child)').removeClass('clean');
	$('.window-cleaning .feedback').hide();
	$('.windows__wrapper').css('pointer-events', 'auto');
});

$(document).on("click", ".emoji", function () {
	$(this).toggleClass("chosen");
});

$('.js-submit-emoji').on('click', function(){
	if ($(".emoji.chosen").length == 2) {
		$(this).addClass('disabled');
		$('.emoji').css('pointer-events', 'none');
		var emojis = [];
		$(".emoji.chosen").each(function () {
			emojis.push($(this).text());
			
		});
		if (emojis.indexOf("🐢") > -1 && emojis.indexOf("πŸ—") > -1) {
			$(".which-emoji .feedback.positive").show();
			$(".which-emoji .feedback.negative").hide();
		} else {
			$(".which-emoji .feedback.negative").show();
			$(".which-emoji .feedback.positive").hide();
		}
	} else {
		$('.which-emoji .instruction').append('<strong> 2 emojis!!</strong>')
	}
});

$('.which-emoji .js-try-again').on('click', function(){
	$('.which-emoji .feedback').hide();
	$('.emoji.chosen').removeClass('chosen');
	$('.emoji').css('pointer-events', 'auto');
	$('.js-submit-emoji').removeClass('disabled');
});

Final Output:

Creating Engaging Captchas with HTML, CSS, and JavaScript.gif

Conclusion:

In the ever-evolving landscape of web security, Captchas stand as stalwart guardians, defending websites against the relentless tide of automated bots and cyber threats. In this blog post, we've embarked on a journey through six captivating Captcha ideas, each crafted with HTML, CSS, and JavaScript.

These innovative Captchas go beyond mere security measures; they engage users, creating a dynamic and memorable interaction. From image recognition to mathematical challenges and geolocation verification, we've explored a diverse range of user verification techniques that can elevate your website's defenses.

As you consider implementing these creative Captchas, remember the delicate balance between security and user experience. While the primary goal is to safeguard your digital realm, it's equally important to ensure that genuine users navigate your site with ease.

Whether you're a web development enthusiast seeking to fortify your project or a security-conscious site owner looking to enhance your defenses, the tools and knowledge provided here empower you to do just that.

In the end, Captchas are not just lines of code; they are a testament to the ongoing battle for a secure, accessible, and user-friendly online world. We hope this guide has equipped you with the insights and inspiration needed to take your web security to new heights while captivating your audience. Thank you for joining us on this journey, and may your digital endeavors be both secure and engaging.

Creator: Olivia Ng

That’s a wrap!

I hope you enjoyed this post. Now, with these examples, you can create your own amazing page.

Did you like it? Let me know in the comments below πŸ”₯ and you can support me by buying me a coffee.

And don’t forget to sign up to our email newsletter so you can get useful content like this sent right to your inbox!

Thanks!
Faraz 😊

End of the article

Subscribe to my Newsletter

Get the latest posts delivered right to your inbox


Latest Post