<!-- ---------------- Created By InCoder ---------------- -->
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Random Password Generator - InCoder</title>
    <link rel="stylesheet" href="main.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css">
</head>

<body>
    <div class="container">
        <div class="coppiedMessage">
            <i class="fa-solid fa-circle-check"></i>
            <p>Password Copied</p>
        </div>
        <div class="generatorBox">
            <h1 class="title">Password Generator</h1>
            <div id="passwordDisplay"><p>Password</p> <span id="copyToClipboardBtn"><i class="fa-solid fa-copy"></i></span></div>
            <form id="generatorOptions">
                <div class="options">
                    <div class="characterRange">
                        <p>Characters: <span class="characterSpan">16</span></p>
                        <div class="form-group">
                            <input type="range" id="characterRange" value="16" min="4">
                        </div>
                    </div>
                    <p>Options</p>
                    <div class="includeUppercase">
                        <div class="form-group">
                            <p>Include Uppercase</p>
                            <input type="checkbox" id="includeUppercase">
                            <label class="checkbox" for="includeUppercase">
                                <span class="slider"></span>
                            </label>
                        </div>
                    </div>
                    <div class="includeNumbers">
                        <div class="form-group">
                            <p>Include Numbers</p>
                            <input type="checkbox" id="includeNumbers">
                            <label class="checkbox" for="includeNumbers">
                                <span class="slider"></span>
                            </label>
                        </div>
                    </div>
                    <div class="includeSymbols">
                        <div class="form-group">
                            <p>Include Symbols</p>
                            <input type="checkbox" id="includeSymbols">
                            <label class="checkbox" for="includeSymbols">
                                <span class="slider"></span>
                            </label>
                        </div>
                    </div>
                    <button type="submit">Generate Password</button>
                </div>
            </form>
        </div>
    </div>

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

</html>
/* ---------------- Created By InCoder ---------------- */

@import url("https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap");

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: "Poppins", sans-serif;
}

:root {
  --X: 0;
  --Y: 0;
  --border-radius: 0.5rem;
}

body {
  display: flex;
  height: 100vh;
  align-items: center;
  background: #008d91e3;
  justify-content: center;
}

.container .generatorBox {
  display: flex;
  align-items: center;
  border-radius: 0.8rem;
  flex-direction: column;
  justify-content: center;
  width: clamp(20rem, 22vw, 20rem);
  box-shadow: 0 0 20px #33295f8a;
  transition: box-shadow 0.3s ease-in-out;
  background-image: linear-gradient(250deg, #1e1642 30%, #211558 80%);
}

.container .generatorBox .title {
  color: #fff;
  text-align: center;
  padding-top: 0.6rem;
  font-size: clamp(1.2rem, 4vw, 1.5rem);
}

#passwordDisplay {
  border: 0;
  width: 100%;
  color: #fff;
  display: flex;
  height: 3.2rem;
  padding: 0 0.8rem;
  font-size: 0.9rem;
  overflow: hidden;
  margin-top: 0.6rem;
  position: relative;
  align-items: center;
  background: #33295f;
  justify-content: center;
  max-width: calc(100% - 1.5rem);
  border-radius: var(--border-radius);
}

#passwordDisplay p {
  max-width: 80%;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

#passwordDisplay:focus {
  outline: none;
  pointer-events: none;
}

#passwordDisplay::placeholder {
  color: #ccc;
}

#passwordDisplay:focus::placeholder {
  color: #fff;
}

#generatorOptions {
  color: #fff;
  width: calc(100% - 1.5rem);
}

#generatorOptions .form-group {
  border: 0;
  height: 3rem;
  color: #fff;
  display: flex;
  max-width: 100%;
  padding: 0 0.8rem;
  font-size: 0.9rem;
  align-items: center;
  margin-bottom: 0.5rem;
  background: #33295f;
  justify-content: space-between;
  border-radius: var(--border-radius);
}

#generatorOptions .characterRange {
  font-size: 0.7rem;
  margin-top: 0.6rem;
}

#generatorOptions .characterRange .form-group {
  justify-content: center !important;
}

