Простой калькулятор на HTML, CSS и JavaScript

Кратко
Этот урок показывает, как сделать простой калькулятор на HTML, CSS и JavaScript. Вы получите готовую структуру, стили и код функций (очистка, ввод, вычисление). В разделе дополнений — идеи улучшений, альтернативы eval(), критерии приёмки и тесты.
Лучший способ выучить JavaScript — собирать проекты. Если вы хотите стать хорошим веб‑разработчиком, начните создавать проекты как можно раньше. На этом примере вы реализуете базовый калькулятор, который выполняет сложение, вычитание, умножение и деление, поддерживает десятичные числа и имеет кнопку очистки.
Что делает этот калькулятор
- Выполняет базовые арифметические операции: сложение (+), вычитание (-), умножение (*) и деление (/).
- Поддерживает десятичные числа.
- При делении на ноль будет отображать “Infinity” (поведение JavaScript по умолчанию).
- При неверном выражении (например,
5++9) результат не отображается — выражение остаётся некорректным. - Есть кнопка очистки для мгновенного сброса поля.
Код проекта доступен в репозитории GitHub и обычно распространяется под MIT‑лицензией; также можно посмотреть живую демонстрацию.
Компоненты калькулятора
- Математические операторы: +, -, *, /
- Цифры и точка: 0–9, .
- Экран (display): показывает текущее выражение и результат
- Кнопка очистки: стирает всё содержимое
- Кнопка “=”: вычисляет выражение

Структура папок проекта
Создайте корневую папку (в примере — Calculator) и поместите в неё три файла: индекс, стили и скрипт. Рекомендуемые имена: index.html, styles.css, script.js.

HTML: разметка калькулятора
Откройте index.html и вставьте следующий HTML-код:
Simple Calculator using HTML, CSS and JavaScript

