Блок отзывов покупателей квартир для сайта застройщика
Плитки с цитатами покупателей: что купили, как шла сделка, ипотека или свои средства и когда получили ключи. Кнопки сверху отбирают отзывы по способу оплаты.
<section class="vbopk">
<div class="vbopk-wrap">
<div class="vbopk-head">
<div class="vbopk-head__txt">
<h2 class="vbopk-h2">Кто уже получил ключи</h2>
<p class="vbopk-lead">Пять покупателей рассказали, что выбрали, как шла сделка и когда заехали. Замените тексты и имена на отзывы своих клиентов.</p>
</div>
<div class="vbopk-filter" id="vbopk-filter" role="group" aria-label="Отбор отзывов по способу оплаты"></div>
</div>
<div class="vbopk-grid" id="vbopk-grid"></div>
<p class="vbopk-foot">Свободные планировки в тех же корпусах <a class="vbopk-link" href="#podbor">смотрите в подборе</a>.</p>
</div>
</section>
<style>
.vbopk, .vbopk *, .vbopk *::before, .vbopk *::after { box-sizing: border-box; }
.vbopk {
--acc: #1f6f5c; --acc-dark: #185a4a; --ink: #1b2620; --muted: #5e6f68; --line: #dde6e2; --soft: #f1f7f4;
--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, 82px) 20px;
}
.vbopk-wrap { max-width: 1200px; margin: 0 auto; padding: 0 clamp(0px, 2vw, 40px); }
.vbopk-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 20px clamp(20px, 3vw, 48px); margin-bottom: clamp(22px, 3vw, 38px); }
.vbopk-head__txt { max-width: 40em; }
.vbopk-h2 { font-family: var(--fh); font-size: clamp(26px, 3.4vw, 40px); line-height: 1.12; font-weight: 700; letter-spacing: -.02em; margin: 0 0 12px; }
.vbopk-lead { font-size: 16px; line-height: 1.65; color: var(--muted); margin: 0; }
.vbopk-filter { display: flex; flex-wrap: wrap; gap: 8px; }
.vbopk-chip { -webkit-appearance: none; appearance: none; cursor: pointer; font: inherit; font-size: 14px; line-height: 1.2;
padding: 10px 16px; border: 1.5px solid var(--line); border-radius: 999px;
background: #fff !important; color: var(--muted) !important; transition: border-color .18s ease, color .18s ease, background .18s ease; }
.vbopk-chip:hover { border-color: var(--acc); color: var(--acc) !important; }
.vbopk-chip[aria-pressed="true"] { border-color: var(--acc); background: var(--acc) !important; color: #fff !important; font-weight: 600; }
.vbopk-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: clamp(14px, 1.6vw, 20px); align-items: start; }
.vbopk-card { position: relative; display: flex; flex-direction: column; background: #fff; border: 1px solid var(--line); border-radius: 20px;
padding: clamp(20px, 2.2vw, 28px) clamp(18px, 2.2vw, 26px); overflow: hidden;
opacity: 0; transform: translateY(12px); transition: opacity .45s ease, transform .45s cubic-bezier(.22,1,.36,1); }
.vbopk-card.is-in { opacity: 1; transform: none; }
.vbopk-card::before { content: '\00AB'; position: absolute; right: 16px; top: 2px; font-family: var(--fh); font-size: 74px; line-height: 1; color: var(--soft); }
.vbopk-card--wide { grid-column: span 2; }
.vbopk-top { position: relative; display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.vbopk-ava { flex: 0 0 46px; width: 46px; height: 46px; border-radius: 15px; display: flex; align-items: center; justify-content: center;
font-family: var(--fh); font-size: 15px; font-weight: 700; color: #fff; letter-spacing: .02em; }
.vbopk-name { display: block; font-size: 15.5px; font-weight: 600; line-height: 1.2; }
.vbopk-obj { display: block; font-size: 12.5px; color: var(--muted); margin-top: 4px; }
.vbopk-pay { margin-left: auto; font-size: 11.5px; font-weight: 600; line-height: 1.2; border-radius: 999px; padding: 6px 11px; white-space: nowrap;
background: var(--soft); color: var(--acc); }
.vbopk-pay--cash { background: #f3f2ee; color: #7a6c4f; }
.vbopk-quote { position: relative; margin: 0 0 18px; font-size: 15px; line-height: 1.68; color: var(--muted); flex: 1; }
.vbopk-dl { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 12px 16px; margin: 0; padding-top: 16px; border-top: 1px solid var(--line); }
.vbopk-dl dt { font-size: 11px; color: #93a29b; margin-bottom: 4px; }
.vbopk-dl dd { margin: 0; font-size: 13.5px; line-height: 1.4; font-weight: 600; }
.vbopk-foot { margin: clamp(20px, 2.4vw, 30px) 0 0; font-size: 15px; line-height: 1.6; color: var(--muted); }
.vbopk-link, .vbopk-link:link, .vbopk-link:visited { color: var(--acc) !important; text-decoration: underline; }
.vbopk-link:hover { color: var(--acc-dark) !important; }
@media (max-width: 780px) { .vbopk-card--wide { grid-column: auto; } }
@media (prefers-reduced-motion: reduce) {
.vbopk-card { opacity: 1 !important; transform: none !important; transition: none !important; }
.vbopk-chip { transition: none !important; }
}
</style>
<script>
(function () {
/* ── ОТЗЫВЫ: pay: 'ипотека' или 'наличные', c: цвет плашки с инициалами ── */
var REVIEWS = [
{ name: 'Анна Ветрова', obj: 'Студия 28 м², корпус 2', pay: 'ипотека', c: '#1f6f5c', wide: false,
deal: 'Договор долевого участия', bank: 'Одобрение за 4 дня', keys: 'Заселилась в апреле',
text: 'Смотрела студии полгода и боялась брать на этапе котлована. Здесь показали такую же готовую в первом корпусе, дали походить и померить кухню рулеткой. После этого сомнений не осталось, документы подписали через неделю.' },
{ name: 'Игорь и Полина Дмитриевы', obj: 'Двушка 54 м², корпус 3', pay: 'ипотека', c: '#2c6a86', wide: true,
deal: 'Договор долевого участия', bank: 'Семейная ставка, первый взнос 20%', keys: 'Заселились в июне',
text: 'Брали двушку в третьем корпусе под семейную программу. Менеджер собрала пакет документов за нас и сама возила его в банк, нам осталось приехать на подписание. Отдельно скажу про приёмку: замечания по откосам и одной двери устранили за девять дней, повторный осмотр назначили сами, без напоминаний. Ключи получили на две недели раньше срока из договора.' },
{ name: 'Сергей Тимохин', obj: 'Однушка 41 м², корпус 1', pay: 'наличные', c: '#7a6c4f', wide: false,
deal: 'Готовая квартира, переуступка', bank: 'Оплата одним платежом', keys: 'Заселился в феврале',
text: 'Продал старую квартиру и искал вариант без ожидания стройки. Взял по переуступке в сданном корпусе, сделку провели через аккредитив за три дня. Сумма в договоре совпала с той, что назвали по телефону.' },
{ name: 'Марина Соколова', obj: 'Двушка 58 м² с террасой, корпус 3', pay: 'ипотека', c: '#8a5a2b', wide: false,
deal: 'Договор долевого участия', bank: 'Ставка 6,2%, срок 20 лет', keys: 'Заселилась в мае',
text: 'Хотела квартиру с выходом на террасу и долго не могла найти. Планировку нашли за один визит, но пришлось подождать переоформления брони от прежнего покупателя. Держали в курсе каждый день, это было важно.' },
{ name: 'Артём Кузнецов', obj: 'Студия 31 м², корпус 2', pay: 'наличные', c: '#5a5f7a', wide: false,
deal: 'Покупка под аренду', bank: 'Оплата в два платежа', keys: 'Сдал арендаторам в марте',
text: 'Брал как вложение, считал доходность по соседним объявлениям. Помогли подобрать этаж и сторону, чтобы квартира быстрее сдавалась. Арендаторы нашлись за неделю после отделки.' }
];
var roots = document.querySelectorAll('.vbopk');
for (var i = 0; i < roots.length; i++) init(roots[i]);
function init(root) {
if (root.__vb) return; root.__vb = 1;
var grid = root.querySelector('#vbopk-grid'), filter = root.querySelector('#vbopk-filter');
var modes = ['Все отзывы', 'ипотека', 'наличные'], active = 'Все отзывы';
filter.innerHTML = modes.map(function (m) {
var label = m === 'ипотека' ? 'С ипотекой' : m === 'наличные' ? 'Без ипотеки' : m;
return '<button type="button" class="vbopk-chip" data-m="' + m + '" aria-pressed="' + (m === active) + '">' + label + '<\/button>';
}).join('');
function card(r) {
var w = r.name.split(' ');
var ini = w[0].charAt(0) + w[w.length - 1].charAt(0);
return '<article class="vbopk-card' + (r.wide ? ' vbopk-card--wide' : '') + '" data-pay="' + r.pay + '">' +
'<div class="vbopk-top">' +
'<span class="vbopk-ava" style="background:' + r.c + '">' + ini + '<\/span>' +
'<span><b class="vbopk-name">' + r.name + '<\/b><span class="vbopk-obj">' + r.obj + '<\/span><\/span>' +
'<span class="vbopk-pay' + (r.pay === 'наличные' ? ' vbopk-pay--cash' : '') + '">' + (r.pay === 'ипотека' ? 'Ипотека' : 'Свои средства') + '<\/span>' +
'<\/div>' +
'<p class="vbopk-quote">' + r.text + '<\/p>' +
'<dl class="vbopk-dl">' +
'<div><dt>Форма сделки<\/dt><dd>' + r.deal + '<\/dd><\/div>' +
'<div><dt>Деньги<\/dt><dd>' + r.bank + '<\/dd><\/div>' +
'<div><dt>Заселение<\/dt><dd>' + r.keys + '<\/dd><\/div>' +
'<\/dl><\/article>';
}
function show(list) {
grid.innerHTML = list.map(card).join('');
var cards = Array.prototype.slice.call(grid.querySelectorAll('.vbopk-card'));
cards.forEach(function (el, n) {
setTimeout(function () { el.classList.add('is-in'); }, Math.min(n, 6) * 60);
});
}
filter.addEventListener('click', function (e) {
var btn = e.target.closest ? e.target.closest('.vbopk-chip') : null;
if (!btn) return;
active = btn.getAttribute('data-m');
var all = filter.querySelectorAll('.vbopk-chip');
for (var k = 0; k < all.length; k++) all[k].setAttribute('aria-pressed', String(all[k] === btn));
show(REVIEWS.filter(function (r) { return active === 'Все отзывы' || r.pay === active; }));
});
show(REVIEWS);
}
})();
</script> Вставляется целиком в блок T123 «HTML-код». Внутри уже есть стили и скрипт, подключать ничего не нужно.
Как вставить блок в Tilda
- Скопируйте кодКнопка «Скопировать код» выше кладёт всё содержимое в буфер обмена.
- Добавьте блок T123В редакторе страницы: «Библиотека блоков» → «Другое» → T123 «HTML-код».
- Вставьте и сохранитеНажмите «Контент», вставьте код в поле, сохраните и обновите страницу.
- ОпубликуйтеВ превью скрипты Tilda работают не всегда — проверяйте на опубликованной странице.
Подробная инструкция с граблями — как вставить вайб-блок в Tilda.
Что менять под себя
| Где в коде | За что отвечает |
|---|---|
массив REVIEWS в начале скрипта | имена, объекты, тексты отзывов и даты заселения |
поле pay у отзыва | относит историю к ипотеке или своим средствам, от него работает отбор |
поле wide: true | растягивает плитку на две колонки, подходит для самой длинной истории |
--acc на корне блока | цвет плашек, активной кнопки отбора и ссылки в подвале |
ссылка href="#podbor" внизу | ведёт к вашему разделу с планировками или к форме на странице |
Отзывы покупателей квартир: зачем он нужен
Квартиру выбирают месяцами и постоянно оглядываются на чужой опыт. Безликое «всё понравилось» такому покупателю ничего не даёт: ему важно, кто брал студию и кто двушку в третьем корпусе, сколько дней банк рассматривал заявку и через сколько после сдачи люди реально заехали. Блок собран вокруг этих деталей, поэтому каждый отзыв работает как маленький разбор сделки. Человек находит похожий на свой случай и перестаёт считать покупку прыжком в темноту.
Каждая плитка состоит из цитаты и трёх строк снизу: форма сделки, что было с деньгами, дата заселения. Отзывы лежат одним массивом в начале скрипта, там же задаются цвет плашки с инициалами и признак широкой плитки для самой развёрнутой истории. Кнопки над сеткой отбирают ипотечные покупки и покупки за свои средства, счётчик и вёрстка при этом не ломаются. Плитки появляются с лёгкой задержкой друг за другом, а при включённом системном запрете анимаций показываются сразу.
Вопросы по этому блоку
-
Скопируйте любой объект в массиве REVIEWS и поменяйте поля. Сетка сама разложит новую плитку, править разметку не нужно.
-
Да. Удалите контейнер с идентификатором фильтра из разметки и строку, которая его находит в скрипте. Все отзывы останутся на месте и покажутся сразу.
-
Скрипт складывает их из первого и последнего слова имени. Цвет квадрата задаётся полем c у каждого отзыва, фотографии для этого блока не нужны.
-
Да. Код на этой странице копируется целиком, без регистрации и подписки. Указывать авторство не нужно, использовать можно в коммерческих проектах.
-
Нет. Все классы внутри имеют собственный префикс vbopk, поэтому не пересекаются ни со стилями Tilda, ни с другими блоками. Скрипт привязан к своему элементу и запускается один раз, даже если блок вставлен дважды.
-
Раскладка перестраивается под узкие экраны, размеры заданы через clamp, поля ввода имеют шрифт 16 пикселей — iOS не будет зумить страницу при фокусе. Отдельной мобильной версии подключать не нужно.
Другие блоки отзывов
Ещё блоки для недвижимости
Собрать сайт целиком, а не по блокам
Дровосеки делают сайты на Tilda под ключ: структура, тексты, дизайн, вёрстка и вайб-блоки под задачи бизнеса.