Features of this Password Generator:
- Interactive Design:
- Modern gradient background with glassmorphism effect
- Smooth animations and transitions
- Responsive layout that works on all devices
- Password Generation Options:
- Adjustable password length (8-32 characters)
- Toggle for uppercase, lowercase, numbers, and symbols
- Option to use secure API or local generation
- Password Strength Indicator:
- Visual strength meter that updates in real-time
- Color-coded feedback (weak, fair, good, strong)
- Password Management:
- Generate new passwords with one click
- Copy to clipboard functionality
- Save functionality (simulated for demo)
- Clear button to reset
- API Integration:
- Uses the API Ninjas password generator API
- Fallback to local generation if API fails
- Toggle to choose between API and local generation
- User Experience:
- Notification system for user feedback
- Clear visual hierarchy
- Intuitive controls and options
Simply copy and paste this code into an HTML file and open it in your browser to use the password generator.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Secure Password Generator</title>
<style>
:root {
--primary: #4361ee;
--primary-dark: #3a56d4;
--secondary: #7209b7;
--success: #4cc9f0;
--danger: #f72585;
--light: #f8f9fa;
--dark: #212529;
--gray: #6c757d;
--border-radius: 12px;
--shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
--transition: all 0.3s ease;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
color: var(--light);
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
padding: 2rem 1rem;
}
.container {
max-width: 800px;
width: 100%;
background: rgba(255, 255, 255, 0.05);
backdrop-filter: blur(10px);
border-radius: var(--border-radius);
padding: 2rem;
box-shadow: var(--shadow);
border: 1px solid rgba(255, 255, 255, 0.1);
}
header {
text-align: center;
margin-bottom: 2rem;
}
h1 {
font-size: 2.5rem;
margin-bottom: 0.5rem;
background: linear-gradient(to right, var(--primary), var(--secondary));
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.subtitle {
color: var(--gray);
font-size: 1.1rem;
}
.password-display {
background: rgba(0, 0, 0, 0.3);
border-radius: var(--border-radius);
padding: 1.5rem;
margin-bottom: 1.5rem;
position: relative;
border: 1px solid rgba(255, 255, 255, 0.1);
}
.password-text {
font-size: 1.5rem;
font-weight: 600;
letter-spacing: 1px;
word-break: break-all;
margin-bottom: 1rem;
min-height: 2rem;
color: var(--success);
}
.password-placeholder {
color: var(--gray);
font-style: italic;
}
.password-actions {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
}
.btn {
padding: 0.75rem 1.5rem;
border: none;
border-radius: var(--border-radius);
font-weight: 600;
cursor: pointer;
transition: var(--transition);
display: flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
}
.btn-primary {
background: var(--primary);
color: white;
}
.btn-primary:hover {
background: var(--primary-dark);
transform: translateY(-2px);
}
.btn-secondary {
background: rgba(255, 255, 255, 0.1);
color: white;
border: 1px solid rgba(255, 255, 255, 0.2);
}
.btn-secondary:hover {
background: rgba(255, 255, 255, 0.2);
}
.btn-success {
background: var(--success);
color: var(--dark);
}
.btn-success:hover {
background: #3ab0d5;
}
.btn-danger {
background: var(--danger);
color: white;
}
.btn-danger:hover {
background: #e01a6f;
}
.options {
background: rgba(0, 0, 0, 0.2);
border-radius: var(--border-radius);
padding: 1.5rem;
margin-bottom: 1.5rem;
}
.option-group {
margin-bottom: 1.5rem;
}
.option-title {
font-size: 1.1rem;
margin-bottom: 0.75rem;
color: var(--light);
display: flex;
align-items: center;
gap: 0.5rem;
}
.slider-container {
display: flex;
align-items: center;
gap: 1rem;
}
.slider {
flex: 1;
-webkit-appearance: none;
height: 8px;
border-radius: 4px;
background: rgba(255, 255, 255, 0.1);
outline: none;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
width: 20px;
height: 20px;
border-radius: 50%;
background: var(--primary);
cursor: pointer;
transition: var(--transition);
}
.slider::-webkit-slider-thumb:hover {
background: var(--primary-dark);
transform: scale(1.1);
}
.length-value {
font-weight: 600;
min-width: 2rem;
text-align: center;
}
.checkbox-group {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 0.75rem;
}
.checkbox-item {
display: flex;
align-items: center;
gap: 0.5rem;
}
.checkbox-item input {
width: 18px;
height: 18px;
accent-color: var(--primary);
}
.strength-meter {
margin-top: 1.5rem;
}
.strength-bar {
height: 10px;
border-radius: 5px;
background: rgba(255, 255, 255, 0.1);
margin-top: 0.5rem;
overflow: hidden;
}
.strength-fill {
height: 100%;
width: 0%;
border-radius: 5px;
transition: var(--transition);
}
.strength-text {
font-weight: 600;
margin-top: 0.5rem;
}
.strength-weak {
background: var(--danger);
width: 25%;
}
.strength-fair {
background: #ff9e00;
width: 50%;
}
.strength-good {
background: #ffd166;
width: 75%;
}
.strength-strong {
background: var(--success);
width: 100%;
}
.api-section {
background: rgba(0, 0, 0, 0.2);
border-radius: var(--border-radius);
padding: 1.5rem;
margin-top: 1.5rem;
}
.api-toggle {
display: flex;
align-items: center;
gap: 0.5rem;
margin-bottom: 1rem;
cursor: pointer;
}
.api-toggle input {
width: 18px;
height: 18px;
accent-color: var(--primary);
}
.api-info {
color: var(--gray);
font-size: 0.9rem;
margin-top: 0.5rem;
}
.notification {
position: fixed;
top: 20px;
right: 20px;
padding: 1rem 1.5rem;
background: var(--success);
color: var(--dark);
border-radius: var(--border-radius);
box-shadow: var(--shadow);
transform: translateX(150%);
transition: transform 0.3s ease;
z-index: 1000;
font-weight: 600;
}
.notification.show {
transform: translateX(0);
}
footer {
margin-top: 2rem;
text-align: center;
color: var(--gray);
font-size: 0.9rem;
}
@media (max-width: 600px) {
.container {
padding: 1.5rem;
}
h1 {
font-size: 2rem;
}
.password-text {
font-size: 1.25rem;
}
.checkbox-group {
grid-template-columns: 1fr;
}
.password-actions {
flex-direction: column;
}
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>Secure Password Generator</h1>
<p class="subtitle">Create strong, random passwords to keep your accounts safe</p>
</header>
<div class="password-display">
<div class="password-text" id="passwordOutput">
<span class="password-placeholder">Your password will appear here</span>
</div>
<div class="password-actions">
<button class="btn btn-primary" id="generateBtn">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M8 4.754a3.246 3.246 0 1 0 0 6.492 3.246 3.246 0 0 0 0-6.492zM5.754 8a2.246 2.246 0 1 1 4.492 0 2.246 2.246 0 0 1-4.492 0z"/>
<path d="M9.796 1.343c-.527-1.79-3.065-1.79-3.592 0l-.094.319a.873.873 0 0 1-1.255.52l-.292-.16c-1.64-.892-3.433.902-2.54 2.541l.159.292a.873.873 0 0 1-.52 1.255l-.319.094c-1.79.527-1.79 3.065 0 3.592l.319.094a.873.873 0 0 1 .52 1.255l-.16.292c-.892 1.64.901 3.434 2.541 2.54l.292-.159a.873.873 0 0 1 1.255.52l.094.319c.527 1.79 3.065 1.79 3.592 0l.094-.319a.873.873 0 0 1 1.255-.52l.292.16c1.64.893 3.434-.902 2.54-2.541l-.159-.292a.873.873 0 0 1 .52-1.255l.319-.094c1.79-.527 1.79-3.065 0-3.592l-.319-.094a.873.873 0 0 1-.52-1.255l.16-.292c.893-1.64-.902-3.433-2.541-2.54l-.292.159a.873.873 0 0 1-1.255-.52l-.094-.319zm-2.633.283c.246-.835 1.428-.835 1.674 0l.094.319a1.873 1.873 0 0 0 2.693 1.115l.291-.16c.764-.415 1.6.42 1.184 1.185l-.159.292a1.873 1.873 0 0 0 1.116 2.692l.318.094c.835.246.835 1.428 0 1.674l-.319.094a1.873 1.873 0 0 0-1.115 2.693l.16.291c.415.764-.42 1.6-1.185 1.184l-.291-.159a1.873 1.873 0 0 0-2.693 1.116l-.094.318c-.246.835-1.428.835-1.674 0l-.094-.319a1.873 1.873 0 0 0-2.692-1.115l-.292.16c-.764.415-1.6-.42-1.184-1.185l.159-.291A1.873 1.873 0 0 0 1.945 8.93l-.319-.094c-.835-.246-.835-1.428 0-1.674l.319-.094A1.873 1.873 0 0 0 3.06 4.377l-.16-.292c-.415-.764.42-1.6 1.185-1.184l.292.159a1.873 1.873 0 0 0 2.692-1.115l.094-.319z"/>
</svg>
Generate Password
</button>
<button class="btn btn-secondary" id="copyBtn">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M4 1.5H3a2 2 0 0 0-2 2V14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3.5a2 2 0 0 0-2-2h-1v1h1a1 1 0 0 1 1 1V14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V3.5a1 1 0 0 1 1-1h1v-1z"/>
<path d="M9.5 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5h3zm-3-1A1.5 1.5 0 0 0 5 1.5v1A1.5 1.5 0 0 0 6.5 4h3A1.5 1.5 0 0 0 11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3z"/>
</svg>
Copy
</button>
<button class="btn btn-success" id="saveBtn">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M2 1a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H9.5a1 1 0 0 0-1 1v7.293l2.646-2.647a.5.5 0 0 1 .708.708l-3.5 3.5a.5.5 0 0 1-.708 0l-3.5-3.5a.5.5 0 1 1 .708-.708L7.5 9.293V2a2 2 0 0 1 2-2H14a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h2.5a.5.5 0 0 1 0 1H2z"/>
</svg>
Save
</button>
<button class="btn btn-danger" id="clearBtn">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z"/>
<path fill-rule="evenodd" d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z"/>
</svg>
Clear
</button>
</div>
</div>
<div class="options">
<div class="option-group">
<h3 class="option-title">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4z"/>
</svg>
Password Length
</h3>
<div class="slider-container">
<input type="range" min="8" max="32" value="16" class="slider" id="lengthSlider">
<span class="length-value" id="lengthValue">16</span>
</div>
</div>
<div class="option-group">
<h3 class="option-title">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M11 1a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h6zM5 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H5z"/>
<path d="M8 14a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/>
</svg>
Character Types
</h3>
<div class="checkbox-group">
<label class="checkbox-item">
<input type="checkbox" id="uppercase" checked>
Uppercase Letters (A-Z)
</label>
<label class="checkbox-item">
<input type="checkbox" id="lowercase" checked>
Lowercase Letters (a-z)
</label>
<label class="checkbox-item">
<input type="checkbox" id="numbers" checked>
Numbers (0-9)
</label>
<label class="checkbox-item">
<input type="checkbox" id="symbols" checked>
Symbols (!@#$%^&*)
</label>
</div>
</div>
<div class="option-group strength-meter">
<h3 class="option-title">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M3.5 11.5a3.5 3.5 0 1 1 3.163-5H14L15 5g-2 0-6.5-.5S2 5 2 5.5 3.5 11.5 3.5 11.5zm.5-9a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1zm3 0a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1zm3 0a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h1a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5h-1z"/>
</svg>
Password Strength
</h3>
<div class="strength-bar">
<div class="strength-fill" id="strengthFill"></div>
</div>
<div class="strength-text" id="strengthText">Generate a password to see strength</div>
</div>
</div>
<div class="api-section">
<label class="api-toggle">
<input type="checkbox" id="useApi">
Use API for generation (more secure)
</label>
<p class="api-info">When enabled, passwords are generated using a secure external API. Otherwise, generation happens locally in your browser.</p>
</div>
</div>
<div class="notification" id="notification">Password copied to clipboard!</div>
<footer>
<p>© 2023 Secure Password Generator | Keep your accounts safe with strong passwords</p>
</footer>
<script>
// DOM Elements
const passwordOutput = document.getElementById('passwordOutput');
const generateBtn = document.getElementById('generateBtn');
const copyBtn = document.getElementById('copyBtn');
const saveBtn = document.getElementById('saveBtn');
const clearBtn = document.getElementById('clearBtn');
const lengthSlider = document.getElementById('lengthSlider');
const lengthValue = document.getElementById('lengthValue');
const uppercaseCheckbox = document.getElementById('uppercase');
const lowercaseCheckbox = document.getElementById('lowercase');
const numbersCheckbox = document.getElementById('numbers');
const symbolsCheckbox = document.getElementById('symbols');
const strengthFill = document.getElementById('strengthFill');
const strengthText = document.getElementById('strengthText');
const useApiCheckbox = document.getElementById('useApi');
const notification = document.getElementById('notification');
// Character sets
const uppercaseChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
const lowercaseChars = 'abcdefghijklmnopqrstuvwxyz';
const numberChars = '0123456789';
const symbolChars = '!@#$%^&*()_+-=[]{}|;:,.<>?';
// Update length display when slider changes
lengthSlider.addEventListener('input', () => {
lengthValue.textContent = lengthSlider.value;
});
// Generate password function
function generatePassword() {
const length = parseInt(lengthSlider.value);
const useUppercase = uppercaseCheckbox.checked;
const useLowercase = lowercaseCheckbox.checked;
const useNumbers = numbersCheckbox.checked;
const useSymbols = symbolsCheckbox.checked;
const useApi = useApiCheckbox.checked;
// Validate at least one character type is selected
if (!useUppercase && !useLowercase && !useNumbers && !useSymbols) {
showNotification('Please select at least one character type', 'error');
return;
}
if (useApi) {
generatePasswordWithAPI(length);
} else {
generatePasswordLocally(length, useUppercase, useLowercase, useNumbers, useSymbols);
}
}
// Generate password locally
function generatePasswordLocally(length, useUppercase, useLowercase, useNumbers, useSymbols) {
let charset = '';
if (useUppercase) charset += uppercaseChars;
if (useLowercase) charset += lowercaseChars;
if (useNumbers) charset += numberChars;
if (useSymbols) charset += symbolChars;
let password = '';
for (let i = 0; i < length; i++) {
const randomIndex = Math.floor(Math.random() * charset.length);
password += charset[randomIndex];
}
displayPassword(password);
}
// Generate password using API
async function generatePasswordWithAPI(length) {
try {
generateBtn.disabled = true;
generateBtn.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"><path d="M11.534 7h3.932a.25.25 0 0 1 .192.41l-1.966 2.36a.25.25 0 0 1-.384 0l-1.966-2.36a.25.25 0 0 1 .192-.41zm-11 2h3.932a.25.25 0 0 0 .192-.41L2.692 6.23a.25.25 0 0 0-.384 0L.342 8.59A.25.25 0 0 0 .534 9z"/><path fill-rule="evenodd" d="M8 3c-1.552 0-2.94.707-3.857 1.818a.5.5 0 1 1-.771-.636A6.002 6.002 0 0 1 13.917 7H12.9A5.002 5.002 0 0 0 8 3zM3.1 9a5.002 5.002 0 0 0 8.757 2.182.5.5 0 1 1 .771.636A6.002 6.002 0 0 1 2.083 9H3.1z"/></svg> Generating...';
const response = await fetch(`https://api.api-ninjas.com/v1/passwordgenerator?length=${length}`, {
headers: {
'X-Api-Key': 'iwnxiYFzuzAJmIITJnZpsg==kTvKp8ELZ8YI6mZ9'
}
});
if (!response.ok) {
throw new Error('API request failed');
}
const data = await response.json();
displayPassword(data.random_password);
showNotification('Password generated using secure API');
} catch (error) {
console.error('Error generating password with API:', error);
showNotification('API failed, generating locally', 'error');
// Fallback to local generation
const useUppercase = uppercaseCheckbox.checked;
const useLowercase = lowercaseCheckbox.checked;
const useNumbers = numbersCheckbox.checked;
const useSymbols = symbolsCheckbox.checked;
generatePasswordLocally(length, useUppercase, useLowercase, useNumbers, useSymbols);
} finally {
generateBtn.disabled = false;
generateBtn.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"><path d="M8 4.754a3.246 3.246 0 1 0 0 6.492 3.246 3.246 0 0 0 0-6.492zM5.754 8a2.246 2.246 0 1 1 4.492 0 2.246 2.246 0 0 1-4.492 0z"/><path d="M9.796 1.343c-.527-1.79-3.065-1.79-3.592 0l-.094.319a.873.873 0 0 1-1.255.52l-.292-.16c-1.64-.892-3.433.902-2.54 2.541l.159.292a.873.873 0 0 1-.52 1.255l-.319.094c-1.79.527-1.79 3.065 0 3.592l.319.094a.873.873 0 0 1 .52 1.255l-.16.292c-.892 1.64.901 3.434 2.541 2.54l.292-.159a.873.873 0 0 1 1.255.52l.094.319c.527 1.79 3.065 1.79 3.592 0l.094-.319a.873.873 0 0 1 1.255-.52l.292.16c1.64.893 3.434-.902 2.54-2.541l-.159-.292a.873.873 0 0 1 .52-1.255l.319-.094c1.79-.527 1.79-3.065 0-3.592l-.319-.094a.873.873 0 0 1-.52-1.255l.16-.292c.893-1.64-.902-3.433-2.541-2.54l-.292.159a.873.873 0 0 1-1.255-.52l-.094-.319zm-2.633.283c.246-.835 1.428-.835 1.674 0l.094.319a1.873 1.873 0 0 0 2.693 1.115l.291-.16c.764-.415 1.6.42 1.184 1.185l-.159.292a1.873 1.873 0 0 0 1.116 2.692l.318.094c.835.246.835 1.428 0 1.674l-.319.094a1.873 1.873 0 0 0-1.115 2.693l.16.291c.415.764-.42 1.6-1.185 1.184l-.291-.159a1.873 1.873 0 0 0-2.693 1.116l-.094.318c-.246.835-1.428.835-1.674 0l-.094-.319a1.873 1.873 0 0 0-2.692-1.115l-.292.16c-.764.415-1.6-.42-1.184-1.185l.159-.291A1.873 1.873 0 0 0 1.945 8.93l-.319-.094c-.835-.246-.835-1.428 0-1.674l.319-.094A1.873 1.873 0 0 0 3.06 4.377l-.16-.292c-.415-.764.42-1.6 1.185-1.184l.292.159a1.873 1.873 0 0 0 2.692-1.115l.094-.319z"/></svg> Generate Password';
}
}
// Display password and update strength
function displayPassword(password) {
passwordOutput.innerHTML = password;
updatePasswordStrength(password);
}
// Update password strength indicator
function updatePasswordStrength(password) {
let strength = 0;
const length = password.length;
// Length factor
if (length >= 8) strength += 1;
if (length >= 12) strength += 1;
if (length >= 16) strength += 1;
if (length >= 20) strength += 1;
// Character variety factor
const hasLowercase = /[a-z]/.test(password);
const hasUppercase = /[A-Z]/.test(password);
const hasNumbers = /[0-9]/.test(password);
const hasSymbols = /[^a-zA-Z0-9]/.test(password);
const varietyCount = [hasLowercase, hasUppercase, hasNumbers, hasSymbols].filter(Boolean).length;
strength += varietyCount;
// Update UI
strengthFill.className = 'strength-fill';
if (strength <= 2) {
strengthFill.classList.add('strength-weak');
strengthText.textContent = 'Weak Password';
strengthText.style.color = '#f72585';
} else if (strength <= 4) {
strengthFill.classList.add('strength-fair');
strengthText.textContent = 'Fair Password';
strengthText.style.color = '#ff9e00';
} else if (strength <= 6) {
strengthFill.classList.add('strength-good');
strengthText.textContent = 'Good Password';
strengthText.style.color = '#ffd166';
} else {
strengthFill.classList.add('strength-strong');
strengthText.textContent = 'Strong Password';
strengthText.style.color = '#4cc9f0';
}
}
// Copy password to clipboard
function copyPassword() {
const password = passwordOutput.textContent;
if (!password || password === 'Your password will appear here') {
showNotification('No password to copy', 'error');
return;
}
navigator.clipboard.writeText(password).then(() => {
showNotification('Password copied to clipboard!');
}).catch(err => {
console.error('Failed to copy password: ', err);
showNotification('Failed to copy password', 'error');
});
}
// Save password (simulated - in a real app, this would save to a secure location)
function savePassword() {
const password = passwordOutput.textContent;
if (!password || password === 'Your password will appear here') {
showNotification('No password to save', 'error');
return;
}
// In a real application, this would save to a secure password manager
// For this demo, we'll just show a notification
showNotification('Password saved (simulated action)');
}
// Clear password
function clearPassword() {
passwordOutput.innerHTML = '<span class="password-placeholder">Your password will appear here</span>';
strengthFill.className = 'strength-fill';
strengthText.textContent = 'Generate a password to see strength';
strengthText.style.color = '';
}
// Show notification
function showNotification(message, type = 'success') {
notification.textContent = message;
notification.className = 'notification';
if (type === 'error') {
notification.style.background = '#f72585';
} else {
notification.style.background = '#4cc9f0';
}
notification.classList.add('show');
setTimeout(() => {
notification.classList.remove('show');
}, 3000);
}
// Event listeners
generateBtn.addEventListener('click', generatePassword);
copyBtn.addEventListener('click', copyPassword);
https://youtu.be/GmUxQcZNYnE?si=bBlV5SgnHLhdS0Nx('click', savePassword);
clearBtn.addEventListener('click', clearPassword);
// Generate a password on page load
window.addEventListener('load', generatePassword);
</script>
</body>
</html>