CSS: стили калькулятора
Откройте styles.css и вставьте этот код для базовой стилизации внешнего вида:
@import url('https://fonts.googleapis.com/css2?family=Orbitron&display=swap');
.calculator {
padding: 10px;
border-radius: 1em;
height: 380px;
width: 400px;
margin: auto;
background-color: #191b28;
box-shadow: rgba(0, 0, 0, 0.19) 0px 10px 20px, rgba(0, 0, 0, 0.23) 0px 6px 6px;
}
.display-box {
font-family: 'Orbitron', sans-serif;
background-color: #dcdbe1;
border: solid black 0.5px;
color: black;
border-radius: 5px;
width: 100%;
height: 65%;
}
#btn {
background-color: #fb0066;
}
input[type=button] {
font-family: 'Orbitron', sans-serif;
background-color: #64278f;
color: white;
border: solid black 0.5px;
width: 100%;
border-radius: 5px;
height: 70%;
outline: none;
}
input:active[type=button] {
background: #e5e5e5;
-webkit-box-shadow: inset 0px 0px 5px #c1c1c1;
-moz-box-shadow: inset 0px 0px 5px #c1c1c1;
box-shadow: inset 0px 0px 5px #c1c1c1;
}Коротко: .calculator задаёт контейнер, .display-box — стиль экрана. @import подключает шрифт Orbitron.
JavaScript: функциональность
Откройте script.js и добавьте функции: очистка, ввод символов и вычисление выражения:
// This function clears all the values
function clearScreen() {
document.getElementById("result").value = "";
}
// This function displays the values
function display(value) {
document.getElementById("result").value += value;
}
// This function evaluates the expression and returns the result
function calculate() {
var p = document.getElementById("result").value;
var q = eval(p);
document.getElementById("result").value = q;
}Важно: в примере используется eval(). Это просто и работает для учебных задач, но у него есть ограничения и риски — см. раздел “Безопасность и альтернативы”.
Пояснение к JavaScript-коду
Очистка значения
clearScreen() берёт элемент по id result и устанавливает пустую строку.
function clearScreen() {
document.getElementById("result").value = "";
}Отображение значений
display(value) добавляет к текущей строке значение нажатой кнопки.
function display(value) {
document.getElementById("result").value += value;
}Вычисление выражения
calculate() берёт текущее выражение и передаёт его в eval(), затем результат отображается в поле.
function calculate() {
var p = document.getElementById("result").value;
var q = eval(p);
document.getElementById("result").value = q;
}Определение: eval() — встроенная функция JavaScript, которая выполняет строку как код и возвращает результат.
Когда этот подход не подходит
Важно понимать ограничения учебной реализации:
- Безопасность:
eval()выполняет любую строку, поэтому нельзя передавать выражения от ненадёжных источников. - Ограниченная валидность ввода: выражения типа
5++9приводят к ошибкам выполнения или некорректному поведению. - Локализация отображения чисел: формат десятичной точки и разделителей зависит от локали; здесь используется точка
.. - Нет истории вычислений, нет приоритета операций вне стандартного поведения JavaScript (операции выполняются согласно JS), нет обработки длинных чисел, переполнений и округлений.
Альтернативные подходы
- Использовать парсер математических выражений (например, библиотека mathjs), чтобы безопасно разбирать и вычислять выражение.
- Реализовать собственный парсер с использованием алгоритма «обратная польская нотация» (Shunting‑Yard) и стека — безопасно и даёт контроль над ошибками.
- Использовать Web Worker для тяжёлых вычислений, чтобы не блокировать UI.
- Ограничить допустимые символы и проверять регулярными выражениями перед вычислением.
Мини‑методология разработки (быстрый план)
- Создать структуру HTML и базовые кнопки.
- Подключить CSS и настроить доступность (атрибуты aria, фокус).
- Имплементировать display/clear/calculate с
eval()как PoC. - Написать набор тестов и тестовые выражения.
- Заменить
eval()на безопасный вычислитель (парсер или библиотека). - Добавить расширения: клавиатурный ввод, история, копирование результата.
Критерии приёмки
- Интерфейс показывает нажатые символы и результат после
=. - Кнопка
Cполностью очищает поле. - Поддержка десятичных чисел (
3.14 + 2.86 = 6). - Деление на ноль даёт
Infinity(поведение JavaScript) или другое понятное сообщение при ручной обработке. - Неправильные выражения не приводят к падению страницы; вместо этого показывается пустое поле или сообщение об ошибке.
Чек‑лист для ролей
Для начинающего разработчика
- Разметка соответствует макету
- Кнопки корректно вставляют символы
- [ ] Кнопка
=вычисляет выражение - [ ] Кнопка
Cочищает экран
Для ревьюера кода
- [ ] Нет незадокументированного использования
eval()в продакшн-ветке - Есть тесты на граничные случаи
- Есть обработка неверного ввода
Для QA
- Проверить простые выражения
- Проверить десятичные вычисления
- Проверить деление на ноль
- Проверить ввод с клавиатуры
Тестовые случаи
- 1+1 = 2
- 5-2 = 3
- 4*2 = 8
- 9/3 = 3
- 3.5+2.1 = 5.6
- 1/0 -> Infinity (или альтернативный текст об ошибке)
- Некорректное выражение, например
5++9-> не показывать результат, либо показывать сообщение об ошибке
Безопасность и уязвимости
Важно: использование eval() опасно, если выражение формируется из вводимых пользователем данных и затем отправляется на исполнение в контексте страницы. Возможные риски:
- Выполнение произвольного JavaScript‑кода при вводе вредоносной строки.
- XSS‑уязвимости, если результат затем вставляется в DOM без экранирования.
Митигаторы:
- Не используйте
eval()в продакшн‑коде. Замените на парсер выражений или библиотеку. - Фильтруйте допустимые символы (цифры, пробелы, +-*/.()) и отклоняйте всё остальное.
- Минимизируйте привилегии кода, не храните конфиденциальные данные в глобальной области, где код eval мог бы их прочесть.
Шпаргалка: быстрая замена eval
Пример простого безопасного парсинга (алгоритм обратной польской нотации) — краткая идея:
- Токенизировать строку на числа и операторы.
- Преобразовать инфиксное выражение в постфиксное (алгоритм Shunting‑Yard).
- Вычислить постфиксное выражение с помощью стека.
Для большинства задач хватит готовой библиотеки, например mathjs.
Когда можно оставить eval
- В экспериментальных прототипах и учебных проектах, где вы полностью контролируете ввод.
- Никогда для пользовательских данных в публичных приложениях.
Идеи для расширения проекта
- История вычислений и кнопка для повторного ввода предыдущего выражения.
- Поддержка скобок и приоритетов операций (если вы замените eval на парсер — это просто).
- Клавиатурная поддержка (Keydown/Keypress).
- Тёмная/светлая тема и адаптивная верстка для мобильных устройств.
Короткое резюме
- Этот проект — отличный старт для практики JavaScript и DOM‑манипуляций.
eval()прост для PoC, но небезопасен в реальных приложениях.- Для продакшна используйте парсер выражений или библиотеку, добавьте валидацию ввода и тесты.
Важно
Если цель — обучение, начните с текущего кода. Если цель — продукт, замените eval() и добавьте обработку ошибок, тесты и меры безопасности.
Примечание
Все пути к изображениям и файлам в этом материале сохранены без изменений. Вы можете использовать код как отправную точку и развивать функциональность дальше.