Dihybrid Cross Calculator – Punnett Square

#dihybrid-cross-calculator { max-width: 600px; margin: 20px auto; padding: 15px; background: #fff; border-radius: 5px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); font-family: -apple-system, BlinkMacSystemFont, ‘Arial’, sans-serif; color: #333; box-sizing: border-box; } h2 { text-align: center; margin: 0 0 15px; font-size: 1.4rem; line-height: 1.2; color: #333; } p { text-align: center; color: #666; font-size: 14px; margin-bottom: 15px; } .form-group { margin-bottom: 15px; position: relative; } label { display: block; margin-bottom: 5px; font-size: 0.9rem; font-weight: 600; } select { width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 3px; font-size: 0.9rem; box-sizing: border-box; } select:focus { border-color: #0073aa; outline: none; } .tooltip { position: relative; display: inline-block; margin-left: 5px; } .tooltip .tooltip-text { visibility: hidden; width: 180px; background: #333; color: #fff; text-align: center; border-radius: 3px; padding: 5px; position: absolute; z-index: 10; bottom: 125%; left: 50%; transform: translateX(-50%); opacity: 0; transition: opacity 0.3s; font-size: 0.75rem; } .tooltip:hover .tooltip-text { visibility: visible; opacity: 1; } .button-group { display: flex; gap: 10px; justify-content: center; margin-top: 15px; } button { padding: 8px 16px; border: none; border-radius: 3px; cursor: pointer; font-size: 0.9rem; background: #0073aa; color: #fff; } button:hover { background: #005177; } #reset-btn { background: #6c757d; } #reset-btn:hover { background: #5a6268; } #result { margin-top: 15px; padding: 10px; border-radius: 3px; font-size: 0.9rem; line-height: 1.4; min-height: 20px; } #result.success { background: #e6f4ea; border: 1px solid #28a745; } #result.error { background: #f8d7da; border: 1px solid #dc3545; } .punnett-table { width: 100%; border-collapse: collapse; margin-top: 10px; } .punnett-table th, .punnett-table td { padding: 8px; border: 1px solid #ddd; text-align: center; font-size: 0.85rem; } .punnett-table th { background: #f8f9fa; font-weight: 600; } .punnett-table td { background: #fff; } .ratio-table { width: 100%; border-collapse: collapse; margin-top: 10px; } .ratio-table th, .ratio-table td { padding: 8px; border: 1px solid #ddd; text-align: left; font-size: 0.85rem; } .ratio-table th { background: #f8f9fa; font-weight: 600; } noscript { display: block; color: #dc3545; text-align: center; margin-top: 10px; font-size: 0.9rem; } @media (max-width: 600px) { #dihybrid-cross-calculator { margin: 10px; padding: 10px; } h2 { font-size: 1.2rem; } .button-group { flex-direction: column; } button { width: 100%; } .punnett-table th, .punnett-table td { font-size: 0.7rem; padding: 4px; } .ratio-table th, .ratio-table td { font-size: 0.8rem; padding: 6px; } }

Dihybrid Cross Punnett Square Calculator

Calculate genotype and phenotype ratios for a dihybrid cross.