#generatorOptions .options > p {
  font-size: 0.8rem;
  margin-bottom: 0.1rem;
}

#copyToClipboardBtn {
  opacity: 0;
  z-index: 1;
  top: var(--Y);
  width: 2.6rem;
  display: flex;
  height: 2.6rem;
  left: var(--X);
  cursor: pointer;
  color: #1e1642;
  font-size: 1.2rem;
  position: absolute;
  border-radius: 50%;
  align-items: center;
  pointer-events: none;
  transform: scale(0.2);
  justify-content: center;
  background-color: #fff;
  transition: transform 0.6s cubic-bezier(0.24, -0.08, 0.24, 1.81);
}

#passwordDisplay.copyBtnShow #copyToClipboardBtn {
  transform: translate(-50%, -50%) scale(1);
}

#characterRange {
  width: 90%;
  height: 2px;
  opacity: 0.7;
  outline: none;
  position: relative;
  background: #d3d3d3a1;
  -webkit-transition: 0.2s;
  -webkit-appearance: none;
  transition: opacity 0.2s;
}

#characterRange:hover {
  opacity: 1;
}

#characterRange::-webkit-slider-thumb {
  width: 20px;
  height: 20px;
  cursor: pointer;
  appearance: none;
  border-radius: 50%;
  background: #5d68e2;
  -webkit-appearance: none;
}

#characterRange::-moz-range-thumb {
  width: 20px;
  height: 20px;
  cursor: pointer;
  border-radius: 50%;
  background: #5d68e2;
}

#characterRange::before {
  content: "4";
  left: -14px;
  width: auto;
  height: auto;
  bottom: -8px;
  color: #fff;
  font-size: 0.7rem;
  position: absolute;
}

#characterRange::after {
  content: "100";
  right: -23px;
  width: auto;
  height: auto;
  bottom: -8px;
  color: #fff;
  font-size: 0.7rem;
  position: absolute;
}

#generatorOptions .form-group input[type="checkbox"] {
  width: 0;
  height: 0;
  visibility: hidden;
}

#generatorOptions .checkbox {
  width: 2.6rem;
  display: flex;
  height: 1.5rem;
  padding: 0 4px;
  cursor: pointer;
  position: relative;
  align-items: center;
  border-radius: 50rem;
  transition: background-color 0.3s cubic-bezier(0.55, -0.34, 0.16, 1.95);
  background-color: rgba(214, 214, 214, 0.434);
}

#generatorOptions .checkbox::before {
  content: "";
  left: 4px;
  width: 45%;
  height: 75%;
  border-radius: 50%;
  position: absolute;
  background-color: #fff;
  transition: left 0.3s cubic-bezier(0.55, -0.34, 0.16, 1.95);
}

#generatorOptions .form-group input[type="checkbox"]:checked + .checkbox {
  background-color: #7c3aed;
}

#generatorOptions
  .form-group
  input[type="checkbox"]:checked
  + .checkbox::before {
  left: 18px;
}

#generatorOptions button[type="submit"] {
  border: 0;
  width: 100%;
  color: #fff;
  display: flex;
  height: 2.5rem;
  cursor: pointer;
  font-size: 1rem;
  align-items: center;
  margin-bottom: 1rem;
  border-radius: 0.4rem;
  justify-content: center;
  background: linear-gradient(45deg, #7c3aed 30%, #db2777);
}

.coppiedMessage {
  top: 10%;
  left: 50%;
  opacity: 0;
  width: 12rem;
  height: 2rem;
  display: flex;
  color: #30f28a;
  border-radius: 5px;
  position: absolute;
  align-items: center;
  pointer-events: none;
  background: #33295f;
  justify-content: center;
  transform: translate(-50%, 25px);
  transition: transform .3s cubic-bezier(0.18,-0.02, 0.3, 1.6);
}

.coppiedMessage.success{
    opacity: 1;
    pointer-events: auto;
    transform: translate(-50%, 0);
}

.coppiedMessage i{
    color: #30f28a;
    margin-right: .4rem;
}
// ---------------- Created By InCoder ----------------

