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

Блок отзывов для сайта автосервиса

Кладка карточек разной высоты с фильтром по услуге. Длинные отзывы не обрезаются, короткие не растягиваются пустотой.

  • ТипОтзывы
  • НишаАвто
  • Вес кода9.9 КБ
  • Заголовок H1нет, только H2
  • Форма Tildaнет
  • Интерактив
Живое демо — блок работает прямо здесь

Код блока

<section class="vboav">
  <div class="vboav-wrap">
    <div class="vboav-head">
      <h2 class="vboav-h2">Отзывы клиентов</h2>
      <p class="vboav-lead">Без правок и модерации. Если работа сделана плохо, отзыв остаётся — вместе с нашим ответом.</p>
      <div class="vboav-filter" id="vboav-filter" role="group" aria-label="Фильтр по услуге"></div>
    </div>

    <div class="vboav-masonry" id="vboav-list"></div>
    <div class="vboav-more"><button type="button" class="vboav-btn" id="vboav-more">Показать ещё</button></div>
  </div>
</section>

<style>
.vboav, .vboav *, .vboav *::before, .vboav *::after { box-sizing: border-box; }
.vboav {
  --acc: #ff8a1f; --bg: #f6f6f7; --panel: #fff; --ink: #17191c; --muted: #62676e; --line: #e4e6e9; --star: #f0a323;
  --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) 20px;
}
.vboav-wrap { max-width: 1240px; margin: 0 auto; padding: 0 clamp(0px, 2vw, 40px); }
.vboav-head { margin-bottom: clamp(22px, 2.8vw, 34px); }
.vboav-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; }
.vboav-lead { font-size: 16px; line-height: 1.6; color: var(--muted); margin: 0 0 20px; max-width: 42em; }
.vboav-filter { display: flex; flex-wrap: wrap; gap: 8px; }
.vboav-chip { border: 1.5px solid var(--line); margin: 0; -webkit-appearance: none; appearance: none; font: inherit; cursor: pointer;
  background: var(--panel) !important; color: var(--muted) !important; border-radius: 999px; padding: 9px 18px; font-size: 14px; transition: .18s ease; }
