Задать вопрос директору
Telegram
VK
Звонок

Блок отзывов о ремонте с горизонтальной лентой

Шесть отзывов заказчиков в горизонтальной ленте: имя, объект с площадью, дата, текст и метки того, что делали на квартире. Листается стрелками, свайпом и клавишами.

Живое демо — блок работает прямо здесь

Код блока

<section class="vboor">
  <div class="vboor-wrap">
    <div class="vboor-top">
      <div class="vboor-head">
        <h2 class="vboor-h2">Что говорят после сдачи объекта</h2>
        <p class="vboor-lead">Отзывы оставляют через месяц после подписания акта, когда квартира уже обжита и видно, как ведут себя стыки, краска и сантехника.</p>
      </div>
      <div class="vboor-nav">
        <button type="button" class="vboor-arr" id="vboor-prev" aria-label="Предыдущий отзыв">
          <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M15 5l-7 7 7 7" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
        </button>
        <button type="button" class="vboor-arr" id="vboor-next" aria-label="Следующий отзыв">
          <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M9 5l7 7-7 7" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
        </button>
      </div>
    </div>

    <div class="vboor-track" id="vboor-track" tabindex="0" role="group" aria-label="Лента отзывов заказчиков"></div>

    <div class="vboor-bar"><i id="vboor-bar"></i></div>
  </div>
</section>

<style>
.vboor, .vboor *, .vboor *::before, .vboor *::after { box-sizing: border-box; }
.vboor {
  --acc: #e8a33d; --ink: #f2f0ec; --muted: #a2a9b2; --line: #343941; --card: #262a30; --bg: #1e2126;
  --f: var(--t-text-font, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif);
  --fh: var(--t-headline-font, var(--f));
  background: var(--bg); color: var(--ink); font-family: var(--f); padding: clamp(36px, 5vw, 80px) 0;
}
.vboor-wrap { max-width: 1240px; margin: 0 auto; padding: 0 clamp(20px, 4vw, 60px); }
.vboor-top { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; margin-bottom: clamp(22px, 3vw, 36px); }
.vboor-head { max-width: 44em; }
.vboor-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; }
.vboor-lead { font-size: 16px; line-height: 1.65; color: var(--muted); margin: 0; }

.vboor-nav { display: flex; gap: 10px; flex: 0 0 auto; }
.vboor-arr { width: 48px; height: 48px; border-radius: 50%; border: 1px solid var(--line); margin: 0; padding: 0;
  -webkit-appearance: none; appearance: none; cursor: pointer; background: none !important; color: var(--ink) !important;
  display: flex; align-items: center; justify-content: center; transition: border-color .18s ease, color .18s ease, opacity .18s ease; }
.vboor-arr svg { width: 22px; height: 22px; }
.vboor-arr:hover { border-color: var(--acc); color: var(--acc) !important; }
.vboor-arr[disabled] { opacity: .32; cursor: default; }
.vboor-arr[disabled]:hover { border-color: var(--line); color: var(--ink) !important; }

.vboor-track { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(288px, 25%); gap: 16px;
  overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory; scroll-behavior: smooth;
  padding-bottom: 4px; scrollbar-width: none; -ms-overflow-style: none; }
.vboor-track::-webkit-scrollbar { display: none; }
.vboor-track:focus-visible { outline: 2px solid var(--acc); outline-offset: 6px; }
.vboor-card { scroll-snap-align: start; display: flex; flex-direction: column; background: var(--card);
  border: 1px solid var(--line); border-radius: 18px; padding: clamp(20px, 2.2vw, 26px); }
