Перейти к содержимому
Забрать бесплатно
Модификации выключены. Так эта страница выглядит на обычной Тильде.

Zero Block: одинаковый набор элементов во всех адаптивах

28 июля 2026 8 МИН КОМАНДА MODKOD

В Zero Block набор элементов один на все разрешения: элемент — это один узел в разметке, а адаптив задаёт ему другие числа, а не другой элемент. Отсюда общий приём: ненужное на этом разрешении увозят координатами на (5000,5000). Полосы прокрутки не появляется, и кажется, что элемента больше нет. Замер показывает обратное: он остаётся видимым для браузера, картинка качается, скринридер его читает, а табуляция до его ссылки уносит с экрана всё остальное.

✓ ПРОВЕРЕНО 28 июля 2026 18 элементов Zero Block на снятой странице (12 текст, 4 картинка, 1 кнопка, 1 видео) на двух артбордах и четырёх разрешениях сверх базового; замер элемента, увезённого на (5000,5000): display block, размер 128×196, картинка запрошена, заголовок и ссылка в дереве доступности, фокус на ссылке прокручивает артборд в left 3848 / top 4396 и уносит видимый заголовок на left −3808; display none убирает узел из дерева доступности, но картинку браузер всё равно запрашивает — снимок страницы Zero Block в modkit/stand и замер в Chromium через протокол браузера

Короткий ответ

Набор элементов один потому, что элемент — один узел разметки, а адаптив меняет ему только числа. Вынос на (5000,5000) элемент не убирает: замер показывает display: block, запрошенную картинку, заголовок со ссылкой в дереве доступности и прокрутку артборда при табуляции. Убирает — display: none классами видимости Тильды на блок.

Почему требование «одинаковый набор» вообще существует

Это не ограничение редактора, а следствие того, как Zero Block устроен в разметке. Вот один текстовый элемент со снятой страницы, как он лежит в HTML:

<div class='t396__elem tn-elem tn-elem__10245705061738663644970'
     data-elem-id='1738663644970'
     data-elem-type='text'
     data-field-top-value="312"
     data-field-left-value="272"
     data-field-height-value="112"
     data-field-width-value="896"
     data-field-axisy-value="top"
     data-field-container-value="grid">

Дальше у того же узла идут наборы на каждое разрешение — data-field-top-res-960-value, data-field-left-res-640-value, data-group-width-res-480-value и так далее. Всё, что различается между адаптивами, — числа: координаты, размеры, единицы, выравнивание. Ни одного атрибута вида «а на 320 этого элемента нет» в схеме не предусмотрено.

Числа на снятой странице:

ЧтоСколько
элементов всего18
из них текст / картинка / кнопка / видео12 / 4 / 1 / 1
артбордов2
разрешений сверх базового4 (960, 640, 480, 320)
атрибутов …-res-320-…92
атрибутов …-res-480-…93
атрибутов …-res-640-…69
атрибутов …-res-960-…81

Восемнадцать элементов — восемнадцать узлов, и на каждом до пяти наборов координат. Требование «одинаковый набор во всех адаптациях» — это просто другой способ сказать «узел один».

Что остаётся от элемента, увезённого на (5000,5000)

Стенд повторяет условия Тильды буквально: артборд объявлен так же, как в её стилях, — position: relative; width: 100%; height: 100vh; overflow: hidden, — элемент внутри стоит на top: 5000px; left: 5000px и содержит заголовок, ссылку и картинку. Рядом — тот же набор, но убранный display: none классом самой Тильды. Замер в Chromium, окно 1280×800:

Что меримУвезён на (5000,5000)display: none
вычисленный displayblocknone
размер по getBoundingClientRect128 × 1960 × 0
картинка запрошена сетьюдада
заголовок в дереве доступностиданет
ссылка в дереве доступностиданет
текст остался в разметкедада
горизонтальная прокрутка у страницынетнет

Читается из таблицы три вещи, и две из них против общего ожидания.

Увезённый элемент для браузера полностью существует. Он занимает 128×196 пикселей, у него честная геометрия, он участвует в раскладке. Единственное, чего он не делает, — не попадает на экран, потому что артборд его обрезает.

Вес страницы не экономит ни один из двух способов. Картинка запрошена и там, и там. display: none не отменяет загрузку изображения, объявленного в разметке тегом <img>, — браузер решает про загрузку раньше, чем применяет стиль видимости. Значит аргумент «увезённый элемент тяжелит страницу, а скрытый нет» неверен: тяжелит их наличие, а не способ сокрытия.

Разница между способами — в дереве доступности. И она принципиальная: то, что попало в дерево, скринридер прочитает как часть страницы. У увезённого элемента там оказываются и заголовок, и ссылка, и картинка с её alt. Посетитель, слушающий страницу, услышит два заголовка вместо одного и не поймёт, почему.

Почему поломку не видно глазами

scrollWidth документа в замере — 1280 при innerWidth 1280. Полосы прокрутки нет, хотя элемент стоит на пять тысяч пикселей правее. Причина — в стилях самой Тильды:

.t396__artboard { position: relative; width: 100%; height: 100vh; overflow: hidden; }

