Enter a chemical equation to balance it instantly using the Law of Conservation of Mass.
Use capital letters for elements (e.g., Fe, Na) and numbers for subscripts. Use '=' or '->' as the separator.
Balanced Equation:
Error:
How to Balance Chemical Equations
A balanced chemical equation occurs when the number of atoms of each element is equal on both the reactant (left) and product (right) sides of the equation. This is a fundamental requirement of the Law of Conservation of Mass, which states that matter cannot be created or destroyed in a chemical reaction.
Key Rules for Balancing
Coefficients: Only change the numbers in front of the molecules (coefficients). Never change the subscripts (the small numbers within a formula), as this would change the identity of the substance.
Inventory: Count how many atoms of each element are on each side before you start.
Complexity: It is often easiest to start balancing elements that appear in only one molecule on each side. Save Oxygen and Hydrogen for last.
Step-by-Step Example: Combustion of Methane
Let's balance the equation for methane burning in oxygen: CH4 + O2 → CO2 + H2O
Count Atoms: Left (C:1, H:4, O:2) | Right (C:1, H:2, O:3).
Balance Carbon: Carbon is already balanced (1 on each side).
Balance Hydrogen: We have 4 on the left and 2 on the right. Add a coefficient of 2 to H2O: CH4 + O2 → CO2 + 2H2O.
Balance Oxygen: Now we have 2 on the left and 4 on the right (2 from CO2 and 2 from 2H2O). Add a coefficient of 2 to O2: CH4 + 2O2 → CO2 + 2H2O.
Final Check: C:1=1, H:4=4, O:4=4. The equation is balanced!
Common Practice Equations
Unbalanced
Balanced Result
Fe + Cl2 = FeCl3
2Fe + 3Cl2 = 2FeCl3
KClO3 = KCl + O2
2KClO3 = 2KCl + 3O2
C3H8 + O2 = CO2 + H2O
C3H8 + 5O2 = 3CO2 + 4H2O
function calculateBalance() {
var input = document.getElementById('chemInput').value.trim();
var resultDiv = document.getElementById('chemResult');
var errorDiv = document.getElementById('chemError');
var outputSpan = document.getElementById('balancedOutput');
var errorMsg = document.getElementById('errorMessage');
resultDiv.style.display = 'none';
errorDiv.style.display = 'none';
if (!input) {
showError("Please enter an equation.");
return;
}
try {
var balanced = balance(input);
outputSpan.innerText = balanced;
resultDiv.style.display = 'block';
} catch (e) {
showError(e.message);
}
}
function showError(msg) {
var errorDiv = document.getElementById('chemError');
var errorMsg = document.getElementById('errorMessage');
errorMsg.innerText = msg;
errorDiv.style.display = 'block';
}
function balance(formula) {
var parts = formula.split(/=|->|→/);
if (parts.length !== 2) throw new Error("Equation must have one separator (= or ->).");
var lhs = parts[0].split('+').map(function(s) { return s.trim(); });
var rhs = parts[1].split('+').map(function(s) { return s.trim(); });
var allItems = lhs.concat(rhs);
var elements = [];
function getCounts(molecule) {
var counts = {};
var regex = /([A-Z][a-z]*)(\d*)/g;
var match;
while ((match = regex.exec(molecule)) !== null) {
var el = match[1];
var count = parseInt(match[2] || "1", 10);
counts[el] = (counts[el] || 0) + count;
if (elements.indexOf(el) === -1) elements.push(el);
}
return counts;
}
var lhsCounts = lhs.map(getCounts);
var rhsCounts = rhs.map(getCounts);
// Matrix rows = elements, cols = molecules
var matrix = [];
for (var i = 0; i < elements.length; i++) {
var row = [];
var el = elements[i];
for (var j = 0; j < lhsCounts.length; j++) row.push(lhsCounts[j][el] || 0);
for (var j = 0; j < rhsCounts.length; j++) row.push(-(rhsCounts[j][el] || 0));
matrix.push(row);
}
var coefficients = solveMatrix(matrix);
var lhsResult = "";
for (var i = 0; i < lhs.length; i++) {
var c = coefficients[i];
lhsResult += (c === 1 ? "" : c) + lhs[i] + (i < lhs.length – 1 ? " + " : "");
}
var rhsResult = "";
for (var i = 0; i < rhs.length; i++) {
var c = coefficients[i + lhs.length];
rhsResult += (c === 1 ? "" : c) + rhs[i] + (i < rhs.length – 1 ? " + " : "");
}
return lhsResult + " = " + rhsResult;
}
function solveMatrix(matrix) {
var rows = matrix.length;
var cols = matrix[0].length;
// Gaussian elimination
var pivot = 0;
for (var j = 0; j < cols && pivot < rows; j++) {
var max = pivot;
for (var i = pivot + 1; i Math.abs(matrix[max][j])) max = i;
}
var temp = matrix[pivot];
matrix[pivot] = matrix[max];
matrix[max] = temp;
if (Math.abs(matrix[pivot][j]) < 1e-10) continue;
for (var i = 0; i < rows; i++) {
if (i !== pivot) {
var factor = matrix[i][j] / matrix[pivot][j];
for (var k = j; k = 0; i–) {
var sum = 0;
for (var j = i + 1; j 1e-10) {
solution[i] = -sum / matrix[i][i];
} else {
solution[i] = 1; // Free variable
}
}
// Scale to integers
return scaleToIntegers(solution);
}
function scaleToIntegers(solution) {
var bestDenom = 1;
for (var d = 1; d <= 200; d++) {
var allInts = true;
for (var i = 0; i 1e-4) {
allInts = false;
break;
}
}
if (allInts) {
bestDenom = d;
break;
}
}
var finalCoeffs = solution.map(function(v) { return Math.round(v * bestDenom); });
// Safety check: ensure all positive
var min = Math.min.apply(null, finalCoeffs);
if (min < 0) finalCoeffs = finalCoeffs.map(function(v) { return -v; });
return finalCoeffs;
}