Семантическая разметка

Gridstack.js — библиотека для построения динамических сеточных интерфейсов с возможностью перетаскивания и изменения размеров виджетов. Несмотря на то что основная логика библиотеки связана с JavaScript-поведением и управлением координатами элементов, структура HTML остаётся фундаментом, на котором строится вся система.

Семантическая разметка в контексте Gridstack.js выполняет несколько задач:

  • формирует логическую структуру интерфейса
  • делает код понятным и поддерживаемым
  • улучшает доступность интерфейса
  • упрощает интеграцию с CSS и JavaScript
  • облегчает поддержку и расширение системы виджетов

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


Базовая структура сетки Gridstack

Любой интерфейс Gridstack строится вокруг контейнера сетки и вложенных элементов-виджетов.

Минимальная структура выглядит следующим образом:

<div class="grid-stack">
  <div class="grid-stack-item">
    <div class="grid-stack-item-content">
      Контент
    </div>
  </div>
</div>

Основные элементы структуры

Контейнер сетки

<div class="grid-stack"></div>

Этот элемент является корневым контейнером для всех виджетов. Библиотека инициализирует на нём сеточную систему, управляет позициями элементов и отслеживает взаимодействие пользователя.

Элемент сетки (виджет)

<div class="grid-stack-item"></div>

Каждый такой элемент представляет отдельный блок интерфейса, который можно перемещать и масштабировать.

Контент виджета

<div class="grid-stack-item-content"></div>

Этот контейнер содержит реальное содержимое виджета: графики, таблицы, формы, панели управления и другие компоненты интерфейса.


Использование семантических HTML-элементов внутри виджетов

Gridstack управляет только контейнерами виджетов. Содержимое внутри grid-stack-item-content может использовать полноценную семантическую HTML-структуру.

Пример:

<div class="grid-stack">
  <div class="grid-stack-item">
    <div class="grid-stack-item-content">

      <article class="widget">
        <header class="widget-header">
          <h2>Статистика продаж</h2>
        </header>

        <section class="widget-body">
          <canvas id="sales-chart"></canvas>
        </section>

        <footer class="widget-footer">
          Обновлено: сегодня
        </footer>
      </article>

    </div>
  </div>
</div>

Такой подход обеспечивает:

  • структурированность
  • понятность назначения блоков
  • удобство стилизации
  • лучшую доступность для экранных читалок

Логическая структура виджета

Каждый виджет в сетке может иметь стандартную внутреннюю структуру.

Заголовок

<header class="widget-header">
  <h3>Заголовок виджета</h3>
</header>

Заголовок обычно содержит:

  • название виджета
  • кнопки управления
  • индикаторы состояния

Пример:

<header class="widget-header">
  <h3>Активные пользователи</h3>
  <div class="widget-controls">
    <button>Обновить</button>
    <button>Настройки</button>
  </div>
</header>

Основная область

<section class="widget-body">
</section>

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

  • графики
  • таблицы
  • списки
  • диаграммы
  • текстовая информация

Пример:

<section class="widget-body">
  <ul class="stats">
    <li>Сегодня: 1543</li>
    <li>Вчера: 1489</li>
    <li>Неделя: 10234</li>
  </ul>
</section>

Нижняя часть

<footer class="widget-footer">
</footer>

Используется для:

  • дополнительной информации
  • ссылок
  • временных меток
  • действий

Пример:

<footer class="widget-footer">
  Последнее обновление: 12:40
</footer>

Атрибуты позиционирования Gridstack

Семантика структуры дополняется атрибутами позиционирования, которые определяют положение элементов в сетке.

Основные атрибуты:

Атрибут Назначение
gs-x позиция по горизонтали
gs-y позиция по вертикали
gs-w ширина
gs-h высота

Пример:

<div class="grid-stack">
  <div class="grid-stack-item"
       gs-x="0"
       gs-y="0"
       gs-w="4"
       gs-h="2">
       
    <div class="grid-stack-item-content">
      Контент виджета
    </div>

  </div>
</div>

Такая структура позволяет описывать положение элементов прямо в HTML, что удобно для:

  • серверного рендеринга
  • сохранённых пользовательских макетов
  • статических конфигураций интерфейса

Использование data-атрибутов

Для расширения семантики элементов часто применяются data-* атрибуты.

Пример:

<div class="grid-stack-item"
     gs-x="2"
     gs-y="1"
     gs-w="3"
     gs-h="2"
     data-widget-type="chart"
     data-widget-id="sales">

Назначение таких атрибутов:

  • идентификация типа виджета
  • хранение конфигурации
  • передача данных JavaScript

Пример использования:

const widgets = document.querySelectorAll('.grid-stack-item');

widgets.forEach(widget => {
  const type = widget.dataset.widgetType;
  const id = widget.dataset.widgetId;

  console.log(type, id);
});