AA (Homozygous Dominant) Aa (Heterozygous) aa (Homozygous Recessive)
BB (Homozygous Dominant) Bb (Heterozygous) bb (Homozygous Recessive)
AA (Homozygous Dominant) Aa (Heterozygous) aa (Homozygous Recessive)
BB (Homozygous Dominant) Bb (Heterozygous) bb (Homozygous Recessive)
JavaScript is disabled. Please enable it to use the calculator. (function() { if (!document.getElementById(‘dihybrid-cross-calculator’)) return; const form = document.getElementById(‘calc-form’); const parent1Trait1Select = document.getElementById(‘parent1-trait1’); const parent1Trait2Select = document.getElementById(‘parent1-trait2’); const parent2Trait1Select = document.getElementById(‘parent2-trait1’); const parent2Trait2Select = document.getElementById(‘parent2-trait2’); const resultDiv = document.getElementById(‘result’); function getGametes(genotype) { const alleles = genotype.split(”); return alleles.length === 2 ? alleles : [alleles[0]]; } function combineTraits(trait1, trait2) { const result = []; for (let a1 of trait1) { for (let a2 of trait2) { result.push(a1 + a2); } } return result.sort(); } function getSortedGenotype(gamete1, gamete2) { const trait1 = [gamete1[0], gamete2[0]].sort().join(”); const trait2 = [gamete1[1], gamete2[1]].sort().join(”); return trait1 + trait2; } function getPhenotype(genotype) { const trait1 = genotype.slice(0, 2); const trait2 = genotype.slice(2, 4); const pheno1 = /[A]/.test(trait1) ? ‘Dominant A’ : ‘Recessive a’; const pheno2 = /[B]/.test(trait2) ? ‘Dominant B’ : ‘Recessive b’; return `${pheno1}, ${pheno2}`; } function calculate() { resultDiv.className = ”; resultDiv.innerHTML = ”; try { const parent1Trait1 = parent1Trait1Select.value; const parent1Trait2 = parent1Trait2Select.value; const parent2Trait1 = parent2Trait1Select.value; const parent2Trait2 = parent2Trait2Select.value; if (!parent1Trait1 || !parent1Trait2 || !parent2Trait1 || !parent2Trait2) { throw new Error(‘Please select all genotypes.’); } const gametes1Trait1 = getGametes(parent1Trait1); const gametes1Trait2 = getGametes(parent1Trait2); const gametes2Trait1 = getGametes(parent2Trait1); const gametes2Trait2 = getGametes(parent2Trait2); const parent1Gametes = combineTraits(gametes1Trait1, gametes1Trait2); const parent2Gametes = combineTraits(gametes2Trait1, gametes2Trait2); const genotypes = {}; const phenotypes = {}; const punnettData = []; for (let g1 of parent1Gametes) { const row = []; for (let g2 of parent2Gametes) { const genotype = getSortedGenotype(g1, g2); genotypes[genotype] = (genotypes[genotype] || 0) + 1; const phenotype = getPhenotype(genotype); phenotypes[phenotype] = (phenotypes[phenotype] || 0) + 1; row.push(genotype); } punnettData.push(row); } let tableHTML = ` `; for (let g2 of parent2Gametes) { tableHTML += ``; } tableHTML += ‘‘; for (let i = 0; i < parent1Gametes.length; i++) { tableHTML += ``; for (let genotype of punnettData[i]) { tableHTML += ``; } tableHTML += ‘‘; } tableHTML += ‘
${g2}
${parent1Gametes[i]}${genotype}
‘; const total = 16; let genotypeHTML = ` `; for (let genotype in genotypes) { genotypeHTML += ` `; } genotypeHTML += ‘
GenotypeRatio
${genotype} ${genotypes[genotype]}/${total} (${(genotypes[genotype] / total * 100).toFixed(2)}%)
‘; let phenotypeHTML = ` `; for (let phenotype in phenotypes) { phenotypeHTML += ` `; } phenotypeHTML += ‘
PhenotypeRatio
${phenotype} ${phenotypes[phenotype]}/${total} (${(phenotypes[phenotype] / total * 100).toFixed(2)}%)
‘; resultDiv.innerHTML = ` Punnett Square:
${tableHTML}
Genotype Ratios:
${genotypeHTML}
Phenotype Ratios:
${phenotypeHTML} `; resultDiv.className = ‘success’; } catch (error) { resultDiv.innerHTML = `Error: ${error.message}`; resultDiv.className = ‘error’; } } function reset() { form.reset(); resultDiv.className = ”; resultDiv.innerHTML = ‘Select genotypes, then click “Calculate”.’; parent1Trait1Select.focus(); } document.getElementById(‘calculate-btn’).addEventListener(‘click’, calculate); document.getElementById(‘reset-btn’).addEventListener(‘click’, reset); form.addEventListener(‘keypress’, function(e) { if (e.key === ‘Enter’ && e.target.tagName !== ‘BUTTON’) { e.preventDefault(); calculate(); } }); })();