DEV Community

Cover image for Creating an Advanced QR Code Generator Using HTML, CSS, and JavaScript
Hanzla Baig
Hanzla Baig

Posted on

Creating an Advanced QR Code Generator Using HTML, CSS, and JavaScript

Title: Creating an Advanced QR Code Generator Using HTML, CSS, and JavaScript

Introduction

In today's digital age, QR codes have become a staple for quickly sharing information, links, and more. Whether you're at a restaurant scanning a menu, at an event accessing event details, or simply sharing your contact info, QR codes are everywhere. In this post, we'll walk through the creation of an advanced QR code generator using HTML, CSS, and JavaScript. This generator not only creates customizable QR codes but also includes a sleek, responsive design and interactive features to enhance user experience.

What You'll Learn

  1. HTML/CSS/JavaScript Integration: How to structure a web page using HTML, style it with CSS, and add functionality with JavaScript.
  2. QRious Library: Utilize this powerful JavaScript library to generate QR codes.
  3. User Interactivity: Implement various interactive features, such as dark mode, border radius customization, and dynamic font size adjustments.
  4. Modern UI/UX Design: Learn how to create a visually appealing and responsive user interface.

The Code Breakdown

Below is the complete code for our QR Code Generator. I'll walk you through each section, explaining how everything works together to produce the final product.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Advanced QR Code Generator</title>
    <style>
        body {
            font-family: 'Arial', sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            background: linear-gradient(135deg, #16a085, #f4d03f);
            margin: 0;
            overflow: hidden;
            transition: background 0.3s ease-in-out;
        }

        .qr-generator {
            background: #fff;
            border-radius: 20px;
            padding: 30px;
            box-shadow: 0 15px 30px rgba(0, 0, 0, 0.2);
            text-align: center;
            max-width: 500px;
            width: 100%;
            transition: transform 0.3s ease-in-out;
            animation: slideIn 0.5s ease-in-out;
        }

        .qr-generator:hover {
            transform: scale(1.05);
        }

        .qr-generator h1 {
            margin-bottom: 20px;
            font-size: 28px;
            color: #2c3e50;
        }

        .input-group {
            margin-bottom: 20px;
        }

        .input-group input,
        .input-group select,
        .input-group textarea {
            width: 100%;
            padding: 12px;
            border: 1px solid #ccc;
            border-radius: 8px;
            font-size: 16px;
            outline: none;
            transition: border 0.3s;
        }

        .input-group input:focus,
        .input-group select:focus,
        .input-group textarea:focus {
            border-color: #2980b9;
        }

        .input-group label {
            display: block;
            text-align: left;
            margin-bottom: 5px;
            font-weight: bold;
            color: #34495e;
        }

        #generate-btn {
            padding: 15px 30px;
            background-color: #2980b9;
            color: #fff;
            border: none;
            border-radius: 8px;
            font-size: 18px;
            cursor: pointer;
            transition: background-color 0.3s, transform 0.2s;
            margin-top: 20px;
        }

        #generate-btn:hover {
            background-color: #3498db;
            transform: translateY(-3px);
        }

        #qr-code {
            margin-top: 30px;
            display: flex;
            justify-content: center;
            flex-direction: column;
            align-items: center;
        }

        #qr-code canvas {
            max-width: 100%;
            animation: fadeIn 1s ease-in-out;
        }

        #download-btn {
            margin-top: 20px;
            padding: 15px 30px;
            background-color: #27ae60;
            color: #fff;
            border: none;
            border-radius: 8px;
            font-size: 18px;
            cursor: pointer;
            display: none;
            transition: background-color 0.3s, transform 0.2s;
        }

        #download-btn:hover {
            background-color: #2ecc71;
            transform: translateY(-3px);
        }

        #qr-info {
            margin-top: 20px;
            padding: 10px 20px;
            background: #ecf0f1;
            border-radius: 10px;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
            display: none;
            text-align: left;
        }

        @keyframes fadeIn {
            from {
                opacity: 0;
                transform: translateY(-20px);
            }
            to {
                opacity: 1;
                transform: translateY(0);
            }
        }

        @keyframes slideIn {
            from {
                transform: translateY(-50px);
                opacity: 0;
            }
            to {
                transform: translateY(0);
                opacity: 1;
            }
        }

        /* Custom Switch */
        .custom-switch {
            position: relative;
            display: inline-block;
            width: 60px;
            height: 34px;
        }

        .custom-switch input {
            opacity: 0;
            width: 0;
            height: 0;
        }

        .slider {
            position: absolute;
            cursor: pointer;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: #ccc;
            transition: 0.4s;
            border-radius: 34px;
        }

        .slider:before {
            position: absolute;
            content: "";
            height: 26px;
            width: 26px;
            left: 4px;
            bottom: 4px;
            background-color: white;
            transition: 0.4s;
            border-radius: 50%;
        }

        input:checked + .slider {
            background-color: #27ae60;
        }

        input:checked + .slider:before {
            transform: translateX(26px);
        }

        .switch-label {
            margin-left: 10px;
            color: #34495e;
            font-weight: bold;
            user-select: none;
        }

        /* Font Size Slider */
        .slider-container {
            text-align: left;
            margin-top: 10px;
        }

        .slider-container input[type="range"] {
            width: 100%;
        }

        .slider-container label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
            color: #34495e;
        }

        /* QR Code Border Radius */
        .border-radius-container {
            text-align: left;
            margin-top: 10px;
        }

        .border-radius-container input[type="range"] {
            width: 100%;
        }

        .border-radius-container label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
            color: #34495e;
        }
    </style>
