In a world where digital security is paramount, we all need strong, unique passwords. But creating them is often a chore. This tool is my solution—it makes generating secure passwords not just easy, but also a visually pleasing experience.
Features That Make a Difference
This isn't just another random string generator. It's a thoughtfully designed application packed with features to enhance both security and usability.
- Stunning "Glassmorphism" UI: The first thing you'll notice is the design. The frosted-glass effect, created with CSS `backdrop-filter`, gives the app a sleek, modern feel that floats above a mesmerizing animated gradient background.
- Personalized & Secure Logic: It uses your inputs (name, year, word, symbol) as a base, then shuffles them into random patterns. This creates a password that is unique to you but avoids being predictable.
- Smart Character Substitution: With a single click, you can enable "leet speak" mode. This feature automatically swaps letters for symbols (like
e → 3ora → @), instantly making your password much harder to crack. - Instant Strength Analysis: A clean, color-coded bar system immediately tells you if your password is Weak, Medium, or Strong, giving you confidence in your result.
- Zero Dependencies: The entire app runs on pure, native web technologies. No frameworks, no libraries, just clean code. This makes it incredibly lightweight, fast, and portable.
How It Works
Using the generator is incredibly simple:
- Fill in the four fields with information that's memorable to you.
- Decide if you want to use Character Substitution for extra strength.
- Click the Generate button to create your password.
- Click the Copy button to instantly save it to your clipboard. A friendly notification will confirm the action.
The Complete Code
I believe in the power of open source and learning by doing. That's why I'm sharing the complete, single-file code below. You can copy it, save it as an HTML file, and run it offline in your browser anytime you want!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Password Generator</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
<style>
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600&display=swap');
:root {
--primary-color: #f0f0f0;
--text-color: #ffffff;
--light-text-color: #dddddd;
--border-color: rgba(255, 255, 255, 0.3);
--shadow-color: rgba(0, 0, 0, 0.15);
--card-bg: rgba(255, 255, 255, 0.1);
--input-bg: rgba(0, 0, 0, 0.15);
--success-color: #58ff7a;
--weak-color: #ff5959;
--medium-color: #ffb86c;
--strong-color: #50fa7b;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Poppins', sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
padding: 1rem;
background: linear-gradient(135deg, #1e133a, #4a23a0, #7a28d1, #23a094);
background-size: 400% 400%;
animation: gradientAnimation 15s ease infinite;
}
@keyframes gradientAnimation {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
.container {
background-color: var(--card-bg);
padding: 2.5rem;
border-radius: 20px;
box-shadow: 0 15px 35px var(--shadow-color);
width: 100%;
max-width: 450px;
text-align: center;
border: 1px solid rgba(255, 255, 255, 0.2);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
@media (max-width: 480px) {
.container { padding: 2rem 1.5rem; }
}
h1 {
color: var(--text-color);
margin-bottom: 2rem;
font-weight: 600;
text-shadow: 0 2px 4px rgba(0,0,0,0.2);
}
.input-group {
margin-bottom: 1.5rem;
position: relative;
}
.input-group i {
position: absolute;
left: 15px;
top: 50%;
transform: translateY(-50%);
color: var(--light-text-color);
transition: color 0.3s;
z-index: 1;
}
input {
width: 100%;
padding: 0.85rem 1rem 0.85rem 45px;
border: 1px solid var(--border-color);
border-radius: 10px;
font-size: 1rem;
font-family: 'Poppins', sans-serif;
background-color: var(--input-bg);
color: var(--text-color);
transition: all 0.3s ease;
}
input::placeholder { color: rgba(255, 255, 255, 0.5); }
input:focus {
outline: none;
border-color: rgba(255, 255, 255, 0.7);
box-shadow: 0 0 15px rgba(255, 255, 255, 0.1);
}
input:focus ~ i { color: var(--text-color); }
.button-group {
display: flex;
gap: 1rem;
margin-top: 1.5rem;
}
button {
flex: 1;
padding: 0.85rem;
border: none;
border-radius: 10px;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
font-family: 'Poppins', sans-serif;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 10px;
}
.generate-btn {
background-color: #ffffff;
color: #333;
}
.copy-btn {
background-color: transparent;
color: var(--text-color);
border: 2px solid var(--border-color);
}
.copy-btn:hover {
background-color: rgba(255, 255, 255, 0.1);
border-color: rgba(255, 255, 255, 0.5);
}
.generate-btn:hover {
background-color: #f0f0f0;
transform: translateY(-2px);
box-shadow: 0 8px 15px rgba(0,0,0,0.2);
}
@media (max-width: 480px) {
.button-group {
flex-direction: column;
}
}
.password-output-container {
margin-top: 2rem;
}
.password-output {
background-color: var(--input-bg);
padding: 1rem;
border-radius: 10px;
word-wrap: break-word;
font-family: 'Courier New', Courier, monospace;
font-size: 1.2rem;
color: var(--text-color);
min-height: 58px;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid var(--border-color);
position: relative;
}
.strength-indicator {
display: flex;
gap: 5px;
margin-top: 10px;
}
.strength-bar {
flex: 1;
height: 6px;
background-color: var(--input-bg);
border-radius: 3px;
transition: background-color 0.3s;
}
.strength-text {
color: var(--light-text-color);
font-size: 0.9rem;
margin-top: 5px;
text-align: right;
height: 1.2em;
}
footer {
margin-top: 2rem;
font-size: 0.9rem;
color: var(--light-text-color);
}
footer a {
color: var(--primary-color);
text-decoration: none;
font-weight: 500;
}
footer a:hover { text-decoration: underline; }
.toast {
position: fixed;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
background-color: #333;
color: white;
padding: 10px 20px;
border-radius: 5px;
opacity: 0;
visibility: hidden;
transition: opacity 0.3s, visibility 0.3s;
z-index: 1000;
}
.toast.show { opacity: 1; visibility: visible; }
.options {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.5rem 0;
color: var(--light-text-color);
}
.switch {
position: relative;
display: inline-block;
width: 50px;
height: 28px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: var(--input-bg);
transition: .4s;
border-radius: 28px;
border: 1px solid var(--border-color);
}
.slider:before {
position: absolute;
content: "";
height: 20px;
width: 20px;
left: 3px;
bottom: 3px;
background-color: white;
transition: .4s;
border-radius: 50%;
}
input:checked + .slider {
background-color: var(--success-color);
border-color: var(--success-color);
}
input:checked + .slider:before {
transform: translateX(22px);
}
</style>
</head>
<body>
<div class="container">
<h1>Password Generator</h1>
<div class="input-group">
<i class="fas fa-user"></i>
<input type="text" id="name" placeholder="Name">
</div>
<div class="input-group">
<i class="fas fa-calendar-alt"></i>
<input type="number" id="year" placeholder="Birth Year" min="1900" max="2099">
</div>
<div class="input-group">
<i class="fas fa-star"></i>
<input type="text" id="word" placeholder="Favorite Word">
</div>
<div class="input-group">
<i class="fas fa-icons"></i>
<input type="text" id="symbol" placeholder="Symbol">
</div>
<div class="options">
<span><i class="fa-solid fa-arrows-left-right-to-line"></i> Character Substitution</span>
<label class="switch">
<input type="checkbox" id="char-sub">
<span class="slider"></span>
</label>
</div>
<div class="password-output-container">
<div class="password-output" id="passwordOutput">Your password appears here</div>
<div class="strength-indicator">
<div class="strength-bar" id="bar1"></div>
<div class="strength-bar" id="bar2"></div>
<div class="strength-bar" id="bar3"></div>
</div>
<div class="strength-text" id="strengthText"></div>
</div>
<div class="button-group">
<button class="generate-btn" onclick="generatePassword()">
<i class="fas fa-key"></i> Generate
</button>
<button class="copy-btn" id="copyBtn" onclick="copyToClipboard()">
<i class="fas fa-copy"></i> Copy
</button>
</div>
<footer>
Made with <span style="color: #ff5959;">♥</span> by <a href="https://codeanniversary.blogspot.com/" target="_blank">CodeAnniversary</a>
</footer>
</div>
<div id="toast" class="toast"></div>
<script>
const passwordOutput = document.getElementById('passwordOutput');
function showToast(message, isSuccess = true) {
const toast = document.getElementById('toast');
toast.textContent = message;
toast.style.backgroundColor = isSuccess ? '#28a745' : '#dc3545';
toast.classList.add('show');
setTimeout(() => {
toast.classList.remove('show');
}, 3000);
}
function updateStrengthIndicator(password) {
const strengthText = document.getElementById('strengthText');
const bars = [document.getElementById('bar1'), document.getElementById('bar2'), document.getElementById('bar3')];
let strength = 0;
if (password.length >= 8) strength++;
if (password.match(/[A-Z]/)) strength++;
if (password.match(/[0-9]/)) strength++;
if (password.match(/[^a-zA-Z0-9]/)) strength++;
bars.forEach(bar => bar.style.backgroundColor = 'var(--input-bg)');
if (password.length > 0) {
if (strength <= 2) {
bars[0].style.backgroundColor = 'var(--weak-color)';
strengthText.textContent = 'Weak';
strengthText.style.color = 'var(--weak-color)';
} else if (strength === 3) {
bars[0].style.backgroundColor = 'var(--medium-color)';
bars[1].style.backgroundColor = 'var(--medium-color)';
strengthText.textContent = 'Medium';
strengthText.style.color = 'var(--medium-color)';
} else {
bars.forEach(bar => bar.style.backgroundColor = 'var(--strong-color)');
strengthText.textContent = 'Strong';
strengthText.style.color = 'var(--strong-color)';
}
} else {
strengthText.textContent = '';
}
}
function generatePassword() {
const name = document.getElementById('name').value.trim();
const yearInput = document.getElementById('year').value;
const word = document.getElementById('word').value.trim();
const symbol = document.getElementById('symbol').value.trim();
const useCharSub = document.getElementById('char-sub').checked;
if (!name || !yearInput || !word || !symbol) {
showToast('Please fill in all fields.', false);
return;
}
const currentYear = new Date().getFullYear();
const year = parseInt(yearInput, 10);
if (isNaN(year) || year < 1900 || year > currentYear) {
showToast(`Please enter a valid year between 1900 and ${currentYear}.`, false);
return;
}
const nameSub = name.length > 2 ? name.substring(0, 3) : name;
const wordSub = word.length > 2 ? word.substring(0, 3) : word;
let patterns = [
name + symbol + year + word,
word.charAt(0).toUpperCase() + word.slice(1) + year + symbol + name,
symbol + name + word.toUpperCase() + year,
year + word + nameSub + symbol,
nameSub.toUpperCase() + symbol + year.toString().slice(-2) + word.toLowerCase(),
word + symbol + (currentYear - year) + nameSub,
name.toLowerCase() + symbol + word.toLowerCase() + year.toString().slice(-2)
];
let randomPattern = patterns[Math.floor(Math.random() * patterns.length)];
if (useCharSub) {
const substitutions = { 'e': '3', 'a': '@', 'o': '0', 'i': '1', 's': '$', 'l': '!', 't': '7' };
randomPattern = randomPattern.split('').map(char => substitutions[char.toLowerCase()] || char).join('');
}
const randomNumber = Math.floor(Math.random() * 900) + 100;
const generatedPassword = randomPattern + randomNumber;
passwordOutput.textContent = generatedPassword;
updateStrengthIndicator(generatedPassword);
}
function copyToClipboard() {
const copyBtn = document.getElementById('copyBtn');
const password = passwordOutput.textContent;
if (password === 'Your password appears here' || !password) {
showToast('Generate a password first!', false);
return;
}
navigator.clipboard.writeText(password).then(() => {
showToast('Password copied to clipboard!');
copyBtn.innerHTML = '<i class="fas fa-check"></i> Copied!';
setTimeout(() => {
copyBtn.innerHTML = '<i class="fas fa-copy"></i> Copy';
}, 2000);
}).catch(err => {
console.error('Failed to copy: ', err);
showToast('Failed to copy password.', false);
});
}
// Initialize with empty strength indicator
updateStrengthIndicator('');
</script>
</body>
</html>
Feel free to dive into the code on CodePen, fork the project, and experiment with your own patterns or styles. I hope you find this tool as useful and enjoyable as I found building it!

Thanks, It’s working perfectly!!
ReplyDelete