<div class="container">
<h2>Password Generator</h2>
<div class="result-container">
<input type="text" id="result">
<button class="copy-result" id="copy">
Copy
</button>
</div>
<div class="settings">
<div class="input-group">
<label>Password length (4-20)</label>
<input type="range" id="length" min='4' max='20' step="1" />
<span id="length-result">10</span>
</div>
<div class="input-group">
<label>Include numbers</label>
<input type="checkbox" id="numbers" checked />
</div>
<div class="input-group">
<label>Include symbols</label>
<input type="checkbox" id="symbols" checked />
</div>
</div>
<button class="generate-btn" id="generate">
Generate
</button>
</div>
:root {
--teal: #06b6d4;
--blue: #3b82f6;
--lightgray: #cbd5e1;
--gradient: linear-gradient(to right,var(--teal), var(--blue))
}
body {
background-image: var(--gradient);
font-family: "Lexend", sans-serif;
accent-color: var(--blue);
font-smoothing: antialiased;
}
.container {
max-width: 390px;
margin: 5rem auto;
padding: 26px;
border-radius: 20px;
background: white;
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
}
.result-container {
display: flex;
align-items: center;
justify-content: space-between;
position: relative;
}
#result {
flex: 1;
font-family: Monaco, mono;
background: #f4f4f4;
}
.copy-result {
background-image: var(--gradient);
border: none;
padding: 14px 18px;
color: white;
border-radius: 25px;
margin-left: 16px;
position: absolute;
right: 12px;
font-weight: 600;
cursor: pointer;
z-index: 50;
font-size: .8rem;
}
.copy-result:hover {
background: var(--blue);
}
input[type="text"] {
padding: 20px 24px;
border: 1px solid var(--lightgray);
border-radius: 50px;
}
input[type="range"] {
padding: 8px 10px;
background: #f8f8f8;
flex: 1;
margin-left: 1rem;
margin-right: 1rem;
}
input[type="text"]:focus,
input[type="number"]:focus {
border: 1px solid var(--teal);
outline: none;
}
input[type="checkbox"] {
width: 16px;
height: 16px;
}
.settings {
margin-top: 3rem;
}
.input-group {
margin-bottom: 2rem;
display: flex;
align-items: center;
justify-content: space-between;
}
.generate-btn {
background-image: var(--gradient);
padding: 14px 24px;
border: none;
font-weight: 600;
color: white;
display: block;
width: 100%;
border-radius: 25px;
cursor: pointer;
font-size: 1.25rem;
}
.generate-btn:hover,
.copy-btn:hover {
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
background: var(--blue);
}
.alert {
position: fixed;
top: 6px;
right: 6px;
padding: 10px;
border-radius: 4px;
background: rgba(0,0,0, .4);
color: white;
font-size: 20px;
}
const result = document.querySelector('#result');
const passLength = document.querySelector('#length');
const passLengthResult = document.querySelector('#length-result')
const includeNumbers = document.querySelector('#numbers');
const includeSymbols = document.querySelector('#symbols');
const generateBtn = document.querySelector('#generate');
const copyPass = document.querySelector('#copy');
// Set default password length 20 max on load
document.addEventListener('DOMContentLoaded', () => {
passLength.value = 20
passLengthResult.innerText = 20
let onLoadLength = passLength.value
let onLoadNumbers = includeNumbers.checked
let onLoadSymbols = includeSymbols.checked
result.value = generatePassword(onLoadNumbers, onLoadSymbols, onLoadLength)
})
// Listen for password range change
passLength.addEventListener('change', (event) => {
passLengthResult.innerText = event.target.value
})
// Listen for copy button
copyPass.addEventListener('click', () => {
copy(result.value)
})
generateBtn.addEventListener('click', () => {
const length = passLength.value
const numbers = includeNumbers.checked
const symbols = includeSymbols.checked
result.value = generatePassword(numbers, symbols, length)
})
function generatePassword(number, symbol, length) {
let generatedPassword = '';
let variationsCount = [number, symbol].length
for(let i = 0; i < length; i += variationsCount) {
if (number) {
generatedPassword += getRandomNumber()
}
if (symbol) {
generatedPassword += getRandomSymbol()
}
generatedPassword += getRandomLower()
}
const finalPassword = generatedPassword.slice(0, length);
return finalPassword;
}
function getRandomLower() {
return String.fromCharCode(Math.floor(Math.random() * 26) + 97);
}
function getRandomNumber() {
return String.fromCharCode(Math.floor(Math.random() * 10) + 48);
}
function getRandomSymbol() {
const symbols = '!@#$%^&*(){}[]=<>/,.'
return symbols[Math.floor(Math.random() * symbols.length)];
}
// Copy generated password in more secure way
function copy(text) {
const input = document.createElement('input');
input.setAttribute('value', text);
document.body.appendChild(input);
input.select();
let copiedResult = document.execCommand('copy');
document.body.removeChild(input);
const alert = document.createElement("div")
alert.classList.add("alert");
alert.textContent = "Copied!"
document.body.appendChild(alert)
setTimeout(() => {
document.querySelector('.alert').style.display = "none"
document.body.removeChild(alert)
}, 1000)
return result;
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.