Percent to molarity · basis workbench — Choose the correct supplied density type and molar mass to convert a declared percentage concentration to molarity, with unit cancellation…
HTML for this example
Select the code and use your copy shortcut. Changes in this preview are temporary.
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Percent to molarity · basis workbench</title><style>
*{box-sizing:border-box}body{margin:0;background:#eef8f8;color:#163e49;font:16px/1.5 system-ui,sans-serif}main{max-width:1080px;margin:auto;padding:30px}h1{font-size:clamp(29px,4vw,43px);letter-spacing:-.04em;line-height:1.15;margin:7px 0 10px}h2{font-size:22px;margin:0 0 14px}p{margin:0 0 12px}.eyebrow{font-size:12px;font-weight:750;letter-spacing:.13em;text-transform:uppercase;color:#467780}.small{font-size:14px;color:#52717a}.workspace{display:grid;grid-template-columns:1fr 1fr;gap:0;margin-top:24px;border:1px solid #c4dedf;border-radius:17px;overflow:hidden;background:white}.answer{padding:28px;background:#124f5c;color:white}.answer .eyebrow{color:#acdee1}.value{font-size:68px;font-weight:750;letter-spacing:-.06em;line-height:1.15;margin:10px 0}.trace{border-top:1px solid #ffffff33;margin-top:22px;padding-top:18px}.trace p{font-size:17px}.trace b{color:#beeef0}.controls{padding:26px}.buttons{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:18px}button{font:700 14px system-ui;min-height:44px;padding:10px 17px;background:#167789;color:white;border:1px solid #167789;border-radius:7px;cursor:pointer}button.secondary{background:#fff;color:#166374}button[aria-pressed=true]{background:#124f5c;color:white}button:disabled{opacity:.5;cursor:default}:focus-visible{outline:3px solid #c77526;outline-offset:3px}label{font-size:14px;font-weight:650;display:block}input,select{font:16px/1.4 system-ui;display:block;width:100%;padding:10px;border:1px solid #96b9be;background:white;color:#163e49;border-radius:6px;margin:5px 0 15px}.pair{display:grid;grid-template-columns:1fr 1fr;gap:16px}.check{display:flex;align-items:flex-start;gap:9px;font-size:13px;font-weight:500}.check input{width:20px;height:20px;flex-shrink:0;margin:1px 0 0}.density{border-top:1px solid #d8e7e8;padding-top:15px;margin-top:8px}.error{color:#a42f2f;min-height:24px;font-size:14px;margin-top:14px}.comparison{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-top:23px}.case{padding:19px;background:#fff;border:1px solid #c4dedf;border-radius:10px}.case strong{font-size:31px;display:block;margin:8px 0}.case p{font-size:13px}.case button{width:100%;margin-top:5px}.lower{margin:27px 0;font-size:14px;color:#52717a;max-width:85ch}details{margin-top:22px;border-top:1px solid #c4dedf;padding-top:18px}summary{cursor:pointer;font-weight:700;min-height:44px}pre{font:13px/1.6 ui-monospace,Consolas,monospace;white-space:pre-wrap;overflow-wrap:anywhere}[hidden]{display:none!important}@media(max-width:730px){main{padding:23px 17px}.workspace{grid-template-columns:1fr}.answer,.controls{padding:22px}.value{font-size:59px}.comparison{grid-template-columns:1fr}.case{display:grid;grid-template-columns:1fr 1fr;gap:5px 15px}.case button{grid-column:1/-1}.case strong{margin:0;text-align:right}.case p{grid-column:1/-1}}@media(max-width:380px){main{padding:20px 12px}.pair{grid-template-columns:1fr}.buttons button{flex:1;padding:10px}}
</style></head><body><main><p class="eyebrow">Concentration workbench · fictional solute S</p><h1>Which percentage? Which density?</h1><p>Trace solute mass per liter, then divide by the supplied molar mass.</p><section class="workspace"><div class="answer"><p id="basis-label" class="eyebrow">w/v · grams per 100 mL solution</p><div id="result" class="value" role="status">0.8 M</div><p id="result-note">4% w/v · 50 g/mol · no density needed</p><div id="trace" class="trace"><p id="step-one">4 g S / 100 mL solution × 1000 mL/L = 40 g S/L</p><p id="step-two">40 g S/L ÷ 50 g S/mol = 0.8 mol/L</p><p id="property-trace">C1 · supplied fictional arithmetic inputs</p></div></div><div class="controls"><div class="buttons"><button id="wv" type="button" aria-pressed="true">w/v</button><button id="ww" type="button" class="secondary" aria-pressed="false">w/w</button><button id="vv" type="button" class="secondary" aria-pressed="false">v/v</button></div><div class="pair"><label for="percent">Percent number · 4 means 4%<input id="percent" value="4" inputmode="decimal"></label><label for="mass">Molar mass · g/mol<input id="mass" value="50" inputmode="decimal"></label></div><label for="representation">Input representation<select id="representation"><option value="percent">Percent number</option><option value="fraction">Fraction representation · unsupported</option></select></label><div id="density-fields" class="density" hidden><p id="density-instruction" class="small"></p><label for="density">Density · g/mL<input id="density" inputmode="decimal"></label><div class="pair"><label for="role">Supplied density describes<select id="role"><option value="">Not supplied</option><option value="solution">Solution</option><option value="solute">Solute</option></select></label><label for="state">Matching fictional record<select id="state"><option value="">Not supplied</option><option value="C2">C2</option><option value="C3">C3</option></select></label></div><label class="check" for="confirmed"><input id="confirmed" type="checkbox">The supplied property has the correct role and matches this case's declared state.</label></div><div class="buttons" style="margin:18px 0 0"><button id="calculate" type="button">Calculate</button><button id="reset" type="button" class="secondary">Reset</button></div><p id="error" class="error" role="alert"></p></div></section><section class="comparison" aria-label="Separate original worked records"><div class="case"><span>C1 · 4% w/v</span><strong>0.8 M</strong><p>40 g S/L ÷ 50 g/mol. No density.</p><button id="load-c1" type="button" class="secondary">Load C1</button></div><div class="case"><span>C2 · 4% w/w</span><strong>1 M</strong><p>Solution density 1.25 g/mL · C2 state.<br>1250 g solution/L → 50 g S/L.</p><button id="load-c2" type="button" class="secondary">Load C2</button></div><div class="case"><span>C3 · 4% v/v</span><strong>0.6 M</strong><p>Solute density 0.75 g/mL · C3 state.<br>40 mL S/L → 30 g S/L.</p><button id="load-c3" type="button" class="secondary">Load C3</button></div></section><div class="lower"><p>All S properties are authored arithmetic inputs, not real chemical data. C2 and C3 are separate fictional matching states. Actual property source, temperature, and measured state are not supplied.</p><p>A basis change clears the density, role, state confirmation, and current result. Reset restores w/v, 4, and 50 with the result pending; the worked records stay visible. Entering 0.04 in the percent-number field means 0.04%, not 4%.</p><p>Zero percentage is known data; blank is not zero. This helper bounds w/w and v/v at 0–100%, while w/v has no blanket 100 cap. Valid arithmetic does not establish physical feasibility, a preparation method, material suitability, measurement precision, or molality. No substance lookup, native workbook export, saved inputs, or laboratory procedure is provided.</p></div><details><summary>Raw arithmetic for the current valid result</summary><pre id="raw">massPerLiter = 40; molarity = 0.8</pre><p class="small">Display rounding is limited to 10 significant digits for readability. Raw JavaScript numbers are shown above; this is not a significant-figure or uncertainty determination.</p></details></main><script>
'use strict';const $=id=>document.getElementById(id);let basis='wv';const descriptions={wv:'w/v · grams per 100 mL solution',ww:'w/w · grams per 100 g solution',vv:'v/v · mL solute per 100 mL solution'};const fmt=n=>String(Number(n.toPrecision(10)));
function value(raw){const s=String(raw).trim();return s!==''&&/^[+]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?$/i.test(s)&&Number.isFinite(Number(s))?Number(s):null;}
function evaluate(v){const errors=[],p=value(v.percent),mass=value(v.mass),rho=value(v.density);if(!['wv','ww','vv'].includes(v.basis))errors.push('Choose a supported percentage basis.');if(v.representation!=='percent')errors.push('Fraction representation is unsupported. Enter a percent number; no conversion has been guessed.');if(p===null||p<0||(v.basis!=='wv'&&p>100))errors.push('Enter a finite nonnegative percent number'+(v.basis==='wv'?'.':' from 0 to 100.'));if(mass===null||mass<=0)errors.push('Molar mass must be positive and finite.');if(v.basis!=='wv'){if(rho===null||rho<=0)errors.push('Supply a positive finite density in g/mL.');const role=v.basis==='ww'?'solution':'solute',state=v.basis==='ww'?'C2':'C3';if(v.role!==role)errors.push('This basis requires '+role+' density.');if(v.state!==state||!v.confirmed)errors.push('Confirm the supplied density matches the '+state+' state.');}if(errors.length)return{errors};const grams=p*10*(v.basis==='wv'?1:rho),molarity=grams/mass;if(!Number.isFinite(grams)||!Number.isFinite(molarity))return{errors:['The numeric range overflows this helper. Use finite representable inputs.']};return{errors,grams,molarity,p,mass,rho};}
function collect(){return{basis,percent:$('percent').value,mass:$('mass').value,density:$('density').value,role:$('role').value,state:$('state').value,confirmed:$('confirmed').checked,representation:$('representation').value};}
function pending(){$('result').textContent='Pending';$('result-note').textContent='Calculate after the current input contract is complete.';$('trace').hidden=true;$('step-one').textContent=$('step-two').textContent=$('property-trace').textContent='';$('raw').textContent='No current accepted calculation.';$('error').textContent=evaluate(collect()).errors.join(' ');}
function choose(next){basis=next;for(const id of['density','role','state'])$(id).value='';$('confirmed').checked=false;$('density-fields').hidden=basis==='wv';$('basis-label').textContent=descriptions[basis];$('density-instruction').textContent=basis==='ww'?'Use solution density for the supplied C2 state.':'Use solute density for the supplied C3 state.';for(const id of['wv','ww','vv'])$(id).setAttribute('aria-pressed',String(id===basis));pending();}
function calculate(){pending();const r=evaluate(collect());if(r.errors.length)return;$('result').textContent=fmt(r.molarity)+' M';$('result-note').textContent=fmt(r.p)+'% '+basis[0]+'/'+basis[1]+' · '+fmt(r.mass)+' g/mol'+(basis==='wv'?' · no density needed':'');$('trace').hidden=false;$('step-one').textContent=basis==='wv'?fmt(r.p)+' g S / 100 mL solution × 1000 mL/L = '+fmt(r.grams)+' g S/L':basis==='ww'?fmt(r.rho*1000)+' g solution/L × '+fmt(r.p)+'/100 = '+fmt(r.grams)+' g S/L':fmt(r.p*10)+' mL S/L × '+fmt(r.rho)+' g S/mL S = '+fmt(r.grams)+' g S/L';$('step-two').textContent=fmt(r.grams)+' g S/L ÷ '+fmt(r.mass)+' g S/mol = '+fmt(r.molarity)+' mol/L';$('property-trace').textContent=basis==='wv'?'Current w/v inputs · no density used':(basis==='ww'?'C2 · solution density':'C3 · solute density')+' · supplied matching fictional state';$('raw').textContent='massPerLiter = '+r.grams+'; molarity = '+r.molarity;}
function load(caseId){choose(caseId==='C1'?'wv':caseId==='C2'?'ww':'vv');$('percent').value='4';$('mass').value='50';$('representation').value='percent';if(caseId!=='C1'){$('density').value=caseId==='C2'?'1.25':'0.75';$('role').value=caseId==='C2'?'solution':'solute';$('state').value=caseId;$('confirmed').checked=true;}calculate();}
for(const id of['wv','ww','vv'])$(id).addEventListener('click',()=>choose(id));for(const id of['percent','mass','density','role','state','confirmed','representation']){$(id).addEventListener('input',pending);$(id).addEventListener('change',pending);}for(const c of['c1','c2','c3'])$('load-'+c).addEventListener('click',()=>load(c.toUpperCase()));$('calculate').addEventListener('click',calculate);$('reset').addEventListener('click',()=>{choose('wv');$('percent').value='4';$('mass').value='50';$('representation').value='percent';pending();});for(const id of['percent','mass','density'])$(id).addEventListener('keydown',e=>{if(e.key==='Enter'&&!e.isComposing&&!e.repeat){e.preventDefault();calculate();}});calculate();
</script></body></html>