Ипотечный калькулятор для сайта недвижимости
Считает платёж по настоящей аннуитетной формуле, а не делением суммы на месяцы. Показывает переплату и долю тела кредита на диаграмме.
<section class="vbipk">
<div class="vbipk-wrap">
<div class="vbipk-head">
<h2 class="vbipk-h2">Ипотечный калькулятор</h2>
<p class="vbipk-lead">Считаем по банковской аннуитетной формуле — платёж совпадёт с тем, что вам назовут в банке.</p>
<div class="vbipk-progs" id="vbipk-progs" role="radiogroup" aria-label="Ипотечная программа"></div>
</div>
<div class="vbipk-grid">
<div class="vbipk-panel">
<div class="vbipk-ctl">
<div class="vbipk-ctl__top"><span>Стоимость квартиры</span><b id="vbipk-costv"></b></div>
<input type="range" id="vbipk-cost" min="2000000" max="20000000" step="100000" value="6500000" aria-label="Стоимость квартиры">
</div>
<div class="vbipk-ctl">
<div class="vbipk-ctl__top"><span>Первоначальный взнос</span><b id="vbipk-downv"></b></div>
<input type="range" id="vbipk-down" min="15" max="80" step="1" value="20" aria-label="Первоначальный взнос в процентах">
</div>
<div class="vbipk-ctl">
<div class="vbipk-ctl__top"><span>Срок кредита</span><b id="vbipk-yearsv"></b></div>
<input type="range" id="vbipk-years" min="3" max="30" step="1" value="20" aria-label="Срок кредита в годах">
</div>
<div class="vbipk-ctl">
<div class="vbipk-ctl__top"><span>Ставка</span><b id="vbipk-ratev"></b></div>
<input type="range" id="vbipk-rate" min="3" max="25" step="0.1" value="6" aria-label="Процентная ставка">
</div>
</div>
<aside class="vbipk-out">
<span class="vbipk-out__lbl">Ежемесячный платёж</span>
<strong class="vbipk-out__sum" id="vbipk-pay"></strong>
<div class="vbipk-chart">
<svg viewBox="0 0 120 120" role="img" aria-labelledby="vbipk-charttitle" focusable="false">
<title id="vbipk-charttitle">Соотношение тела кредита и переплаты</title>
<circle cx="60" cy="60" r="48" fill="none" stroke="#dfe6e3" stroke-width="16"/>
<circle cx="60" cy="60" r="48" fill="none" stroke="#1f6f5c" stroke-width="16" stroke-linecap="butt"
id="vbipk-arc" transform="rotate(-90 60 60)"/>
</svg>
<ul class="vbipk-legend">
<li><i style="background:#1f6f5c"></i><span>Сумма кредита</span><b id="vbipk-body"></b></li>
<li><i style="background:#dfe6e3"></i><span>Переплата</span><b id="vbipk-over"></b></li>
</ul>
</div>
<ul class="vbipk-rows">
<li><span>Первый взнос</span><b id="vbipk-down2"></b></li>
<li><span>Всего выплатите</span><b id="vbipk-total"></b></li>
<li><span>Нужный доход</span><b id="vbipk-income"></b></li>
</ul>
<a class="vbipk-cta" href="#podbor">Подобрать квартиру под платёж</a>
<p class="vbipk-note">Расчёт справочный. Итоговые условия определяет банк после одобрения заявки.</p>
</aside>
</div>
</div>
</section>
<style>
.vbipk, .vbipk *, .vbipk *::before, .vbipk *::after { box-sizing: border-box; }
.vbipk {
--acc: #1f6f5c; --acc-dark: #175646; --ink: #1a2320; --muted: #5c6c67; --line: #dfe6e3; --soft: #f3f7f5;
--f: var(--t-text-font, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif);
--fh: var(--t-headline-font, var(--f));
background: #fff; color: var(--ink); font-family: var(--f); padding: clamp(36px, 5vw, 80px) 20px;
}
.vbipk-wrap { max-width: 1140px; margin: 0 auto; padding: 0 clamp(0px, 2vw, 40px); }
.vbipk-head { margin-bottom: clamp(22px, 3vw, 34px); }
.vbipk-h2 { font-family: var(--fh); font-size: clamp(26px, 3.4vw, 40px); line-height: 1.1; font-weight: 700; letter-spacing: -.02em; margin: 0 0 12px; }
.vbipk-lead { font-size: 16px; line-height: 1.6; color: var(--muted); margin: 0 0 20px; max-width: 42em; }
.vbipk-progs { display: flex; flex-wrap: wrap; gap: 8px; }
.vbipk-progs button { border: 1.5px solid var(--line); margin: 0; -webkit-appearance: none; appearance: none; font: inherit; cursor: pointer;
background: #fff !important; color: var(--muted) !important; border-radius: 999px; padding: 9px 18px; font-size: 14px; transition: .18s ease; }
.vbipk-progs button:hover { border-color: var(--acc); color: var(--ink) !important; }
.vbipk-progs button[aria-checked="true"] { background: var(--acc) !important; border-color: var(--acc); color: #fff !important; }
.vbipk-grid { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); gap: 18px; align-items: start; }
.vbipk-panel { background: var(--soft); border-radius: 20px; padding: clamp(20px, 2.6vw, 30px); }
.vbipk-ctl { margin-bottom: 24px; }
.vbipk-ctl:last-child { margin-bottom: 0; }
.vbipk-ctl__top { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 12px; font-size: 15px; color: var(--muted); }
.vbipk-ctl__top b { font-family: var(--fh); font-size: 19px; color: var(--ink); }
.vbipk input[type=range] { -webkit-appearance: none; appearance: none; width: 100%; height: 4px; border-radius: 4px; background: #cfdbd7; outline: none; }
.vbipk input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 24px; height: 24px; border-radius: 50%;
background: var(--acc); border: 4px solid #fff; box-shadow: 0 1px 6px rgba(0,0,0,.2); cursor: pointer; }
.vbipk input[type=range]::-moz-range-thumb { width: 18px; height: 18px; border-radius: 50%; background: var(--acc); border: 3px solid #fff; cursor: pointer; }
.vbipk-out { background: #fff; border: 1px solid var(--line); border-radius: 20px; padding: clamp(20px, 2.6vw, 30px); position: sticky; top: 20px; }
.vbipk-out__lbl { display: block; font-size: 13px; color: var(--muted); }
.vbipk-out__sum { display: block; font-family: var(--fh); font-size: clamp(30px, 3.4vw, 40px); line-height: 1.1; font-weight: 700; color: var(--acc); margin: 6px 0 18px; }
.vbipk-chart { display: flex; align-items: center; gap: 18px; padding: 18px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.vbipk-chart svg { flex: 0 0 104px; width: 104px; height: 104px; }
.vbipk-legend { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.vbipk-legend li { display: grid; grid-template-columns: 12px minmax(0, 1fr); column-gap: 9px; align-items: center; }
.vbipk-legend i { width: 12px; height: 12px; border-radius: 3px; grid-row: 1 / 3; }
.vbipk-legend span { font-size: 12.5px; color: var(--muted); }
.vbipk-legend b { font-family: var(--fh); font-size: 16px; font-weight: 700; }
.vbipk-rows { list-style: none; margin: 18px 0 20px; padding: 0; display: grid; gap: 10px; }
.vbipk-rows li { display: flex; justify-content: space-between; gap: 12px; font-size: 14px; color: var(--muted); }
.vbipk-rows b { color: var(--ink); font-weight: 600; white-space: nowrap; }
.vbipk-cta, .vbipk-cta:link, .vbipk-cta:visited, .vbipk-cta:active, .vbipk-cta:focus { display: flex; align-items: center; justify-content: center;
width: 100%; min-height: 54px; border-radius: 10px; font-size: 16px; font-weight: 600;
background: var(--acc); color: #fff !important; text-decoration: none !important; transition: background .2s ease; }
.vbipk-cta:hover { background: var(--acc-dark); color: #fff !important; }
.vbipk-note { margin: 14px 0 0; font-size: 11.5px; line-height: 1.5; color: #8fa19c; }
@media (max-width: 880px) { .vbipk-grid { grid-template-columns: minmax(0, 1fr); } .vbipk-out { position: static; } }
@media (prefers-reduced-motion: reduce) { .vbipk * { transition: none !important; } }
</style>
<script>
(function () {
/* ── ПРОГРАММЫ: если больше одной, над калькулятором появится переключатель ── */
var PROGRAMS = [
{ name: 'Семейная', rate: 6 },
{ name: 'IT-ипотека', rate: 5 },
{ name: 'Господдержка', rate: 8 },
{ name: 'Базовая', rate: 18.5 }
];
var MIN_DOWN = 15; /* минимальный взнос, % */
var INCOME_SHARE = 0.4; /* какую долю дохода банк допускает на платёж */
var roots = document.querySelectorAll('.vbipk');
for (var i = 0; i < roots.length; i++) init(roots[i]);
function init(root) {
if (root.__vb) return; root.__vb = 1;
var $ = function (s) { return root.querySelector(s); };
var st = { cost: 6500000, down: 20, years: 20, rate: PROGRAMS[0].rate };
var LEN = 2 * Math.PI * 48;
function fmt(n) { return String(Math.round(n)).replace(/\B(?=(\d{3})+(?!\d))/g, ' '); }
function mln(n) { return (n / 1000000).toFixed(1).replace('.', ',') + ' млн ₽'; }
function yearsWord(n) { var m = n % 100, k = n % 10; return m > 10 && m < 20 ? 'лет' : k === 1 ? 'год' : k > 1 && k < 5 ? 'года' : 'лет'; }
var pBox = $('#vbipk-progs');
if (PROGRAMS.length > 1) {
PROGRAMS.forEach(function (p, i) {
var b = document.createElement('button');
b.type = 'button'; b.setAttribute('role', 'radio');
b.setAttribute('aria-checked', i === 0 ? 'true' : 'false');
b.innerHTML = p.name + ' · ' + String(p.rate).replace('.', ',') + '%';
b.addEventListener('click', function () {
st.rate = p.rate;
$('#vbipk-rate').value = p.rate;
pBox.querySelectorAll('button').forEach(function (x) { x.setAttribute('aria-checked', 'false'); });
b.setAttribute('aria-checked', 'true');
render();
});
pBox.appendChild(b);
});
}
$('#vbipk-down').min = MIN_DOWN;
['cost', 'down', 'years', 'rate'].forEach(function (k) {
$('#vbipk-' + k).addEventListener('input', function () {
st[k] = +this.value;
if (k === 'rate') pBox.querySelectorAll('button').forEach(function (x) { x.setAttribute('aria-checked', 'false'); });
render();
});
});
function render() {
var down = st.cost * st.down / 100;
var body = st.cost - down;
var n = st.years * 12;
var i = st.rate / 100 / 12;
/* аннуитетный платёж: body * i * (1+i)^n / ((1+i)^n - 1) */
var pay = i > 0 ? body * i * Math.pow(1 + i, n) / (Math.pow(1 + i, n) - 1) : body / n;
var total = pay * n;
var over = total - body;
$('#vbipk-costv').textContent = mln(st.cost);
$('#vbipk-downv').textContent = st.down + '% · ' + fmt(down) + ' ₽';
$('#vbipk-yearsv').textContent = st.years + ' ' + yearsWord(st.years);
$('#vbipk-ratev').textContent = String(st.rate).replace('.', ',') + '%';
$('#vbipk-pay').textContent = fmt(pay) + ' ₽';
$('#vbipk-body').textContent = fmt(body) + ' ₽';
$('#vbipk-over').textContent = fmt(over) + ' ₽';
$('#vbipk-down2').textContent = fmt(down) + ' ₽';
$('#vbipk-total').textContent = fmt(total + down) + ' ₽';
$('#vbipk-income').textContent = 'от ' + fmt(pay / INCOME_SHARE) + ' ₽';
var share = body / (body + over);
var arc = $('#vbipk-arc');
arc.setAttribute('stroke-dasharray', LEN);
arc.setAttribute('stroke-dashoffset', LEN - LEN * share);
}
render();
}
})();
</script> Вставляется целиком в блок T123 «HTML-код». Внутри уже есть стили и скрипт, подключать ничего не нужно.
Как вставить блок в Tilda
- Скопируйте кодКнопка «Скопировать код» выше кладёт всё содержимое в буфер обмена.
- Добавьте блок T123В редакторе страницы: «Библиотека блоков» → «Другое» → T123 «HTML-код».
- Вставьте и сохранитеНажмите «Контент», вставьте код в поле, сохраните и обновите страницу.
- ОпубликуйтеВ превью скрипты Tilda работают не всегда — проверяйте на опубликованной странице.
Подробная инструкция с граблями — как вставить вайб-блок в Tilda.
Что менять под себя
| Где в коде | За что отвечает |
|---|---|
RATE | ставка по умолчанию, в процентах годовых |
MIN_DOWN | минимальный первоначальный взнос в процентах |
диапазоны ползунков | пределы стоимости и срока |
--acc | цвет ползунков и диаграммы |
Ипотечный калькулятор: зачем он нужен
Большинство ипотечных калькуляторов на лендингах врут: делят сумму на срок и получают заниженный платёж. Здесь используется банковская аннуитетная формула, поэтому цифра совпадает с той, что человек увидит в банке, и не рушит доверие на следующем шаге.
Диаграмма показывает соотношение тела кредита и переплаты — наглядно и без нравоучений. Это подталкивает увеличить первоначальный взнос, что выгодно и покупателю, и застройщику.
Вопросы по этому блоку
-
Стандартная аннуитетная: платёж равен сумме кредита, умноженной на месячную ставку и коэффициент, зависящий от срока. Она записана в скрипте одной строкой, её можно проверить на любом банковском калькуляторе.
-
Да, в скрипте есть массив PROGRAMS: название и ставка. Если в нём больше одного элемента, над калькулятором появляется переключатель программ.
-
Да. Код на этой странице копируется целиком, без регистрации и подписки. Указывать авторство не нужно, использовать можно в коммерческих проектах.
-
Нет. Все классы внутри имеют собственный префикс vbipk, поэтому не пересекаются ни со стилями Tilda, ни с другими блоками. Скрипт привязан к своему элементу и запускается один раз, даже если блок вставлен дважды.
-
Раскладка перестраивается под узкие экраны, размеры заданы через clamp, поля ввода имеют шрифт 16 пикселей — iOS не будет зумить страницу при фокусе. Отдельной мобильной версии подключать не нужно.
Другие калькуляторы
Ещё блоки для недвижимости
Собрать сайт целиком, а не по блокам
Дровосеки делают сайты на Tilda под ключ: структура, тексты, дизайн, вёрстка и вайб-блоки под задачи бизнеса.