Семантика контейнеров интерфейса

В сложных интерфейсах сетка может находиться внутри более крупных структур.

Пример панели управления:

<main class="dashboard">

  <header class="dashboard-header">
    <h1>Панель аналитики</h1>
  </header>

  <section class="dashboard-grid">

    <div class="grid-stack">

      <div class="grid-stack-item" gs-w="4" gs-h="2">
        <div class="grid-stack-item-content">
          Виджет
        </div>
      </div>

    </div>

  </section>

</main>

Семантические элементы помогают определить:

  • область приложения (main)
  • отдельные разделы (section)
  • служебные части (header, footer)

Семантика интерактивных элементов

Внутри виджетов часто располагаются элементы управления.

Правильная семантика:

<button class="refresh-btn">
  Обновить
</button>

Вместо:

<div class="refresh-btn">Обновить</div>

Использование корректных HTML-элементов обеспечивает:

  • доступность
  • правильную навигацию с клавиатуры
  • корректную работу ассистивных технологий

Семантические группы данных

Если виджет отображает структурированные данные, полезно применять соответствующие HTML-элементы.

Таблицы

<table class="data-table">
  <thead>
    <tr>
      <th>Страна</th>
      <th>Пользователи</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Казахстан</td>
      <td>1200</td>
    </tr>
  </tbody>
</table>

Списки

<ul class="activity-list">
  <li>Пользователь зарегистрирован</li>
  <li>Обновление профиля</li>
  <li>Создание отчёта</li>
</ul>

Карточки данных

<section class="metrics">

  <article class="metric">
    <h4>Доход</h4>
    <p>$12 430</p>
  </article>

  <article class="metric">
    <h4>Пользователи</h4>
    <p>5 203</p>
  </article>

</section>

Вложенные сетки (Nested Grids)

Gridstack позволяет создавать сетки внутри виджетов.

Семантическая структура:

<div class="grid-stack">

  <div class="grid-stack-item" gs-w="6" gs-h="4">

    <div class="grid-stack-item-content">

      <section class="nested-dashboard">

        <div class="grid-stack nested-grid">

          <div class="grid-stack-item" gs-w="3" gs-h="2">
            <div class="grid-stack-item-content">
              Внутренний виджет
            </div>
          </div>

        </div>

      </section>

    </div>

  </div>

</div>

Это позволяет строить сложные многоуровневые интерфейсы.


Доступность интерфейса (Accessibility)

Семантическая разметка играет ключевую роль в обеспечении доступности.

ARIA-атрибуты

Для сложных интерфейсов применяются дополнительные атрибуты.

Пример:

<div class="grid-stack-item"
     role="region"
     aria-labelledby="widget-title-1">

  <div class="grid-stack-item-content">

    <h3 id="widget-title-1">
      График продаж
    </h3>

  </div>

</div>

Это позволяет экранным читалкам правильно интерпретировать структуру страницы.


Управление с клавиатуры

Для элементов управления важно использовать правильные HTML-теги.

Пример:

<button aria-label="Закрыть виджет">
  ×
</button>

Разделение структуры и поведения

Семантическая разметка должна описывать структуру интерфейса, а не поведение.

Правильный подход:

<button class="widget-refresh">
  Обновить
</button>

Jav * aScript:

document
  .querySelector('.widget-refresh')
  .addEventListener('click', refreshWidget);

Неправильный подход:

<button oncl ick="refreshWidget()">
  Обновить
</button>

Такое разделение:

  • улучшает поддержку кода
  • упрощает тестирование
  • делает архитектуру интерфейса чище

Расширяемость структуры

Семантическая структура облегчает масштабирование интерфейса.

Пример расширяемого виджета:

<article class="widget widget-chart">

  <header class="widget-header">
    <h3>Трафик сайта</h3>
  </header>

  <section class="widget-body">
    <canvas></canvas>
  </section>

  <footer class="widget-footer">
    <button class="details-btn">
      Подробнее
    </button>
  </footer>

</article>

В дальнейшем можно добавить:

  • панель фильтров
  • режим полноэкранного отображения
  • дополнительные действия

Структура остаётся понятной и легко расширяется.


Рекомендуемый шаблон виджета Gridstack

Типовой шаблон:

<div class="grid-stack-item"
     gs-x="0"
     gs-y="0"
     gs-w="4"
     gs-h="2">

  <div class="grid-stack-item-content">

    <article class="widget">

      <header class="widget-header">
        <h3>Название виджета</h3>
      </header>

      <section class="widget-body">
        Основной контент
      </section>

      <footer class="widget-footer">
        Дополнительная информация
      </footer>

    </article>

  </div>

</div>

Такая структура:

  • хорошо читается
  • легко стилизуется
  • удобно интегрируется с Gridstack.js
  • поддерживает сложные интерфейсы дашбордов.