let passwordDisplayText = document.querySelector('#passwordDisplay p')
let copyToClipboardBtn = document.querySelector('#copyToClipboardBtn')
let includeUppercase = document.querySelector('#includeUppercase')
let passwordDisplay = document.querySelector('#passwordDisplay')
let characterRange = document.querySelector('#characterRange')
let includeNumbers = document.querySelector('#includeNumbers')
let coppiedMessage = document.querySelector('.coppiedMessage')
let includeSymbols = document.querySelector('#includeSymbols')
let characterSpan = document.querySelector('.characterSpan')

let arrayLowToHigh = (low, high) => {
    let array = []
    for (let i = low; i <= high; i++) {
        array.push(i);
    }
    return array
}

let LOWERCASE_CHAR_CODES = arrayLowToHigh(97, 122);
let UPPERCASE_CHAR_CODES = arrayLowToHigh(65, 90);
let NUMBERS_CHAR_CODES = arrayLowToHigh(48, 57);
let SYMBOL_CHAR_CODES = arrayLowToHigh(34, 47).concat(
    arrayLowToHigh(58, 64)
).concat(
    arrayLowToHigh(91, 96)
).concat(
    arrayLowToHigh(123, 126)
);


// ---------------- Character value changer ----------------

characterRange.addEventListener('input', e => {
    characterSpan.innerHTML = e.target.value
})

// ---------------- Character value changer End ----------------

// ---------------- Password Generator Function ----------------

let generatePassword = (characterRange, includeUppercase, includeNumbers, includeSymbols) => {
    let charCodes = LOWERCASE_CHAR_CODES;

    if (includeUppercase) charCodes = charCodes.concat(UPPERCASE_CHAR_CODES)
    if (includeNumbers) charCodes = charCodes.concat(NUMBERS_CHAR_CODES)
    if (includeSymbols) charCodes = charCodes.concat(SYMBOL_CHAR_CODES)

    let passwordChar = []
    for (let a = 0; a < characterRange; a++) {
        let characterCode = charCodes[Math.floor(Math.random() * characterRange)]
        passwordChar.push(String.fromCharCode(characterCode))
    }
    return passwordChar.join('')
}

// ---------------- Password Generator Function End ----------------

// ---------------- Form Submit ----------------

let generatorOptions = document.querySelector('#generatorOptions')

generatorOptions.addEventListener('submit', e => {
    e.preventDefault();
    let password = generatePassword(characterRange.value, includeUppercase.checked, includeNumbers.checked, includeSymbols.checked);

    passwordDisplayText.innerHTML = password
    
    // ---------------- Copy Button Function ----------------
    
    passwordDisplay.addEventListener('mousemove', (e) => {
        resultContainerBound = {
            left: passwordDisplay.getBoundingClientRect().left,
            top: passwordDisplay.getBoundingClientRect().top,
        };
        copyToClipboardBtn.style.opacity = '1';
        copyToClipboardBtn.style.pointerEvents = 'all';
        passwordDisplay.classList.add('copyBtnShow')
        copyToClipboardBtn.style.setProperty("--X", `${e.x - resultContainerBound.left}px`);
        copyToClipboardBtn.style.setProperty("--Y", `${e.y - resultContainerBound.top}px`);
    })
    
    passwordDisplay.addEventListener('mouseleave', (e) => {
        setTimeout(() => {
            copyToClipboardBtn.style.opacity = '0';
            copyToClipboardBtn.style.pointerEvents = 'none';
            copyToClipboardBtn.style.setProperty("--X", '0');
            copyToClipboardBtn.style.setProperty("--Y", '0');
        }, 300)
        passwordDisplay.classList.remove('copyBtnShow')
    })
    
    // ---------------- Copy Button Animation End ----------------

    copyToClipboardBtn.addEventListener('click', () => {
        const textarea = document.createElement("textarea");
        textarea.value = password;
        document.body.appendChild(textarea);
        textarea.select();
        document.execCommand("copy");
        textarea.remove();

        coppiedMessage.classList.add('success')
        
        setTimeout(() => {
            coppiedMessage.classList.remove('success')
        }, 2500)
    })
})

// ---------------- Form Submit End ----------------
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.