Motiva
Мои коллекции
← каталог

Heading Inline Image

Снимки вшиты прямо в строку заголовка и раскрываются по прокрутке — слова честно раздвигаются, освобождая им место. Ноль скриптов: ширина чипа анимируется по animation-timeline: view(). Редкий случай, где layout-анимация — сам приём, а не издержка: пересчёт заперт в одном заголовке и идёт только на кадрах прокрутки.

cssscrollrevealintermediatereduced-motion ✓
↗
↕ демо длиннее кадра — прокрутите его
🎛 Настройки — крути и копируй

Пропсы

Разобрано из кода записи: обязательные — без «?», у остальных показано значение по умолчанию.

ПропТипПо умолчаниюЧто это
parts?(string | { img: string })[]PARTSЧасти заголовка вперемешку со снимками: строка — текст, `{ img: "https://motiva.pages.dev/img/…" }` — чип-картинка в этом месте строки.
open?number2.6Ширина раскрытого чипа в em.
fontSize?string"clamp(1.9rem, 6.5cqw, 3.8rem)"Кегль: любое CSS-значение font-size.

Установка

npx shadcn@latest add https://motiva.pages.dev/r/heading-inline-image.json
Что нужно в проекте до установки
  1. Файл components.json в корне

    Из него CLI узнаёт, куда класть файлы. Алиасы — в такой форме:

    "aliases": { "components": "@/components", "lib": "@/lib" }

    Нет файла — установка не начнётся вовсе.

  2. Алиас @ объявлен дважды

    В корневом tsconfig.json и в конфиге сборщика. В Vite корневой tsconfig часто содержит только references — этого мало.

    "paths": { "@/*": ["./src/*"] }        // tsconfig.json
    resolve.alias = { "@": "/src" }        // vite.config.ts

    Без paths CLI молча создаёт папку с именем @.

  3. Токены подключены один раз на приложение

    Они приезжают вместе с записью — достаточно импортировать их в точке входа:

    import "@/styles/motiva-tokens.css";

    Без них блок потеряет цвета, ритм и тему.

  4. Своя типографика не спорит с блоком

    Наследуемые свойства протекают внутрь: text-align: center на обёртке отцентрует содержимое секции. То же касается font-familyи line-height.

  5. Проект без TypeScript? всё равно нужен tsconfig

    CLI грузит tsconfig.json безусловно, а при "tsx": false идёт за jsconfig.json и падает так же. Минимум — файл с pathsи "tsx": true в components.json.

    Приехавший рядом .tsx можно не трогать — вам нужен .vanilla.js.

Экспорт

↓ Скачать .zip

Код

.hii {
  margin: 0;
  font-weight: 800;
  line-height: 1.08;
  letter-spacing: var(--ds-tracking-tight, -0.03em);
  color: var(--ds-fg, oklch(0.95 0.01 265));
}

/* чип-картинка живёт В СТРОКЕ заголовка: рост её ширины честно раздвигает слова.
   Это редкий случай, где layout-анимация — сам приём, а не издержка: пересчёт
   идёт только на кадрах прокрутки и заперт в одном заголовке.
   База (нет поддержки, reduce, data-shot) — чип раскрыт */
.hii-chip {
  display: inline-block;
  vertical-align: -0.12em;
  width: var(--hii-open, 2.6em);
  height: 1em;
  border-radius: 0.5em;
  margin-inline: 0.08em;
  object-fit: cover;
  max-width: none;
}

@supports (animation-timeline: view()) {
  @media not (prefers-reduced-motion: reduce) {
    .hii-chip {
      animation: hii-grow linear both;
      animation-timeline: view();
      /* чип раскрывается, пока заголовок идёт нижней третью кадра к середине */
      animation-range: cover 10% cover 45%;
    }
    @keyframes hii-grow {
      from { width: 0.55em; }
      to   { width: var(--hii-open, 2.6em); }
    }
  }
}

html[data-shot] .hii-chip { animation: none; }
лицензия: MITавтор: Motivaисточник: оригинал (Motiva); идея-референс — Codrops «On-Scroll Expanding Image within Typography» (код не заимствован)v1.0.0