Артборд обрезает всё, что вышло за его границы, и наружу это не прорастает. Именно поэтому приём и живёт: в браузере он выглядит идеально чисто. Ни полосы прокрутки, ни сдвига раскладки, ни предупреждения в консоли — молча.

Что делает табуляция до увезённой ссылки

Это самое неприятное последствие, и его стоит воспроизвести у себя. Ссылка, увезённая за экран, остаётся в порядке обхода клавиатурой. Браузер, ведя по нему фокус, обязан показать элемент — а показать он его может единственным способом: прокрутив тот самый контейнер с overflow: hidden. Замер:

МоментПрокрутка артбордаПозиция видимого заголовка
до фокусаleft: 0, top: 0left: 40
фокус на увезённой ссылкеleft: 3848, top: 4396left: −3808

То есть посетитель нажал Tab несколько раз — и содержимое первого экрана уехало на 3848 пикселей влево, а на его месте оказалось пустое место. Вернуть его обратно нечем: полосы прокрутки у артборда нет, а фокус стоит на элементе, которого не видно.

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

Чем это заменить: то, что делает сама Тильда

У Тильды для этого есть готовые классы, и их видно в её стилях — по пять брейкпоинтов в каждую сторону:

.t-screenmax-320px { display: none; }   /* спрятать на 321 и шире */
.t-screenmax-480px { display: none; }
.t-screenmax-640px { display: none; }
.t-screenmin-320px { display: none; }   /* спрятать на 320 и уже */
.t-screenmin-480px { display: none; }
.t-screenmin-640px { display: none; }
.t-screenmin-980px { display: none; }
.t-screenmin-1200px { display: none; }

Ставятся они на блок, а не на элемент внутри артборда: в настройках блока есть поле «Показывать только на» / «Скрывать на». Значит порядок такой:

  1. Сначала попробовать не дублировать. Один элемент, у которого на 320 другие координаты и другой размер, — это то, для чего адаптивы Zero Block и сделаны. Двойник нужен, когда меняется не геометрия, а содержание: другой текст, другая картинка, другая кнопка.
  2. Если двойник нужен — два блока, а не два элемента в одном артборде. Широкий вариант в одном Zero Block со «скрывать на 480 и уже», мобильный — в другом со «скрывать на 481 и шире». display: none убирает узел из дерева доступности и из порядка обхода клавиатурой — единственный способ это сделать.
  3. Если увезти всё-таки приходится (например, элемент нужен внутри того же артборда из-за анимации), увезённому нужны aria-hidden="true" и tabindex="-1" на всём фокусируемом внутри. Это лечение симптома: узел, разметка и запрос за картинкой останутся, но скринридер его пропустит и табуляция не прокрутит артборд.

Так делает и сама Тильда: на снятой образовательной странице мобильный и настольный варианты одного экрана — два разных блока с классами видимости, а не один блок с увезёнными элементами.

Что это меняет для индексации

Обычный вопрос: «а поисковик не решит, что у меня дублируется текст?» Ответ ровный для обоих способов: текст остаётся в разметке и там, и там. Ни display: none, ни координаты его не убирают, краулер его скачивает. Разница только в том, что скрытый через display: none текст поисковик обычно понижает в вес, а увезённый координатами выглядит как обычный видимый текст.

Практический вывод не про санкции, а про смысл: если у вас на странице два заголовка H1 — один для широкого экрана, один для мобильного, — то в разметке их два независимо от способа сокрытия. Мобильному двойнику лучше быть не <h1>, а <div> с теми же стилями.

Проверка за минуту на своей странице

В консоли на опубликованной странице:

// 1. Кто уехал за пределы артборда. Пустой список — приёма на странице нет.
[...document.querySelectorAll('.t396__artboard .tn-elem')].filter((el) => {
  const board = el.closest('.t396__artboard').getBoundingClientRect();
  const r = el.getBoundingClientRect();
  return r.left > board.right || r.top > board.bottom;
}).map((el) => el.getAttribute('data-elem-type') + ' ' + el.getAttribute('data-elem-id'));

// 2. Что из увезённого попадёт под фокус клавиатурой.
[...document.querySelectorAll('.t396__artboard a, .t396__artboard button')].filter((el) => {
  const board = el.closest('.t396__artboard').getBoundingClientRect();
  return el.getBoundingClientRect().left > board.right;
}).map((el) => el.textContent.trim());

Если первый список не пуст, а второй пуст — приём используется, но по клавиатуре до увезённого не добраться, и это уже терпимо. Если не пуст второй — прокрутка артборда при табуляции у вас есть, и проверить это можно вживую: поставить фокус в адресную строку и нажимать Tab, глядя на первый экран.

Моды из каталога с этим приёмом уживаются: ядро проверяет, попал ли элемент в область видимости, по его настоящей геометрии, а не по факту наличия в разметке. Если нужен эффект, у которого мобильный и настольный варианты ведут себя по-разному, — это работа под задачу, и делается она двумя блоками, а не увезёнными элементами.

Вопросы по этой статье 5

Потому что элемент — это один узел разметки, а не пять. В снятой странице у каждого элемента один набор атрибутов на базовое разрешение и отдельные наборы на 960, 640, 480 и 320 — только числа: координаты, размеры, единицы. Элемента, существующего лишь на одном разрешении, в этой схеме нет чем выразить.