Система классов и атрибуты в Markdown
Содержание
Расширение attr_list позволяет добавлять CSS-классы, ID и атрибуты прямо из Markdown. В гайде — полный список классов и примеры. Под каждым блоком кода сразу показан результат рендера (HTML, который вы получите).
Два синтаксиса
Инлайн (сразу после элемента)
Атрибуты в {} ставятся сразу после ссылки или картинки:
[Ссылка](https://example.com){ .btn }
Результат:
Блочные (на отдельной строке)
Для абзацев и других блоков выражение {...} ставится на строку сразу после текста:
Текст абзаца
{.center .lead}
Результат:
Текст абзаца
Важно
{.class} на той же строке, что и текст, для блоков не работает — только на отдельной строке.
Заголовки
Для заголовков используется синтаксис с {:} — классы и ID пишутся в самих скобках:
### Заголовок {: #my-id .accent }
Результат:
Заголовок
Инлайн-спан: покрасить слово без em/strong
{.класс} цепляется только к элементу. Покрасить «голое» слово нельзя — но
есть нейтральный инлайн-носитель: текст в двойных процентах создаёт <span>
без собственных стилей, классы вешаются как обычно:
Обычный текст %%внимание%%{.accent}, а это %%второстепенное%%{.muted}.
Результат:
Обычный текст внимание, а это второстепенное
Несколько классов, вложенная разметка, непарные проценты и код:
%%два класса%%{.muted .small}
%%жирный **b** внутри%%{.info}
Скидка 50% — одиночный процент синтаксис не ломает.
Код с ``%%x%%`` внутри — спан не начнётся.
Результат:
два класса
жирный b внутри
Скидка 50% — одиночный процент синтаксис не ломает.
Код с %%x%% внутри — спан не начнётся.
Типографика
Крупный текст (lead)
Важный вводный абзац
{.lead}
Результат:
Важный вводный абзац
Мелкий текст (small) и text-sm
Подпись или примечание
{.small .muted}
Ещё мельче — заданная высота
{.text-sm .muted}
Результат:
Подпись или примечание
Ещё мельче — заданная высота
Крупный текст (text-lg)
Крупная строка
{.text-lg}
Результат:
Крупная строка
Нормальный размер (text-normal)
Возврат к обычному (наследуемому) размеру — полезен, когда родительский контейнер крупнее/мельче, а фрагмент должен быть как основной текст:
Параграф крупный, а %%эта часть%%{.text-normal} обычного размера
Результат:
Параграф крупный, а эта часть обычного размера
Размеры заголовков (h1-h6)
Кегли заголовков как утилиты: тот же размер и начертание, что у настоящих
h1–h6, но носитель остаётся инлайновым (не становится блоком). Полезно
для акцентной строки или иконки-«крупнее». Все размеры в rem — масштабируются
кнопкой «Аа».
%%Крупный акцент%%{.h1}
%%Заголовок-иконка%%{.h2 .accent}
%%Средний%%{.h3}
Результат:
Крупный акцент
Заголовок-иконка
Средний
Моноширинный (mono)
const x = 42;
{.mono}
Результат:
const x = 42;
Жирный (bold) и курсив (italic)
**Жирный текст**
{.bold}
Результат (двойное начертание: и разметка, и класс):
Жирный текст
Курсивный текст
{.italic}
Результат:
Курсивный текст
Заглавные буквы (uppercase)
Срочное сообщение
{.bold .uppercase}
Результат:
Срочное сообщение
Обрезка длинного текста (nowrap / ellipsis)
ellipsis требует ограниченной ширины — поэтому задаём max-width через атрибут style:
Очень длинный заголовок, который надо обрезать многоточием
{.ellipsis style="max-width: 260px"}
Результат:
Очень длинный заголовок, который надо обрезать многоточием
nowrap запрещает перенос строки — полезен в таблицах и флекс-строках:
Не переносить на новую строку
{.nowrap}
Результат:
Не переносить на новую строку
Подчёркивание (underline)
Подчёркнутый текст
{.underline}
Результат:
Подчёркнутый текст
Цвет текста
Все цвета заданы CSS-переменными и автоматически адаптируются к светлой/тёмной теме:
Акцентный текст
{.accent}
Опасность
{.danger}
Успех
{.success}
Предупреждение
{.warning}
Информация
{.info}
Приглушённый
{.muted}
Основной текст темы
{.fg}
Инверсия: цвет текста = цвет фона темы
{.fgi}
Результат:
Акцентный текст
Опасность
Успех
Предупреждение
Информация
Приглушённый
Основной текст темы
Инверсия: цвет текста = цвет фона темы
Выравнивание
По левому краю
{.left}
По центру
{.center}
По правому краю
{.right}
Между краями. Этот текст выровнен по ширине — слова распределяются равномерно между левым и правым краем. Хорошо работает для длинных абзацев с переносами строк.
{.justify}
Результат:
По левому краю
По центру
По правому краю
Между краями. Этот текст выровнен по ширине — слова распределяются равномерно между левым и правым краем. Хорошо работает для длинных абзацев с переносами строк.
Фоновые блоки
Карточка (bg-card)
Содержимое карточки
{.bg-card}
Результат:
Содержимое карточки
Акцентный блок (bg-accent)
Важное сообщение на акцентном фоне
{.bg-accent}
Результат:
Важное сообщение на акцентном фоне
Цветные блоки
Успешная операция
{.bg-success}
Ошибка при загрузке
{.bg-danger}
Предупреждение пользователя
{.bg-warning}
Результат:
Успешная операция
Ошибка при загрузке
Предупреждение пользователя
Информационный блок (bg-info)
Полезное замечание
{.bg-info}
Результат:
Полезное замечание
Приглушённый фон (bg-muted)
Второстепенная информация
{.bg-muted}
Результат:
Второстепенная информация
Все .bg-* блоки используют CSS-переменные и адаптируются к теме автоматически.
Фон темы (bg)
Фон совпадает с фоном страницы (var(--bg)) — полезен, чтобы «сбросить» вложенный блок к общему фону:
Блок на фоне темы
{.bg}
Результат:
Блок на фоне темы
Инверсия (bgi)
Инверсия по вертикали: цвет фона = цвет текста темы (var(--fg)), а текст — наоборот. Читается только в паре с инвертированным цветом текста .fgi:
Инвертированная плашка
{.bgi .fgi}
Результат:
Инвертированная плашка
Фон блока кода (bg-code)
Особый случай: фон совпадает с фоном блоков кода и зависит от выбранной темы кода (админка → SiteSettings → code_theme) и от светлой/тёмной темы оформления. Цвет текста тоже подхватывается из темы кода, поэтому класс читаем даже на тёмных темах вроде monokai.
Текст на фоне темы кода
{.bg-code}
Результат:
Текст на фоне темы кода
Типичный приём — парные колонки «код → результат»: каждой колонке {.border-card .bg-code}, а блоку кода внутри — {.border-0}. Обе половины получаются одного цвета и размера.
Пример:
````columns
{: .border-card .bg-code}
```python {: .border-0}
def f(x):
return x + 1
```
:::
{: .border-card .bg-code}
Правая колонка живёт на том же фоне, что и код
````
Результат:
def f(x):
return x + 1
Правая колонка живёт на том же фоне, что и код
Границы
Карточка с рамкой (border-card)
Контент внутри рамки
{.border-card}
Результат:
Контент внутри рамки
Акцентная полоска слева (border-left)
Цитата или выделенный блок
{.border-left}
Результат:
Цитата или выделенный блок
Цветные полоски
Важное
{.border-left .danger}
Подсказка
{.border-left .success}
Заметка
{.border-left .info}
Результат:
Важное
Подсказка
Заметка
Скруглённые углы и тень
Карточка с тенью
{.border-card .shadow .rounded}
Результат:
Карточка с тенью
Рамка (border)
Простая рамка
{.border .p-md}
Результат:
Простая рамка
Скругления (rounded)
Малое скругление
{.border-card .rounded-sm}
Среднее скругление
{.border-card .rounded}
Большое скругление
{.border-card .rounded-lg}
Результат:
Малое скругление
Среднее скругление
Большое скругление
Тени
Малая тень
{.border-card .shadow-sm}
Обычная тень
{.border-card .shadow}
Большая тень
{.border-card .shadow-lg}
Результат:
Малая тень
Обычная тень
Большая тень
Отступы
Шкала размеров: 0 — 0px, sm — 8px, md — 16px, lg — 24px.
| Префикс | Куда применяется |
|---|---|
m-* / p-* |
со всех сторон |
mt-* / pt-* |
сверху |
mr-* / pr-* |
справа |
mb-* / pb-* |
снизу |
ml-* / pl-* |
слева |
mx-* / px-* |
по горизонтали (слева и справа) |
my-* / py-* |
по вертикали (сверху и снизу) |
mx-auto |
центрирование блока по горизонтали |
Пример — внешний отступ со всех сторон и внутренний по центру:
Это блок с отступом p-md
{.p-md .m-md .center .bg-card}
Результат:
Это блок с отступом p-md
Отступ только сверху у заголовка:
### Заголовок {: .mt-0 }
Результат:
Заголовок
Убрать отступ у кнопки после карточки:
[Подписаться](#){ .btn .btn-lg .mt-0 }
Результат:
Отображение и доступность
inline-block
Строчно-блочный элемент: и текст, и блок занимают одну строку рядом друг с другом:
Обычный текст и <span class="inline-block bg-success" style="border-radius: 6px; padding: 2px 8px">блочный сосед</span> в одной строке.
Результат:
Обычный текст и блочный сосед в одной строке.
hidden и sr-only
Скрыть элемент (display: none)
{.hidden}
Только для скринридеров (визуально скрыто, но доступно)
{.sr-only}
Результат: оба элемента скрыты — на странице их не видно. sr-only при этом остаётся доступным для программ чтения с экрана.
Кнопки
Одиночная кнопка
[Кнопка](https://example.com){ .btn }
Результат:
Размеры
Каждая ссылка-кнопка на отдельной строке превращается в свой абзац:
[Маленькая](#){ .btn .btn-sm }
[Обычная](#){ .btn }
[Большая](#){ .btn .btn-lg }
Результат:
Чтобы поставить кнопки в ряд, оборачиваем их в флекс-контейнер (d-flex, см. раздел «Флекс»):
<div class="d-flex gap-sm">
<a class="btn btn-sm" href="#">Маленькая</a>
<a class="btn" href="#">Обычная</a>
<a class="btn btn-lg" href="#">Большая</a>
</div>
Результат:
Цвета и варианты
[Основная](#){ .btn }
[Опасность](#){ .btn .btn-danger }
[Успех](#){ .btn .btn-success }
[Внимание](#){ .btn .btn-warning }
[Контурная](#){ .btn .btn-outline }
Результат:
Комбинации
[Большая контурная](#){ .btn .btn-lg .btn-outline }
[Маленькая зелёная](#){ .btn .btn-sm .btn-success }
Результат:
Неактивная (disabled)
Класс .btn-disabled (или атрибут disabled для <button>) — фон приглушён, курсор not-allowed, клик не сработает:
[Недоступно](#){ .btn .btn-disabled }
Результат:
В ряд с другими вариантами:
<div class="d-flex gap-sm">
<a class="btn btn-disabled" href="#">Недоступно</a>
<a class="btn btn-outline btn-disabled" href="#">Контурная disabled</a>
<button class="btn" disabled>Кнопка disabled</button>
</div>
Результат:
Пример из интерфейса: в кабинете у черновиков кнопка «Открыть» показывается серой:
<a class="btn btn-sm btn-disabled" href="/p/draft-slug/" aria-disabled="true">Открыть</a>
Флекс и грид
Флекс-контейнер
.flex — чистый флекс (только display: flex). Отступы между элементами задаём через gap-*:
<div class="flex gap-md">
<div class="bg-card">Элемент 1</div>
<div class="bg-card">Элемент 2</div>
<div class="bg-card">Элемент 3</div>
</div>
Результат:
d-flex — с отступами и центровкой сразу
То же, но gap 12px и вертикальное центрирование уже встроены:
<div class="d-flex">
<div class="bg-card">Элемент 1</div>
<div class="bg-card">Элемент 2</div>
</div>
Результат:
По центру
<div class="flex flex-center">
<div class="bg-card">Центр</div>
</div>
Результат:
Между краями
<div class="flex-between">
<div class="bg-card">Лево</div>
<div class="bg-card">Право</div>
</div>
Результат:
Колонка
<div class="flex flex-col gap-sm">
<div class="bg-card">Блок 1</div>
<div class="bg-card">Блок 2</div>
</div>
Результат:
Выравнивание по вертикали (items-*)
<div class="d-flex items-start">
<div class="bg-card">Сверху</div>
<div class="bg-card">Тоже сверху</div>
</div>
Результат:
<div class="d-flex items-center">
<div class="bg-card">По центру</div>
<div class="bg-card">По центру</div>
</div>
Результат:
<div class="d-flex items-end">
<div class="bg-card">Снизу</div>
<div class="bg-card">Снизу</div>
</div>
Результат:
Распределение по горизонтали (justify-*)
<div class="d-flex justify-start">
<div class="bg-card">Слева</div>
<div class="bg-card">Слева</div>
</div>
Результат:
<div class="d-flex justify-center">
<div class="bg-card">По центру</div>
<div class="bg-card">По центру</div>
</div>
Результат:
<div class="d-flex justify-end">
<div class="bg-card">Справа</div>
<div class="bg-card">Справа</div>
</div>
Результат:
Растягивание и сжатие (flex-1 / grow-0 / shrink-0)
flex-1 — элемент растягивается и занимает свободное место; shrink-0 — не сжимается; grow-0 — не растёт:
<div class="d-flex">
<div class="bg-card flex-1">Тянется</div>
<div class="bg-card shrink-0">Не сжимается</div>
<div class="bg-card grow-0">Не растёт</div>
</div>
Результат:
Перенос и отступы (flex-wrap / gap-*)
<div class="flex flex-wrap gap-lg">
<div class="bg-card">Тег</div>
<div class="bg-card">Тег</div>
<div class="bg-card">Тег</div>
<div class="bg-card">Тег</div>
</div>
Результат:
Грид
Две колонки (grid-2)
<div class="grid-2">
<div class="bg-card">Колонка 1</div>
<div class="bg-card">Колонка 2</div>
</div>
Результат:
Три колонки (grid-3)
<div class="grid-3">
<div class="bg-card">Колонка 1</div>
<div class="bg-card">Колонка 2</div>
<div class="bg-card">Колонка 3</div>
</div>
Результат:
Ширина
Классы ширины работают внутри флекс- или грид-контейнеров:
<div class="d-flex">
<div class="bg-card w-half">50%</div>
<div class="bg-card w-half">50%</div>
</div>
Результат:
<div class="d-flex">
<div class="bg-card w-third">33%</div>
<div class="bg-card w-two-thirds">67%</div>
</div>
Результат:
<div class="d-flex">
<div class="bg-card w-quarter">25%</div>
<div class="bg-card w-three-quarters">75%</div>
</div>
Результат:
Центрирование блока фиксированной ширины через mx-auto:
<div class="w-half mx-auto bg-card">Центрированный блок 50%</div>
Результат:
Адаптивность
На экранах уже 640px все колонки и блоки с фиксированной шириной становятся на всю ширину — грид и флекс автоматически перестраиваются в одну колонку.
Пропорции (.ar-W-H)
Классы соотношения ширины к высоте (CSS aspect-ratio): высота элемента считается из ширины по заданной пропорции — без JS и без фиксированных пикселей. Годятся для .box, карточек cards, обложек, картинок.
<div class="d-flex">
<div class="ar-1-1 bg-card border rounded" style="flex: 1">Квадрат</div>
<div class="ar-16-9 bg-card border rounded" style="flex: 1">Видео</div>
<div class="ar-4-1 bg-card border rounded" style="flex: 1">Баннер</div>
</div>
Результат:
| Класс | Пропорция |
|---|---|
.ar-1-1 |
1:1 |
.ar-3-2 |
3:2 |
.ar-4-3 |
4:3 |
.ar-16-9 |
16:9 |
.ar-9-16 |
9:16 |
.ar-21-9 |
21:9 |
.ar-4-1 |
4:1 |
.ar-4-5 |
4:5 |
.ar-2-3 |
2:3 |
Для картинки класс вешается прямо на <img> и комбинируется со стилем object-fit: cover (кадрирование вместо растягивания):
{: .ar-16-9 style="width:100%;object-fit:cover" }
Графики mermaid/vega
.ar-* задаёт рамку контейнера, а на фенсе vega ещё и пропорции
самого графика: высота пересчитывается от реальной ширины, а числовые
width/height из спеки перекрываются. С mermaid SVG по-прежнему
рисует свою высоту — класс на них не влияет.
Пропорция для vega — класс на открывающей строке фенса (тот же attr_list):
```vega {: .ar-16-9}
{
"data": {"values": [{"x": 1, "y": 3}, {"x": 2, "y": 1}, {"x": 3, "y": 4}]},
"mark": "bar",
"encoding": {
"x": {"field": "x", "type": "ordinal"},
"y": {"field": "y", "type": "quantitative"}
}
}
```
Живой пример — высота уже не фиксированные 230px, а честные 16:9 от ширины:
Отказ от автоматики (.zoom-0 / .code-0)
Классы-выключатели механик на самом элементе или его обёртке.
zoom-0 — без зума
Отключает zoom.js для картинок/mermaid и кнопку «Развернуть» у .vega-chart:
{: .zoom-0 }
code-0 — без копирования кода
Отключает копи-кнопку у блока кода, а у ```vega``` — кнопку «Код» и копирование спеки на панели JSON:
```python {: .code-0 }
print("без копи-кнопки")
```
Класс можно вешать и на обёртку (например card/box), чтобы отключить копирование у всех блоков кода внутри.
Разделитель (divider)
То же самое дают --- (markdown) и <hr class="divider">. Класс пригодится,
когда нужен разделитель без пустой строки вокруг (например внутри таблиц или
блоков):
Текст выше
<hr class="divider">
Текст ниже
Результат:
Текст выше
Текст ниже
Таблицы (.t-*)
attr_list не может повесить класс на саму таблицу: table, thead, tbody и tr — «неявные» элементы, которых нет в тексте Markdown (классы цепляются только к ячейкам th/td). Поэтому оформление таблиц работает через обёртку: классы .t-* ставятся на фенс box, а CSS применяет их ко всем таблицам внутри контейнера. Обычная таблица уже рисуется с рамками по умолчанию — .t-bordered включает их явно (и даёт чуть больше воздуха в ячейках), .t-border-0 убирает.
| Класс | Действие |
|---|---|
.t-bordered |
Рамки ячеек 1px, просторнее ячейки |
.t-border-0 |
Полностью убрать рамки |
.t-header-same |
Шапка в тон теме сайта |
.t-header-inverse |
Шапка, обратная теме сайта |
.t-stripe |
Фон чётных строк (лёгкий) |
.t-stripe-strong |
Фон чётных строк (плотнее) |
.t-row-danger |
Красная строка (удаление/ошибка) |
.t-row-success |
Зелёная строка (успех) |
.t-row-warning |
Жёлтая строка (предупреждение) |
.t-row-info |
Голубая строка (информация) |
Семантические классы .t-row-* ставятся на box-обёртку (как и остальные .t-*), окрашивают все ячейки строки. Перекрывают .t-stripe без !important — karena td с явным background переопределяет наследование от tr.
Полный набор
````box {: .t-bordered .t-header-same .t-stripe }
| Планета | Спутники | Кольца | Первый спутник |
|---------|----------|--------|----------------|
| Земля | 1 | нет | Луна |
| Марс | 2 | нет | Фобос |
| Юпитер | 95 | слабые | Ганимед |
| Сатурн | 146 | яркие | Титан |
````
Результат:
| Планета | Спутники | Кольца | Первый спутник |
|---|---|---|---|
| Земля | 1 | нет | Луна |
| Марс | 2 | нет | Фобос |
| Юпитер | 95 | слабые | Ганимед |
| Сатурн | 146 | яркие | Титан |
Шапка: в тон теме и наоборот
.t-header-same — шапка совпадает по светлоте с темой сайта: в светлой теме тёмный текст на чуть затемнённом фоне, в тёмной — светлый на чуть осветлённом. .t-header-inverse — зеркально: в светлой теме светлая шапка на тёмном фоне, в тёмной — тёмная на светлом. Рамка шапки красится в тон её фона. Переключите тему сайта (иконка в шапке) — обе таблицы перестроятся на лету:
````box {: .t-bordered .t-header-same }
| Метод | Путь | Статус |
|-------|------|--------|
| GET | /p/`<slug>`/ | 200 |
| POST | /comments/ | 302 |
| DELETE | /p/`<slug>`/ | 403 |
````
Результат:
| Метод | Путь | Статус |
|---|---|---|
| GET | /p/<slug>/ |
200 |
| POST | /comments/ | 302 |
| DELETE | /p/<slug>/ |
403 |
````box {: .t-bordered .t-header-inverse }
| Метод | Путь | Статус |
|-------|------|--------|
| GET | /p/`<slug>`/ | 200 |
| POST | /comments/ | 302 |
| DELETE | /p/`<slug>`/ | 403 |
````
Результат:
| Метод | Путь | Статус |
|---|---|---|
| GET | /p/<slug>/ |
200 |
| POST | /comments/ | 302 |
| DELETE | /p/<slug>/ |
403 |
Полосы (зебра)
.t-stripe — лёгкий фон чётных строк (был в «полном наборе»), .t-stripe-strong — плотнее. Зебра помогает не терять строку глазами в длинных таблицах:
````box {: .t-bordered .t-header-inverse .t-stripe-strong }
| Статья | Просмотров | Комментарии |
|--------|------------|--------------|
| Markdown-гайд | 1204 | 18 |
| Mermaid-темы | 987 | 9 |
| Эмодзи-коды | 832 | 4 |
| Класс O | 645 | 7 |
````
Результат:
| Статья | Просмотров | Комментарии |
|---|---|---|
| Markdown-гайд | 1204 | 18 |
| Mermaid-темы | 987 | 9 |
| Эмодзи-коды | 832 | 4 |
| Класс O | 645 | 7 |
Без рамок
.t-border-0 убирает рамки — таблица держится только на шапке и зебре:
````box {: .t-border-0 .t-header-same .t-stripe }
| Тема кода | Светлая | Тёмная |
|-----------|---------|--------|
| github | да | да |
| monokai | нет | да |
| nord-dark | нет | да |
````
Результат:
| Тема кода | Светлая | Тёмная |
|---|---|---|
| github | да | да |
| monokai | нет | да |
| nord-dark | нет | да |
Семантические строки
````box {: .t-bordered .t-header-same .t-row-danger }
| Статус | Описание |
|--------|----------|
| Ошибка | Сервер недоступен |
| ОК | Всё хорошо |
````
Результат:
| Статус | Описание |
|---|---|
| Ошибка | Сервер недоступен |
| ОК | Всё хорошо |
Сочетаются с другими классами: {: .t-bordered .t-header-inverse .t-stripe .t-row-success }.
Широкие таблицы
.h-scroll включает горизонтальную прокрутку контейнера без сжатия (min-width: max-content) — для таблиц и блоков кода, которые лучше читать несжатыми:
````box {: .h-scroll }
| Очень | широкая | таблица |… | которая | не | сжимается | а | скроллится |
|---|---:|---:|---:|---:|---:|---:|---:|---:|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
````
Результат — таблица сохраняет естественную ширину, в нижней части появляется горизонтальный скролл (на мобильном — всегда, на десктопе если не влезает):
| Очень | широкая | таблица | … | которая | не | сжимается | а | скроллится |
|---|---|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
.t-* сочетаются с .h-scroll: {: .h-scroll .t-bordered .t-header-inverse .t-stripe }. Есть варианты .h-scroll-narrow (скролл только ≤640px) и .h-scroll-wide (только ≥641px).
Комбинированные примеры
Заголовок по центру с акцентом
### Контакты {: #contacts .center .accent }
Результат:
Контакты
Блок-цитата с полоской
> Важная мысль
{.border-left .accent}
Результат:
Важная мысль
Карточка с заголовком и кнопкой
<div class="border-card p-lg center">
<h3 class="mt-0">Подписка</h3>
<p class="small muted mb-lg">Получайте уведомления о новых статьях</p>
<div class="mt-lg"><a class="btn btn-lg" href="#">Подписаться</a></div>
</div>
Результат:
Три карточки в гриде
<div class="grid-3">
<div class="border-card"><strong>Фича 1</strong><br>Описание</div>
<div class="border-card"><strong>Фича 2</strong><br>Описание</div>
<div class="border-card"><strong>Фича 3</strong><br>Описание</div>
</div>
Результат:
Описание
Описание
Описание
Плашка-предупреждение
Admonition с типом danger уже имеет красный стиль — дополнительный класс не нужен:
!!! danger "Не публикуйте ключи"
Используйте переменные окружения.
Результат:
Не публикуйте ключи
Используйте переменные окружения.
Врезки (обтекание, float)
Карточка или картинка прижимается к краю и обтекается текстом абзацев. Ширина задаётся отдельным классом (.w-third, .w-quarter, .w-half). Перед следующим полноширинным блоком — заголовком секции, кодом или таблицей — обычно нужен {: .clear }, иначе блок встанет рядом с незаконченной врезкой.
```box {: .float-right .w-third .bg-card .border .rounded }
Врезка: плашка прижата вправо, текст обтекает её слева
```
Текст статьи идёт в одну колонку и обтекает врезку. Чтобы оборвать обтекание перед следующей секцией — `{: .clear }` на заголовке.
{: .float-left .w-quarter }
Картинка-врезка слева с шириной `.w-quarter`.
Результат:
Абзац, который обтекает врезку справа-слева: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.
Второй абзац продолжает обтекание, пока врезка не закончится.
На телефоне (≤640px)
Флоат автоматически гасится: врезка становится обычным блоком на всю ширину (там же, где .w-* → 100%).
Вписывание медиа (.fit-*)
Классы для картинок/видео: как элемент вписывается в свой слот. Потоковые — по одной оси, боксовые — заполняют слот целиком.
| Класс | Поведение |
|---|---|
.fit-w |
По ширине: width:100%; height:auto (пропорции держатся) |
.fit-h |
По высоте слота: width:auto; height:100% (без искажений) |
.fit-cover |
Заполнить слот, кадрируя (объект-фит cover) |
.fit-contain |
Заполнить слот целиком, с полями (contain) |
.fit-fill |
Заполнить слот, растянув (fill, искажает) |
Важно: у .fit-h, .fit-cover, .fit-contain, .fit-fill нужен слот с определённой высотой — .ar-*-бокс или фикс-высота. Иначе height:100% схлопывается в auto, и картинка просто встаёт по ширине.
.fit-slot на слот-боксе. Класс растягивает содержимое на высоту слота, обнуляет паддинг (картинка заполняет панель край-в-край — рамка симметрична) и обрезает переполнение (overflow: hidden). Механика селекторами по потомкам слота — zoom.js оборачивает каждую картинку в span.zoom-wrap (кнопку-лупу), поэтому прямой > img не сработает; баг проявлялся как «картинка во всю ширину, видна верхняя половина».
```box {: .fit-slot .ar-16-9 .bg-card .border .rounded }
{: .fit-cover }
```
Такой приём даёт кроп 16:9 из любой картинки.
На ≤640px
Флоат-классы гаснуть, .fit-* — нет: вертикальный слот (.ar-2-3-бокс) честно держит высоту и на телефоне, .fit-h работает там же.
Табы (tabbed): как убрать паддинг вокруг кода
У блоков кода внутри табов своя особенность: у каждого таба есть свой контейнер .tabbed-content с внутренним отступом и верхней линией. Классами из attr_list (вроде {.p-0} или {.border-0}) вы можете убрать рамку/отступ самого кода, но не паддинг таба — до него attr_list не дотягивается. Если фон кода отличается от фона таба, вы увидите поле цвета таба вокруг кода.
Вариант 1: <style> + :has() (рекомендуемый)
Вставьте <style> в начало статьи и убирайте рамку/отступ точечно — правило сработает только для табов, внутри которых есть код с классом .border-0:
<style>
.tabbed-content:has(div.highlight.border-0) { padding: 0; }
</style>
Пример — первый таб с {.border-0 .p-0}, второй обычный:
=== "Python"
```{.python .border-0 .p-0}
print('привет')
```
=== "Обычный код (с рамкой)"
```python
print('остаётся с отступами таба')
```
Вот этот же пример вживую (стиль уже применён):
Результат:
print('привет')
print('остаётся с отступами таба')
Обратите внимание: первый таб — код прижат к границам таба, без фона-поля; у второго рамка и отступы таба сохранены.
Без :has() правило применится ко всем табам в статье:
<style>
.tabbed-content { padding: 0; }
</style>
Вариант 2: без CSS — подобрать фон
Если рамка мешает только зазором по вертикали, можно не убирать паддинг, а подобрать тему кода (code_theme в SiteSettings) так, чтобы фон кода совпадал с фоном таба. Тогда граница визуально исчезает, а отступы таба остаются.
Почему attr_list не работает
attr_list цепляет класс к элементу, после которого стоит {.…}. У кода в табе это обёртка div.highlight, а контейнер .tabbed-content создаётся самим расширением tabbed выше по дереву — до него атрибут дойти не может. Поэтому единственный способ — CSS-селектор по родителям.
Полный список классов
Типографика
| Класс | Описание |
|---|---|
.lead |
Крупный текст (1.25em, medium) |
.small |
Мелкий текст (0.85em) |
.text-sm |
Мелкий текст (0.85em) |
.text-normal |
Обычный (наследуемый) размер, 1em |
.text-lg |
Крупный текст (1.15em) |
.h1 … .h6 |
Кегль и начертание заголовков h1–h6 (2rem…0.875rem, 600): инлайн-носитель, не блок |
.mono |
Моноширинный шрифт |
.bold |
Жирный |
.italic |
Курсив |
.uppercase |
Заглавные буквы |
.nowrap |
Без переноса строк |
.ellipsis |
Обрезка одной строки с многоточием |
.underline |
Нейтральное подчёркивание (1.5px, offset 3px) |
.divider |
Горизонтальный разделитель (тождествен ---; вид <hr class="divider"> для обёртки) |
Цвета
Все цвета через CSS-переменные, адаптируются к теме.
| Класс | Переменная |
|---|---|
.fg |
var(--fg) (основной текст темы) |
.fgi |
var(--bg) (инверсия: цвет как фон темы) |
.accent |
var(--accent) |
.muted |
var(--muted) |
.danger |
var(--danger) |
.success |
var(--success) |
.warning |
var(--warning) |
.info |
var(--info) |
Фоны
| Класс | Описание |
|---|---|
.bg |
Фон страницы (var(--bg)) |
.bgi |
Инверсия: фон как цвет текста (var(--fg)); текст — .fgi |
.bg-card |
Серый фон (как карточки), padding 12px 16px |
.bg-accent |
Акцентный фон, белый текст |
.bg-danger |
Красный фон |
.bg-success |
Зелёный фон |
.bg-warning |
Жёлтый фон |
.bg-info |
Информационный блок (светло-голубой/тёмно-синий) |
.bg-muted |
Приглушённый фон (чуть темнее/светлее card-bg) |
.bg-code |
Фон и цвет текста как у блоков кода (зависит от темы кода) |
Выравнивание
| Класс | Описание |
|---|---|
.left |
По левому краю |
.center |
По центру |
.right |
По правому краю |
.justify |
По ширине |
Отступы
Шкала: 0 (0px) / sm (8px) / md (16px) / lg (24px).
| Префикс | Сторона |
|---|---|
m-* / p-* |
все стороны |
mt-* / pt-* |
сверху |
mr-* / pr-* |
справа |
mb-* / pb-* |
снизу |
ml-* / pl-* |
слева |
mx-* / px-* |
по горизонтали |
my-* / py-* |
по вертикали |
mx-auto |
автоцентрирование по горизонтали |
Кнопки
| Класс | Описание |
|---|---|
.btn |
Базовая кнопка |
.btn-sm |
Маленькая |
.btn-lg |
Большая |
.btn-outline |
Контурная |
.btn-danger |
Красная |
.btn-success |
Зелёная |
.btn-warning |
Янтарная |
.btn-disabled / :disabled |
Неактивная |
Границы
| Класс | Описание |
|---|---|
.border-card |
Рамка с фоном, скруглением и padding |
.border |
Простая рамка 1px |
.border-0 |
Без рамки |
.border-left |
Акцентная полоска слева |
.border-left.danger |
Красная полоска |
.border-left.success |
Зелёная полоска |
.border-left.warning |
Жёлтая полоска |
.border-left.info |
Голубая полоска |
.rounded-sm |
Скругление 6px |
.rounded |
Скругление 12px |
.rounded-lg |
Скругление 16px |
.shadow-sm |
Малая тень |
.shadow |
Обычная тень |
.shadow-lg |
Большая тень |
Флекс и грид
| Класс | Описание |
|---|---|
.flex |
Чистый флекс (display: flex) |
.d-flex |
Флекс с gap 12px и align-items: center |
.flex-col |
Колонка |
.flex-wrap |
Перенос |
.flex-between |
Между краями |
.flex-center |
По центру |
.flex-1 |
Растягивается, заполняет место |
.grow-0 |
Не растёт |
.shrink-0 |
Не сжимается |
.items-start / .items-center / .items-end |
Выравнивание по вертикали |
.justify-start / .justify-center / .justify-end |
Выравнивание по горизонтали |
.gap-sm |
gap 4px |
.gap-md |
gap 12px |
.gap-lg |
gap 20px |
.grid-2 |
Две колонки |
.grid-3 |
Три колонки |
Ширина
| Класс | Размер |
|---|---|
.w-full |
100% |
.w-half |
50% |
.w-third |
33% |
.w-two-thirds |
67% |
.w-quarter |
25% |
.w-three-quarters |
75% |
Таблицы
Классы .t-* ставятся на обёртку (фенс box), не на саму таблицу.
| Класс | Описание |
|---|---|
.t-bordered |
Рамки ячеек 1px, просторнее ячейки |
.t-border-0 |
Без рамок |
.t-header-same |
Шапка в тон теме сайта |
.t-header-inverse |
Шапка, обратная теме |
.t-stripe |
Зебра (лёгкий фон чётных строк) |
.t-stripe-strong |
Зебра (плотный фон чётных строк) |
.t-row-danger |
Красная строка (перекрывает страйп) |
.t-row-success |
Зелёная строка (перекрывает страйп) |
.t-row-warning |
Жёлтая строка (перекрывает страйп) |
.t-row-info |
Голубая строка (перекрывает страйп) |
Пропорции (.ar-*)
Аспект-соотношение ширины к высоте через CSS aspect-ratio:
| Класс | Описание |
|---|---|
.ar-1-1 |
Квадрат 1:1 |
.ar-3-2 |
Фото 3:2 |
.ar-4-3 |
Экран 4:3 |
.ar-16-9 |
Видео 16:9 |
.ar-9-16 |
Мобильный портрет 9:16 |
.ar-21-9 |
Панорама 21:9 |
.ar-4-1 |
Баннер 4:1 (обложки) |
.ar-4-5 |
Портрет 4:5 |
.ar-2-3 |
Портрет 2:3 |
Врезки
Обтекание текстом (флоат):
| Класс | Описание |
|---|---|
.float-left |
Прижать влево, текст обтекает справа (margin-right 20px) |
.float-right |
Прижать вправо, текст обтекает слева (margin-left 20px) |
.clear |
Оборвать обтекание (clear: both); на ≤640px флоат гасится сам |
Вписывание медиа (.fit-*)
| Класс | Описание |
|---|---|
.fit-w |
По ширине (width:100%; height:auto) |
.fit-h |
По высоте слота (width:auto; height:100%, без искажений) |
.fit-cover |
Заполнить слот с кадрированием (object-fit: cover) |
.fit-contain |
Заполнить слот целиком, с полями (contain) |
.fit-fill |
Заполнить слот растяжением (fill) |
Отображение и доступность
| Класс | Описание |
|---|---|
.hidden |
Скрыть (display: none) |
.inline |
display: inline |
.inline-block |
display: inline-block |
.block |
display: block |
.sr-only |
Скрыть визуально, оставить для скринридеров |
.min-w-0 |
Разрешить сжатие флекс-элемента до нуля |
.w-full-block |
display: block + width: 100% |
.only-wide |
Виден только на широких экранах (≥641px) |
.only-narrow |
Виден только на узких экранах (≤640px) |
.h-scroll |
Гориз. скролл всегда (min-width: max-content, без сжатия) |
.h-scroll-narrow |
Гориз. скролл только на узком экране (≤640px) |
.h-scroll-wide |
Гориз. скролл только на широком экране (≥641px) |
.zoom-0 |
Без зума (zoom.js) и без кнопки «Развернуть» у vega |
.code-0 |
Без копи-кнопки кода и без кнопки «Код»/копии спеки у vega |
Безопасность
attr_list позволяет добавлять любые HTML-атрибуты: style, id, data-* и другие (в том числе onclick). Любой автор статьи может вставить произвольный HTML. Это осознанный компромисс: контент пишут только авторы с ролью author/admin.
Советы
- Комбинируйте классы —
{ .btn .btn-lg .btn-outline },{.border-card .shadow .rounded} - Для флекса сначала
.flexили.d-flex, затем добавляйте.flex-center,.flex-between,.flex-col,gap-* - Ширина работает только внутри
.flex,.d-flexили.grid-*контейнеров - На телефоне грид и ширины автоматически становятся в одну колонку
- Цвета фона и
.border-cardуже включают padding — не добавляйте отступы вручную, если не нужны - Таблицы оформляются классами
.t-*на обёрткеbox; комбинируйте их с.h-scrollдля широких таблиц — не добавляйте отступы вручную, если не нужны
Комментарии
Пока нет комментариев.
Войдите, чтобы комментировать.