</head>
<body>
    <div class="qr-generator">
        <h1>Advanced QR Code Generator</h1>
        <div class="input-group">
            <label for="text-input">Enter Text or URL:</label>
            <textarea id="text-input" placeholder="Enter text or URL" rows="3"></textarea>
        </div>
        <div class="input-group">
            <label for="size-input">Size (px):</label>
            <input type="number" id="size-input" value="300" min="100" max="500">
        </div>
        <div class="input-group">
            <label for="bg-color-input">Background Color:</label>
            <input type="color" id="bg-color-input" value="#ffffff">
        </div>
        <div class="input-group">
            <label for="fg-color-input">Foreground Color:</label>
            <input type="color" id="fg-color-input" value="#000000">
        </div>
        <div class="input-group">
            <label for="error-correction">Error Correction Level:</label>
            <select id="error-correction">
                <option value="L">Low (L)</option>
                <option value="M">Medium (M)</option>
                <option value="Q">Quartile (Q)</option>
                <option value="H">High (H)</option>
            </select>
        </div>
        <div class="input-group">
            <label for="font-size-slider" class="slider-label">Font Size (for text embedded in QR):</label>
            <div class="slider-container">
                <input type="range" id="font-size-slider" min="8" max="24" value="16">
            </div>
        </div>
        <div class="input-group">
            <label for="border-radius-slider" class="slider-label">QR Code Border Radius:</label>
            <div class="border-radius-container">
                <input type="range

" id="border-radius-slider" min="0" max="50" value="0">
            </div>
        </div>
        <div class="input-group">
            <label class="switch-label">Dark Mode:</label>
            <label class="custom-switch">
                <input type="checkbox" id="dark-mode-toggle">
                <span class="slider"></span>
            </label>
        </div>
        <button id="generate-btn">Generate QR Code</button>
        <div id="qr-code">
            <canvas id="qr-canvas"></canvas>
            <button id="download-btn">Download QR Code</button>
            <div id="qr-info"></div>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/qrious/dist/qrious.min.js"></script>
    <script>
        const qr = new QRious({
            element: document.getElementById('qr-canvas'),
            size: 300,
            value: '',
            background: '#ffffff',
            foreground: '#000000',
            level: 'L'
        });

        document.getElementById('generate-btn').addEventListener('click', () => {
            const text = document.getElementById('text-input').value;
            const size = parseInt(document.getElementById('size-input').value);
            const bgColor = document.getElementById('bg-color-input').value;
            const fgColor = document.getElementById('fg-color-input').value;
            const errorCorrection = document.getElementById('error-correction').value;
            const fontSize = document.getElementById('font-size-slider').value;
            const borderRadius = document.getElementById('border-radius-slider').value;

            if (text.trim() === '') {
                alert('Please enter text or a URL');
                return;
            }

            qr.set({
                value: text,
                size: size,
                background: bgColor,
                foreground: fgColor,
                level: errorCorrection
            });

            // Show download button and info
            document.getElementById('download-btn').style.display = 'block';
            document.getElementById('qr-info').style.display = 'block';

            // Update QR Info
            document.getElementById('qr-info').innerHTML = `
                <strong>Text/URL:</strong> ${text}<br>
                <strong>Size:</strong> ${size}px<br>
                <strong>Background Color:</strong> ${bgColor}<br>
                <strong>Foreground Color:</strong> ${fgColor}<br>
                <strong>Error Correction Level:</strong> ${errorCorrection}<br>
                <strong>Font Size:</strong> ${fontSize}px<br>
                <strong>Border Radius:</strong> ${borderRadius}px
            `;
        });

        document.getElementById('download-btn').addEventListener('click', () => {
            const canvas = document.getElementById('qr-canvas');
            const link = document.createElement('a');
            link.href = canvas.toDataURL('image/png');
            link.download = 'qr-code.png';
            link.click();
        });

        document.getElementById('dark-mode-toggle').addEventListener('change', (event) => {
            document.body.style.background = event.target.checked
                ? 'linear-gradient(135deg, #2c3e50, #2980b9)'
                : 'linear-gradient(135deg, #16a085, #f4d03f)';
        });
    </script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Code Walkthrough

  1. HTML Structure: We begin with a basic HTML structure, setting up the main container (qr-generator) and various input fields to customize the QR code.

  2. CSS Styling: The CSS styles the QR generator with modern UI elements like a gradient background, smooth animations, and a sleek card layout. We've also implemented a dark mode toggle and adjustable font size and border radius sliders for enhanced customization.

  3. JavaScript Logic:

    • QRious Integration: We use the QRious library to generate the QR code based on user input.
    • Event Listeners: The code includes event listeners for the "Generate" and "Download" buttons, enabling users to create and save their customized QR codes.
    • Dark Mode Toggle: Users can switch between light and dark modes, dynamically changing the background gradient.

Features and Enhancements

  • Customizable QR Code: Users can adjust the size, background color, foreground color, error correction level, font size, and border radius to create a QR code that suits their needs.
  • Dark Mode: Toggle between light and dark modes to match your preference.
  • Responsive Design: The generator is fully responsive, ensuring a seamless experience on both desktop and mobile devices.
  • Download Option: Once generated, users can easily download their QR code as a PNG image.

Conclusion

With just a few lines of HTML, CSS, and JavaScript, you can create a fully customizable and visually appealing QR code generator. This project is a great way to practice integrating front-end technologies while creating something functional and modern. Feel free to expand upon this base by adding more features or tweaking the design to fit your needs. Happy coding!


By Mirza Hanzla 😎

Top comments (0)