.vboor-card__top { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.vboor-ava { flex: 0 0 44px; width: 44px; height: 44px; border-radius: 50%; background: rgba(232, 163, 61, .16); color: var(--acc);
  display: flex; align-items: center; justify-content: center; font-family: var(--fh); font-size: 16px; font-weight: 700; }
.vboor-who { min-width: 0; }
.vboor-who b { display: block; font-size: 15px; font-weight: 600; }
.vboor-who span { display: block; font-size: 12.5px; color: var(--muted); margin-top: 3px; }
.vboor-date { margin-left: auto; flex: 0 0 auto; font-size: 12px; color: var(--muted); white-space: nowrap; }
.vboor-text { margin: 0 0 18px; font-size: 14.5px; line-height: 1.68; color: #d5d8dc; }
.vboor-did { list-style: none; margin: auto 0 0; padding: 14px 0 0; border-top: 1px solid var(--line);
  display: flex; flex-wrap: wrap; gap: 6px; }
.vboor-did li { font-size: 11.5px; line-height: 1; color: var(--muted); border: 1px solid var(--line); border-radius: 999px; padding: 7px 10px; }

.vboor-bar { height: 3px; border-radius: 3px; background: var(--line); margin-top: clamp(18px, 2.4vw, 26px); overflow: hidden; }
.vboor-bar i { display: block; height: 100%; width: 25%; border-radius: 3px; background: var(--acc); transition: width .25s ease, margin-left .25s ease; }

@media (max-width: 900px) {
  .vboor-top { flex-direction: column; align-items: flex-start; }
  .vboor-track { grid-auto-columns: minmax(268px, 78%); }
}
@media (prefers-reduced-motion: reduce) {
  .vboor-track { scroll-behavior: auto; }
  .vboor-bar i, .vboor-arr { transition: none !important; }
}
</style>

<script>
(function () {
  /* ОТЗЫВЫ: obj это объект и площадь, did это перечень работ */
  var REVIEWS = [
    { name: 'Ирина Дёмина', obj: 'Двушка 54 м², Академический', date: 'март 2025', ini: 'И',
      text: 'Брали капитальный пакет, жили это время у родителей. График висел в общем чате, каждую пятницу прораб выкладывал фотографии и писал, что закрыли за неделю. По срокам вышли с опозданием на четыре дня из-за поставки плитки, предупредили за две недели.',
      did: ['Демонтаж до бетона', 'Электрика', 'Санузел', 'Стены под покраску'] },
    { name: 'Сергей Мальцев', obj: 'Дом 148 м², Кольцово', date: 'январь 2025', ini: 'С',
      text: 'Отделка первого этажа после строителей: полы гуляли, стены под штукатурку никто не готовил. Бригада переделала стяжку и вывела геометрию, теперь двери закрываются как надо. Смету пересчитали один раз, когда вскрыли пол, и показали, из чего сложилась разница.',
      did: ['Стяжка', 'Штукатурка по маякам', 'Двери', 'Ламинат'] },
    { name: 'Анна Ковалёва', obj: 'Студия 28 м², Уралмаш', date: 'февраль 2025', ini: 'А',
      text: 'Квартира под сдачу, важен был срок. Уложились в 26 дней, ключи отдали в оговорённую пятницу. Мусор выносили сами, соседи ни разу не жаловались на грязь в подъезде.',
      did: ['Косметический ремонт', 'Обои', 'Розетки', 'Ламинат'] },
    { name: 'Марат Хайруллин', obj: 'Трёшка 76 м², Ботанический', date: 'ноябрь 2024', ini: 'М',
      text: 'Переносили кухню, поэтому нужна была разводка воды и вытяжки по проекту. Электрик отдал схему щита и фотографии трасс в стенах, теперь понятно, где сверлить. Плитку в санузле уложили с раскладкой от центра, шов ровный по всей стене.',
      did: ['Перенос кухни', 'Разводка воды', 'Щит', 'Керамогранит'] },
    { name: 'Ольга Терентьева', obj: 'Однушка 38 м², Пионерский', date: 'декабрь 2024', ini: 'О',
      text: 'Первый ремонт в жизни, боялась, что меня будут дёргать по каждой мелочи. Прораб приезжал на выбор материалов и давал спецификацию с количеством, поэтому в строительном я не переплатила за лишние упаковки.',
      did: ['Выравнивание стен', 'Покраска', 'Плитка на кухне'] },
    { name: 'Дмитрий Рогов', obj: 'Таунхаус 112 м², Кольцово', date: 'май 2025', ini: 'Д',
      text: 'Работали по дизайн-проекту с чужими чертежами, часть узлов пришлось пересогласовывать. Спорные места обсуждали на объекте с дизайнером и решали за один визит. Через полгода вызвал по гарантии из-за трещины на откосе, приехали и переделали бесплатно.',
      did: ['Работа по проекту', 'Свет', 'Санузлы', 'Гарантийный выезд'] }
  ];

  var roots = document.querySelectorAll('.vboor');
  for (var i = 0; i < roots.length; i++) init(roots[i]);

  function init(root) {
    if (root.__vb) return; root.__vb = 1;
    var track = root.querySelector('#vboor-track');
    var prev = root.querySelector('#vboor-prev'), next = root.querySelector('#vboor-next'), bar = root.querySelector('#vboor-bar');

    track.innerHTML = REVIEWS.map(function (r) {
      return '<article class="vboor-card"><div class="vboor-card__top">' +
        '<span class="vboor-ava" aria-hidden="true">' + r.ini + '<\/span>' +
        '<span class="vboor-who"><b>' + r.name + '<\/b><span>' + r.obj + '<\/span><\/span>' +
        '<span class="vboor-date">' + r.date + '<\/span><\/div>' +
        '<p class="vboor-text">' + r.text + '<\/p>' +
        '<ul class="vboor-did">' + r.did.map(function (d) { return '<li>' + d + '<\/li>'; }).join('') + '<\/ul>' +
        '<\/article>';
    }).join('');

    function step() {
      var card = track.querySelector('.vboor-card');
      return card ? card.offsetWidth + 16 : 300;
    }
    function maxScroll() { return track.scrollWidth - track.clientWidth; }

    function sync() {
      var max = maxScroll(), x = track.scrollLeft;
      prev.disabled = x < 4;
      next.disabled = x > max - 4;
      var visible = track.clientWidth / track.scrollWidth;
      var pos = max > 0 ? x / max : 0;
      bar.style.width = Math.max(visible * 100, 8) + '%';
      bar.style.marginLeft = pos * (100 - Math.max(visible * 100, 8)) + '%';
    }

    prev.addEventListener('click', function () { track.scrollLeft -= step(); });
    next.addEventListener('click', function () { track.scrollLeft += step(); });
    track.addEventListener('scroll', function () {
      if (track.__raf) return;
      track.__raf = 1;
      window.requestAnimationFrame(function () { track.__raf = 0; sync(); });
    });
    track.addEventListener('keydown', function (e) {
      if (e.key === 'ArrowRight') { track.scrollLeft += step(); e.preventDefault(); }
      if (e.key === 'ArrowLeft') { track.scrollLeft -= step(); e.preventDefault(); }
    });
    window.addEventListener('resize', sync);
    sync();
    setTimeout(sync, 300);
  }
})();
</script>

Вставляется целиком в блок T123 «HTML-код». Внутри уже есть стили и скрипт, подключать ничего не нужно.

Как вставить блок в Tilda

  1. Скопируйте кодКнопка «Скопировать код» выше кладёт всё содержимое в буфер обмена.
  2. Добавьте блок T123В редакторе страницы: «Библиотека блоков» → «Другое» → T123 «HTML-код».
  3. Вставьте и сохранитеНажмите «Контент», вставьте код в поле, сохраните и обновите страницу.
  4. ОпубликуйтеВ превью скрипты Tilda работают не всегда — проверяйте на опубликованной странице.

Подробная инструкция с граблями — как вставить вайб-блок в Tilda.

Что менять под себя

Где в кодеЗа что отвечает
массив REVIEWS в начале скриптаимя, объект, дата, текст отзыва и метки работ
поле ini у отзывабуква в кружке вместо аватара
grid-auto-columns у .vboor-trackсколько карточек видно в ленте одновременно
--bg и --cardоттенки тёмного фона секции и карточки
--accцвет стрелок при наведении, кружка и полосы прокрутки

Отзывы о ремонте лентой: зачем он нужен

Отзыв про ремонт работает, когда рядом стоит объект: «двушка 54 квадратных метра» или «дом 148 квадратных метров в Кольцово». Тогда посетитель находит свой случай и дочитывает текст до конца. В карточке под отзывом идут метки работ, поэтому видно, за что именно человек хвалит бригаду. Дата показывает, что отзывы свежие и собираются постоянно.

Лента прокручивается штатным механизмом браузера с привязкой к карточкам, поэтому свайп на телефоне работает так, как человек ожидает. Стрелки гаснут на краях ленты, а полоса под ней показывает, сколько отзывов ещё осталось. Ленту можно листать с клавиатуры стрелками влево и вправо, когда фокус стоит на области отзывов. Тёмный фон отделяет блок от белых секций сверху и снизу.

Вопросы по этому блоку

  • В стилях у .vboor-track поменяйте grid-auto-columns с 25% на 33%. Мобильная ширина задаётся отдельно в медиазапросе и правится там же.

  • Да, это обычная горизонтальная прокрутка с привязкой карточек к краю. Стрелки остаются на месте и делают то же самое для тех, кто работает мышью.

  • Да, поменяйте --bg на светлый оттенок, --card на белый, а --ink и --muted на тёмные. Остальные цвета собраны из этих переменных, править разметку не придётся.

  • Да. Код на этой странице копируется целиком, без регистрации и подписки. Указывать авторство не нужно, использовать можно в коммерческих проектах.

  • Нет. Все классы внутри имеют собственный префикс vboor, поэтому не пересекаются ни со стилями Tilda, ни с другими блоками. Скрипт привязан к своему элементу и запускается один раз, даже если блок вставлен дважды.

  • Раскладка перестраивается под узкие экраны, размеры заданы через clamp, поля ввода имеют шрифт 16 пикселей — iOS не будет зумить страницу при фокусе. Отдельной мобильной версии подключать не нужно.

Другие блоки отзывов

Ещё блоки для ремонта и строительства

Собрать сайт целиком, а не по блокам

Дровосеки делают сайты на Tilda под ключ: структура, тексты, дизайн, вёрстка и вайб-блоки под задачи бизнеса.