percentage/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Percentage Calculator</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: Helvetica, -apple-system, BlinkMacSystemFont, sans-serif;
line-height: 1.6;
color: #333;
background-color: #f5f5f5;
padding: 20px;
}
.container {
max-width: 800px;
margin: 0 auto;
}
.header {
text-align: center;
margin-bottom: 30px;
}
h1 {
font-size: 1.8rem;
font-weight: 600;
margin-bottom: 8px;
}
.subtitle {
font-size: 1rem;
color: #666;
}
.calculator-grid {
display: grid;
gap: 20px;
}
.calculator-card {
background: white;
border-radius: 8px;
padding: 24px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
.calculator-title {
font-size: 1.1rem;
font-weight: 600;
margin-bottom: 20px;
color: #222;
line-height: 1.5;
}
input[type="number"] {
padding: 10px 12px;
border: 1px solid #ddd;
border-radius: 4px;
font-family: Helvetica, sans-serif;
font-size: 16px;
width: 100px;
min-height: 44px;
transition: border-color 0.2s, box-shadow 0.2s;
}
input[type="number"]:focus {
outline: none;
border-color: #4a90d9;
box-shadow: 0 0 0 3px rgba(74, 144, 217, 0.2);
}
.result-box {
margin-top: 16px;
padding: 16px;
background-color: #f8f9fa;
border-radius: 6px;
border-left: 4px solid #4a90d9;
}
.result-sentence {
font-size: 1.1rem;
font-weight: 500;
margin-bottom: 8px;
}
.result-value {
font-weight: 700;
color: #2c5282;
}
.result-value.increase {
color: #38a169;
}
.result-value.decrease {
color: #e53e3e;
}
.result-math {
font-size: 0.9rem;
color: #666;
font-family: "Courier New", monospace;
margin-bottom: 12px;
word-break: break-all;
}
.result-actions {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.btn {
padding: 10px 16px;
border: 1px solid #ccc;
border-radius: 4px;
cursor: pointer;
font-family: Helvetica, sans-serif;
font-size: 16px;
min-height: 44px;
min-width: 44px;
transition: all 0.2s;
background: white;
color: #555;
}
.btn:hover {
background-color: #e2e8f0;
border-color: #a0aec0;
}
.btn:active {
transform: scale(0.98);
}
.btn-primary {
background-color: #4a90d9;
color: white;
border-color: #4a90d9;
}
.btn-primary:hover {
background-color: #357abd;
border-color: #357abd;
}
.error {
color: #e53e3e;
font-size: 0.9rem;
margin-top: 8px;
min-height: 1.2em;
}
@media (max-width: 600px) {
body {
padding: 16px;
}
.calculator-card {
padding: 20px;
}
input[type="number"] {
width: 80px;
padding: 8px 10px;
}
h1 {
font-size: 1.5rem;
}
.subtitle {
font-size: 0.95rem;
}
.btn {
padding: 12px 16px;
}
}
</style>
</head>
<body>
<div class="container">
<header class="header">
<h1>Percentage Calculator</h1>
<p class="subtitle">Calculate percentages, ratios, and percentage changes instantly with clear explanations.</p>
</header>
<main class="calculator-grid">
<section class="calculator-card" aria-labelledby="calc1-title">
<div class="calculator-title" id="calc1-title">What is <input type="number" id="p1-percent" placeholder="X" step="any" aria-label="Percentage value"> % of <input type="number" id="p1-value" placeholder="Y" step="any" aria-label="Base value"> ?</div>
<div class="result-box">
<div class="result-sentence" id="p1-sentence">Enter values to calculate</div>
<div class="result-math" id="p1-math" aria-live="polite"></div>
<div class="result-actions">
<button class="btn btn-primary" onclick="copyToClipboard('p1-sentence')">Copy Result</button>
<button class="btn" onclick="clearCalculator(1)">Clear</button>
</div>
</div>
<div class="error" id="p1-error" role="alert"></div>
</section>
<section class="calculator-card" aria-labelledby="calc2-title">
<div class="calculator-title" id="calc2-title"><input type="number" id="p2-part" placeholder="X" step="any" aria-label="Part value"> is what percent of <input type="number" id="p2-whole" placeholder="Y" step="any" aria-label="Whole value"> ?</div>
<div class="result-box">
<div class="result-sentence" id="p2-sentence">Enter values to calculate</div>
<div class="result-math" id="p2-math" aria-live="polite"></div>
<div class="result-actions">
<button class="btn btn-primary" onclick="copyToClipboard('p2-sentence')">Copy Result</button>
<button class="btn" onclick="clearCalculator(2)">Clear</button>
</div>
</div>
<div class="error" id="p2-error" role="alert"></div>
</section>
<section class="calculator-card" aria-labelledby="calc3-title">
<div class="calculator-title" id="calc3-title">What is the percentage increase/decrease<br>from <input type="number" id="p3-from" placeholder="X" step="any" aria-label="Original value"> to <input type="number" id="p3-to" placeholder="Y" step="any" aria-label="New value"> ?</div>
<div class="result-box">
<div class="result-sentence" id="p3-sentence">Enter values to calculate</div>
<div class="result-math" id="p3-math" aria-live="polite"></div>
<div class="result-actions">
<button class="btn btn-primary" onclick="copyToClipboard('p3-sentence')">Copy Result</button>
<button class="btn" onclick="clearCalculator(3)">Clear</button>
</div>
</div>
<div class="error" id="p3-error" role="alert"></div>
</section>
</main>
</div>
<script type="module">
function formatNumber(num) {
if (!isFinite(num) || isNaN(num)) return null;
return Math.round(num * 100) / 100;
}
function showError(elementId, message) {
document.getElementById(elementId).textContent = message;
}
function clearError(elementId) {
document.getElementById(elementId).textContent = '';
}
function calculate1() {
const percent = parseFloat(document.getElementById('p1-percent').value);
const value = parseFloat(document.getElementById('p1-value').value);
const sentenceEl = document.getElementById('p1-sentence');
const mathEl = document.getElementById('p1-math');
clearError('p1-error');
if (isNaN(percent) || isNaN(value)) {
sentenceEl.textContent = 'Enter values to calculate';
sentenceEl.className = 'result-sentence';
mathEl.textContent = '';
return;
}
const result = formatNumber(value * (percent / 100));
sentenceEl.innerHTML = `<span class="result-value">${percent}%</span> of <span class="result-value">${value}</span> is <span class="result-value">${result}</span>`;
sentenceEl.className = 'result-sentence';
mathEl.textContent = `${value} × (${percent} / 100) = ${result}`;
}
function calculate2() {
const part = parseFloat(document.getElementById('p2-part').value);
const whole = parseFloat(document.getElementById('p2-whole').value);
const sentenceEl = document.getElementById('p2-sentence');
const mathEl = document.getElementById('p2-math');
clearError('p2-error');
if (isNaN(part) || isNaN(whole)) {
sentenceEl.textContent = 'Enter values to calculate';
sentenceEl.className = 'result-sentence';
mathEl.textContent = '';
return;
}
if (whole === 0) {
sentenceEl.textContent = 'Cannot calculate percentage of zero';
sentenceEl.className = 'result-sentence';
mathEl.textContent = '';
showError('p2-error', 'Division by zero is undefined');
return;
}
const result = formatNumber((part / whole) * 100);
sentenceEl.innerHTML = `<span class="result-value">${part}</span> is <span class="result-value">${result}%</span> of <span class="result-value">${whole}</span>`;
sentenceEl.className = 'result-sentence';
mathEl.textContent = `(${part} / ${whole}) × 100 = ${result}%`;
}
function calculate3() {
const from = parseFloat(document.getElementById('p3-from').value);
const to = parseFloat(document.getElementById('p3-to').value);
const sentenceEl = document.getElementById('p3-sentence');
const mathEl = document.getElementById('p3-math');
clearError('p3-error');
if (isNaN(from) || isNaN(to)) {
sentenceEl.textContent = 'Enter values to calculate';
sentenceEl.className = 'result-sentence';
mathEl.textContent = '';
return;
}
if (from === 0) {
sentenceEl.textContent = 'Cannot calculate change from zero';
sentenceEl.className = 'result-sentence';
mathEl.textContent = '';
showError('p3-error', 'Division by zero is undefined');
return;
}
const result = formatNumber(((to - from) / Math.abs(from)) * 100);
const changeType = result > 0 ? 'increase' : result < 0 ? 'decrease' : 'change';
const resultClass = result > 0 ? 'increase' : result < 0 ? 'decrease' : '';
sentenceEl.innerHTML = `From <span class="result-value">${from}</span> to <span class="result-value">${to}</span> is a <span class="result-value ${resultClass}">${Math.abs(result)}%</span> ${changeType}`;
sentenceEl.className = 'result-sentence';
mathEl.textContent = `((${to} - ${from}) / |${from}|) × 100 = ${result}%`;
}
function copyToClipboard(elementId) {
const el = document.getElementById(elementId);
const text = el.textContent;
if (text && text !== 'Enter values to calculate' && text !== 'Cannot calculate percentage of zero' && text !== 'Cannot calculate change from zero') {
navigator.clipboard.writeText(text).then(() => {
const btn = event.target;
const originalText = btn.textContent;
btn.textContent = 'Copied!';
setTimeout(() => {
btn.textContent = originalText;
}, 1500);
}).catch(() => {});
}
}
function clearCalculator(calcNum) {
if (calcNum === 1) {
document.getElementById('p1-percent').value = '';
document.getElementById('p1-value').value = '';
document.getElementById('p1-sentence').textContent = 'Enter values to calculate';
document.getElementById('p1-sentence').className = 'result-sentence';
document.getElementById('p1-math').textContent = '';
clearError('p1-error');
} else if (calcNum === 2) {
document.getElementById('p2-part').value = '';
document.getElementById('p2-whole').value = '';
document.getElementById('p2-sentence').textContent = 'Enter values to calculate';
document.getElementById('p2-sentence').className = 'result-sentence';
document.getElementById('p2-math').textContent = '';
clearError('p2-error');
} else if (calcNum === 3) {
document.getElementById('p3-from').value = '';
document.getElementById('p3-to').value = '';
document.getElementById('p3-sentence').textContent = 'Enter values to calculate';
document.getElementById('p3-sentence').className = 'result-sentence';
document.getElementById('p3-math').textContent = '';
clearError('p3-error');
}
}
document.getElementById('p1-percent').addEventListener('input', calculate1);
document.getElementById('p1-value').addEventListener('input', calculate1);
document.getElementById('p2-part').addEventListener('input', calculate2);
document.getElementById('p2-whole').addEventListener('input', calculate2);
document.getElementById('p3-from').addEventListener('input', calculate3);
document.getElementById('p3-to').addEventListener('input', calculate3);
</script>
</body>
</html>