.vboav-chip:hover { border-color: var(--acc); color: var(--ink) !important; }
.vboav-chip[aria-pressed="true"] { background: var(--ink) !important; border-color: var(--ink); color: #fff !important; }

.vboav-masonry { columns: 3; column-gap: 16px; }
.vboav-card { break-inside: avoid; background: var(--panel); border: 1px solid var(--line); border-radius: 18px;
  padding: 20px 22px; margin-bottom: 16px; display: inline-block; width: 100%; }
.vboav-card__top { display: flex; align-items: center; gap: 11px; margin-bottom: 12px; }
.vboav-ava { flex: 0 0 38px; width: 38px; height: 38px; border-radius: 50%; background: var(--bg); display: flex; align-items: center;
  justify-content: center; font-size: 14px; font-weight: 700; color: var(--acc); }
.vboav-card__n { display: block; font-size: 14.5px; font-weight: 600; }
.vboav-card__c { display: block; font-size: 12px; color: var(--muted); margin-top: 2px; }
.vboav-stars { display: flex; gap: 2px; margin-bottom: 10px; }
.vboav-stars svg { width: 14px; height: 14px; color: var(--star); }
.vboav-stars svg.is-off { color: #d9dbde; }
.vboav-card p { margin: 0 0 12px; font-size: 14.5px; line-height: 1.6; }
.vboav-card__f { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; padding-top: 12px; border-top: 1px solid var(--line);
  font-size: 12px; color: var(--muted); }
.vboav-tag { background: var(--bg); border-radius: 999px; padding: 3px 10px; }

.vboav-more { text-align: center; margin-top: 8px; }
.vboav-btn { min-height: 50px; padding: 0 30px; border: 1.5px solid var(--line); margin: 0; -webkit-appearance: none; appearance: none;
  font: inherit; font-size: 15px; font-weight: 600; cursor: pointer; border-radius: 999px; background: var(--panel) !important; color: var(--ink) !important; transition: .18s ease; }
.vboav-btn:hover { border-color: var(--acc); }
.vboav-btn[hidden] { display: none; }

@media (max-width: 1000px) { .vboav-masonry { columns: 2; } }
@media (max-width: 640px) { .vboav-masonry { columns: 1; } }
@media (prefers-reduced-motion: reduce) { .vboav * { transition: none !important; } }
</style>

<script>
(function () {
  var SHOW = 6;   /* сколько отзывов показывать сразу */

  /* ── ОТЗЫВЫ ── */
  var REVIEWS = [
    { name: 'Андрей', car: 'Kia Sportage, 2019', service: 'Диагностика', rate: 5, date: 'март',
      text: 'Приехал с плавающей ошибкой, которую в двух местах не нашли. Здесь сняли логи, показали на экране, где именно уходит сигнал, и починили проводку за час. Не стали менять датчик, хотя могли.' },
    { name: 'Виктор', car: 'Toyota Camry, 2016', service: 'Ремонт двигателя', rate: 5, date: 'февраль',
      text: 'Капиталка. Дорого, долго, но честно: присылали фото каждого этапа, обосновывали каждую позицию в смете. Через 12 тысяч пробега — никаких нареканий, расход вернулся к заводскому.' },
    { name: 'Сергей', car: 'Lada Vesta, 2021', service: 'Подвеска', rate: 5, date: 'март',
      text: 'Стучало спереди. Сказали честно: стойки ещё походят, дело в стойках стабилизатора. Поменяли только их, вышло 4 тысячи вместо ожидаемых 20.' },
    { name: 'Марина', car: 'Hyundai Solaris, 2018', service: 'ТО', rate: 5, date: 'январь',
      text: 'Первый сервис, где мне объяснили, что именно меняют и зачем, без снисходительного тона. Записалась через сайт, приняли минута в минуту.' },
    { name: 'Олег', car: 'Volkswagen Tiguan, 2017', service: 'Кузовной ремонт', rate: 4, date: 'декабрь',
      text: 'Красили крыло после парковки. Цвет попал идеально, шагрень тоже. Сделали на два дня дольше обещанного из-за поставки краски — предупредили заранее, но планы пришлось двигать.' },
    { name: 'Дмитрий', car: 'BMW 320i, 2015', service: 'Диагностика', rate: 5, date: 'февраль',
      text: 'Отговорили от замены турбины, которую мне настойчиво продавали в другом месте. Проблема была в клапане. Экономия — сто с лишним тысяч.' },
    { name: 'Екатерина', car: 'Renault Duster, 2020', service: 'ТО', rate: 5, date: 'март',
      text: 'Делали ТО-3. Понравилось, что сразу отдали снятые фильтры — видно, что реально меняли, а не просто отметили в книжке.' },
    { name: 'Павел', car: 'Mazda 6, 2014', service: 'Подвеска', rate: 5, date: 'январь',
      text: 'Меняли рычаги и сайлентблоки. Машина поехала как новая. Отдельно порадовало, что дали посмотреть на старые детали и объяснили, что именно в них умерло.' },
    { name: 'Игорь', car: 'Skoda Octavia, 2019', service: 'Кузовной ремонт', rate: 5, date: 'февраль',
      text: 'Полировка и удаление вмятин без покраски. Результат лучше, чем ожидал за эти деньги. Машину отдали вымытой, мелочь, а приятно.' }
  ];

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

  function init(root) {
    if (root.__vb) return; root.__vb = 1;
    var list = root.querySelector('#vboav-list'), fBox = root.querySelector('#vboav-filter'), more = root.querySelector('#vboav-more');
    var filter = 'Все', limit = SHOW;

    var services = ['Все'].concat(REVIEWS.map(function (r) { return r.service; }).filter(function (v, i, a) { return a.indexOf(v) === i; }));
    fBox.innerHTML = services.map(function (s) {
      return '<button type="button" class="vboav-chip" data-s="' + s + '" aria-pressed="' + (s === filter) + '">' + s + '<\/button>';
    }).join('');
    fBox.querySelectorAll('.vboav-chip').forEach(function (b) {
      b.addEventListener('click', function () {
        filter = b.dataset.s; limit = SHOW;
        fBox.querySelectorAll('.vboav-chip').forEach(function (x) { x.setAttribute('aria-pressed', 'false'); });
        b.setAttribute('aria-pressed', 'true');
        draw();
      });
    });

    function star(on) {
      return '<svg viewBox="0 0 16 16" class="' + (on ? '' : 'is-off') + '" aria-hidden="true" focusable="false">' +
        '<path d="M8 1.6l1.9 3.9 4.3.6-3.1 3 .7 4.3L8 11.4 4.2 13.4l.7-4.3-3.1-3 4.3-.6z" fill="currentColor"/><\/svg>';
    }

    function draw() {
      var pool = REVIEWS.filter(function (r) { return filter === 'Все' || r.service === filter; });
      var shown = pool.slice(0, limit);
      list.innerHTML = shown.map(function (r) {
        var stars = '';
        for (var s = 1; s <= 5; s++) stars += star(s <= r.rate);
        return '<article class="vboav-card"><div class="vboav-card__top">' +
          '<span class="vboav-ava">' + r.name.charAt(0) + '<\/span>' +
          '<span><b class="vboav-card__n">' + r.name + '<\/b><span class="vboav-card__c">' + r.car + '<\/span><\/span><\/div>' +
          '<div class="vboav-stars" aria-label="Оценка ' + r.rate + ' из 5">' + stars + '<\/div>' +
          '<p>' + r.text + '<\/p>' +
          '<div class="vboav-card__f"><span class="vboav-tag">' + r.service + '<\/span><span>' + r.date + '<\/span><\/div><\/article>';
      }).join('');
      more.hidden = shown.length >= pool.length;
    }

    more.addEventListener('click', function () { limit += SHOW; draw(); });
    draw();
  }
})();
</script>

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

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

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

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

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

Где в кодеЗа что отвечает
массив REVIEWSотзывы: имя, машина, услуга, текст, дата
список услуг фильтракатегории для фильтрации
--accцвет активного фильтра и оценки

Отзывы об автосервисе: зачем он нужен

Отзывы у автосервиса разные по длине: кто-то напишет строку, кто-то — историю с деталями. Кладка позволяет показать и то и другое без обрезки текста и без карточек-переростков.

Фильтр по услуге помогает человеку с конкретной проблемой найти похожий случай. Это тот же принцип, что и в поиске по FAQ: релевантность важнее количества.

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

  • В скрипте есть переменная SHOW — по умолчанию шесть, остальные раскрываются кнопкой. Это держит блок компактным и ускоряет загрузку страницы.

  • Нет, на узких экранах она становится одной колонкой в исходном порядке. Порядок карточек в разметке и на экране совпадает.

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

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

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

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

Ещё блоки для авто-тематики

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

Дровосеки делают сайты на Tilda под ключ: структура, тексты, дизайн, вёрстка и вайб-блоки под задачи бизнеса. Как это выглядит для ниши «Авто», видно на отдельной странице.