HTML фреймы

Чтение — около 7 минут· без учёта практики

В предыдущем уроке мы отметили на сайте Тони его успехи. В этом уроке мы рассмотрим, что такое фреймы, для чего они нужны и как применяются, — и покажем маршрут прогулки Тони во фрейме прямо на главной странице.

Элемент iframe

Элемент <iframe> (англ. inline frame — встроенный фрейм) определяет встроенную в веб-страницу область, которая отображает отдельный документ: другую HTML-страницу, изображение, документ PDF (если в браузере есть средство просмотра PDF), медиаконтент или страницу другого сайта. Содержимое фрейма существует независимо от окружающей страницы: у него свой HTML-код, свои стили и своя история переходов.

Раньше фреймы использовались для навигации по сайту: навигационная страница располагалась в одном окне, а страницы с содержимым — в других документах. Сейчас для этого фреймы не применяют. Их используют, чтобы встроить на страницу то, что подготовлено другим сайтом: карту, проигрыватель видео (например, с видеохостинга YouTube), пример кода из «песочницы» (выделенной среды для исполнения компьютерного кода) или форму стороннего сервиса.

Синтаксис для добавления фрейма:

HTML
<iframe src="URL" title="Описание содержимого"></iframe>

Атрибут src определяет адрес документа или сайта, который загружается во фрейм. Адрес может быть относительным, как у ссылок и изображений, или абсолютным. Закрывающий тег </iframe> обязателен. Содержимое между тегами браузер не показывает, поэтому запасную ссылку на документ размещайте рядом с фреймом, а не внутри него.

Другие атрибуты, которые понадобятся в этом уроке:

  • title — название фрейма. Программы экранного доступа объявляют его, когда пользователь переходит к фрейму, поэтому название должно описывать содержимое: «Маршрут прогулки Тони», а не «Фрейм».
  • width и height — ширина и высота фрейма в пикселях (записываются числом без единиц). Без них фрейм занимает 300 × 150 пикселей.
  • name — имя фрейма. Если указать это имя в атрибуте target ссылки, ссылка откроется не на всей вкладке, а внутри фрейма.

Прогулки Тони во фрейме

Во фрейм с именем walk загружена страница pages/route.html. Нажимайте ссылки над фреймом: у них указан target="walk", поэтому фотографии и маршрут открываются внутри фрейма, а сама страница остаётся на месте. Удалите target у ссылки «Маршрут» — страница маршрута откроется вместо всей страницы, вернуться можно кнопкой «Назад».

index.html
HTML
<!doctype html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>Прогулки Тони</title>
  </head>
  <body>
    <h1>Мои прогулки</h1>
    <p>
      <a href="pages/route.html" target="walk">Маршрут</a> |
      <a href="assets/tony.png" target="walk">Фото с прогулки</a> |
      <a href="assets/tony-toy.png" target="walk">Я и мой канат</a> |
      <a href="https://ru.wikipedia.org/wiki/Карликовый_пинчер" target="walk">О породе в Википедии</a>
    </p>
    <!-- Фрейм с именем walk: в нём открываются ссылки с target="walk" -->
    <iframe src="pages/route.html" name="walk" title="Маршрут и фотографии прогулки" width="320" height="420"></iframe>
  </body>
</html>
pages/route.html
HTML
<!doctype html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>Маршрут прогулки</title>
  </head>
  <body>
    <h2>Маршрут прогулки</h2>
    <ol>
      <li>Выходим из дома и идём к скверу.</li>
      <li>Обходим пруд и здороваемся с утками.</li>
      <li>Играем с канатом на поляне.</li>
      <li>Возвращаемся домой через парк.</li>
    </ol>
    <p>Вся прогулка занимает около часа.</p>
  </body>
</html>

В этом примере мы:

  • Элементом <iframe> создали фрейм, которому атрибутом name задали имя "walk", атрибутами width и height — ширину 320 и высоту 420 пикселей, а атрибутом title — понятное название. В атрибуте src указали относительный путь к странице маршрута pages/route.html.
  • Перед фреймом разместили четыре ссылки, которые открываются непосредственно во фрейме: в значении атрибута target указано имя нашего фрейма. Первая ссылка открывает страницу, загруженную изначально, вторая и третья загружают изображения, а четвёртая — статью о породе Тони в Википедии.

Учебный редактор загружает внешние страницы по HTTPS, если сайт разрешает встраивание, но из-за отключённых скриптов и отправки форм некоторые возможности сайта внутри фрейма могут не работать.

Код встраивания сторонних сервисов

Карты, видеохостинги и другие сервисы обычно предлагают готовый код с фреймом. Например, в Google Картах он находится в меню «Поделиться» → «Встраивание карт»: адрес фрейма в нём начинается с https://www.google.com/maps/embed?pb=. Как встроить видео с YouTube, мы рассмотрим в уроке «Размещение видео с видеохостинга YouTube».

Вставляя готовый код, проверьте атрибут title: при необходимости добавьте его или уточните описание содержимого фрейма, например title="Карта проезда к парку".

Безопасность и скорость загрузки

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

Атрибуты безопасности и загрузки элемента iframe
Атрибут Описание
loading="lazy" Откладывает загрузку фрейма, пока пользователь не прокрутит страницу близко к нему (англ. lazy — ленивый). Подходит для карт и видео в нижней части страницы. Значение по умолчанию eager загружает фрейм сразу.
sandbox Включает «песочницу» (англ. sandbox): без значения запрещает во фрейме скрипты, формы, всплывающие окна и переходы во вкладке, а содержимое считается загруженным с отдельного сайта. Отдельные возможности возвращаются значениями через пробел: allow-scripts, allow-forms, allow-popups и другими.
allow Перечисляет возможности браузера, которые разрешены фрейму, например allow="fullscreen" (полноэкранный режим) или allow="autoplay; picture-in-picture". Логический атрибут allowfullscreen также разрешает полноэкранный режим и остаётся допустимым в HTML. Ни allow, ни allowfullscreen не могут отменить запрет, установленный для родительской страницы.
referrerpolicy Определяет, какую часть адреса вашей страницы браузер сообщит встроенному сайту, например strict-origin-when-cross-origin передаёт при запросе к другому источнику только источник (протокол, домен и порт), при запросе к тому же источнику — полный адрес без фрагмента, а при переходе с HTTPS на HTTP не передаёт адрес.

Значения sandbox добавляйте только по необходимости: например, интерактивной карте нужен allow-scripts. Не сочетайте allow-scripts и allow-same-origin для страниц своего же сайта: вместе они позволяют встроенной странице снять ограничения песочницы.

HTML
<iframe src="https://example.com/map" title="Карта парка" width="600" height="400"
        loading="lazy" sandbox="allow-scripts"></iframe>
Из истории: frameset и frame

В ранних версиях HTML страницу целиком делили на окна элементом <frameset>, а в каждое окно загружали отдельный документ элементом <frame>: например, меню слева и содержимое справа. У такой вёрстки много недостатков: на внутреннюю страницу трудно дать ссылку, поисковые системы находили страницы без меню, а кнопка «Назад» работала непредсказуемо. Современный стандарт HTML считает <frameset> и <frame> устаревшими. Из фреймов остался только встроенный <iframe>.

Проверьте себя

Выберите ответ — объяснение появится сразу. Ответ можно менять.

1. На странице есть <iframe name="walk"> и ссылка <a href="photo.png" target="walks">. Где откроется фотография?
Показать ответ

В новой вкладке или окне — Фрейма с именем walks нет, поэтому браузер открывает ссылку в новой вкладке с этим именем.

2. Зачем фрейму атрибут title?
Показать ответ

Чтобы назвать содержимое фрейма для программ экранного доступа — Название фрейма объявляется при переходе к нему, поэтому оно должно описывать содержимое.

3. Вы встроили во фрейм страницу поисковой системы, но фрейм остался пустым. Какая причина наиболее вероятна?
Показать ответ

Сайт запрещает показывать свои страницы во фреймах — Владелец сайта может запретить встраивание заголовками сервера. Используйте код встраивания сервиса и оставьте рядом обычную ссылку.

4. Какой атрибут отложит загрузку карты в конце длинной страницы, пока пользователь не прокрутит к ней?
Показать ответ

loading="lazy" — Ленивая загрузка откладывает фрейм, пока он не окажется близко к видимой области.

5. Что запрещает фрейму атрибут sandbox без значения?
Показать ответ

Скрипты, формы и всплывающие окна — Пустой sandbox включает все ограничения. Нужные возможности возвращают значениями, например allow-scripts.

Задание

Тони хочет, чтобы гости сайта видели его маршрут, не уходя с главной страницы. В файле index.html уже есть раздел «Где я гуляю» с двумя ссылками, а страница маршрута — в файле pages/walks.html. Выполните два шага:

  1. После абзаца со ссылками добавьте фрейм шириной 320 и высотой 420 пикселей. Загрузите в него pages/walks.html, задайте имя walk и понятное название.
  2. Сделайте так, чтобы обе ссылки раздела открывались во фрейме.

Выполните задание

index.html
HTML
<!doctype html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>Сайт Тони</title>
  </head>
  <body style="background-color: linen">
    <header>
      <!-- Меню сайта -->
      <nav>
        <ul>
          <li><a href="index.html">Главная</a></li>
          <li><a href="pages/toys.html">Мои игрушки</a></li>
        </ul>
      </nav>
    </header>
    <main>
      <h1 id="top" style="color: saddlebrown; text-align: center">Привет! Меня зовут Тони</h1>
      <p>Я карликовый пинчер. Мне три года, я вешу 8&nbsp;кг и люблю гулять в любую погоду. Хозяин говорит: <q>Тони — лучший сторож в доме</q>.</p>
      <p>Мой день рождения — <time datetime="2023-09-12">12 сентября</time>. <strong>Пожалуйста, не кормите меня со стола!</strong></p>
      <p>Моя родословная записана в Российской кинологической федерации (<abbr title="Российская кинологическая федерация">РКФ</abbr>).</p>
      <ul>
        <li><a href="#toy">Моя любимая игрушка</a></li>
        <li><a href="#commands">Команды, которые я знаю</a></li>
        <li><a href="#schedule">Мой режим дня</a></li>
        <li><a href="#walks">Где я гуляю</a></li>
      </ul>
      <section>
        <h2 id="toy" class="section-title" style="color: #8B4513">Моя любимая игрушка</h2>
        <p data-toy-id="17">Это канат с мячиком. Хозяин бросает его, а я приношу обратно — <em>почти</em> всегда. <a href="pages/toys.html">Посмотреть все игрушки Тони</a>.</p>
        <figure>
          <img src="assets/tony-toy.png" alt="Тони сидит и держит в зубах канат с красным мячиком" width="300" height="400" title="Мой канат &quot;Удав&quot;">
          <figcaption style="color: dimgray">Я и мой канат «Удав»</figcaption>
        </figure>
        <p><a href="assets/tony-toy.png" download>Скачать фотографию</a></p>
        <p>Подробнее о моей породе — в статье <a href="https://ru.wikipedia.org/wiki/Карликовый_пинчер" target="_blank">«Карликовый пинчер» в Википедии</a>.</p>
        <hr>
        <p>Вечером игра закончилась. Канат остался на полу, а я свернулся калачиком в кресле.</p>
      </section>
      <section>
        <h2 style="color: #8B4513">Мой стишок</h2>
        <p>
          Я маленький, но смелый,<br>
          Гуляю целый день,<br>
          А вечером на кресле<br>
          Сплю — и мне не лень.
        </p>
      </section>
      <section>
        <h2 id="commands" class="section-title" style="color: #8B4513">Команды, которые я знаю</h2>
        <p>Хозяин научил меня командам на немецком:</p>
        <dl>
          <dt lang="de">Sitz!</dt>
          <dd>сидеть</dd>
          <dt lang="de">Platz!</dt>
          <dd>лежать</dd>
          <dt lang="de">Fuß!</dt>
          <dd>рядом</dd>
        </dl>
        <details>
          <summary>Почему команды на немецком?</summary>
          <p>Карликовый пинчер — немецкая порода, и хозяину понравилась эта традиция.</p>
        </details>
      </section>
      <section>
        <h2 id="schedule" style="color: #8B4513">Мой режим дня</h2>
        <table>
          <caption>Режим дня Тони</caption>
          <thead>
            <tr>
              <th scope="col">Время</th>
              <th scope="col">Будни</th>
              <th scope="col">Выходные</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <th scope="row">07:00</th>
              <td>Прогулка, 20 минут</td>
              <td>Сплю</td>
            </tr>
            <tr>
              <th scope="row">08:00</th>
              <td colspan="2">Завтрак</td>
            </tr>
            <tr>
              <th scope="row">13:00</th>
              <td>Жду хозяина и сплю</td>
              <td>Прогулка в парке, 1 час</td>
            </tr>
            <tr>
              <th scope="row">19:00</th>
              <td colspan="2">Ужин</td>
            </tr>
            <tr>
              <th scope="row">21:00</th>
              <td colspan="2">Вечерняя прогулка</td>
            </tr>
          </tbody>
        </table>
      </section>
      <section>
        <h2 id="progress" style="color: #8B4513">Мои успехи</h2>
        <p>Учу команду «Апорт»: пройдено 3 занятия из 5. <progress value="3" max="5">3 из 5</progress></p>
        <p>Прогулка сегодня: 40 минут. <meter value="40" min="0" max="90" low="30" high="60" optimum="75">40 из 90 минут</meter></p>
      </section>
      <section>
        <h2 id="walks" style="color: #8B4513">Где я гуляю</h2>
        <p>Я люблю гулять в сквере у дома.</p>
        <p>
          <a href="pages/walks.html">Маршрут</a> |
          <a href="assets/tony.png">Фото с прогулки</a>
        </p>
      </section>
      <section>
        <h2 style="color: #8B4513">Моя любимая книга</h2>
        <p>Хозяин читал мне вслух рассказ <cite>«Каштанка»</cite> Антона Чехова. Он начинается так:</p>
        <figure>
          <blockquote>
            <p>Молодая рыжая собака — помесь таксы с дворняжкой — очень похожая мордой на лисицу, бегала взад и вперёд по тротуару и беспокойно оглядывалась по сторонам.</p>
          </blockquote>
          <figcaption>— Антон Чехов, <cite>«Каштанка»</cite></figcaption>
        </figure>
      </section>
      <p><a href="#top">Наверх</a></p>
    </main>
    <footer style="background-color: hsl(30, 50%, 90%)">
      <p style="text-align: center"><small>&copy; 2026 Тони и его хозяин</small></p>
      <address>Написать хозяину Тони: <a href="mailto:tony@example.com">tony@example.com</a></address>
    </footer>
  </body>
</html>
pages/toys.html
HTML
<!doctype html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>Игрушки Тони</title>
  </head>
  <body>
    <header>
      <nav>
        <ul>
          <li><a href="../index.html">Главная</a></li>
          <li><a href="toys.html">Мои игрушки</a></li>
        </ul>
      </nav>
    </header>
    <main>
      <h1>Мои игрушки</h1>
      <ul>
        <li>Канат с мячиком «Удав» — моя любимая игрушка</li>
        <li>Резиновая косточка — для вечеров, когда гулять уже поздно</li>
        <li>Пищащий ёжик — его я прячу <del>под диваном</del> <ins>в своей лежанке</ins></li>
      </ul>
      <img src="../assets/tony.png" alt="Тони сидит и смотрит в камеру" width="300" height="400">
      <h2>Как играть со мной в канат</h2>
      <ol>
        <li>Покажите мне канат.</li>
        <li>Бросьте его подальше.</li>
        <li>Подождите, пока я принесу его обратно.</li>
        <li>Похвалите меня — и всё сначала!</li>
      </ol>
      <section>
        <h2 id="album">Мой фотоальбом</h2>
        <ul>
          <li>
            <figure>
              <img src="../assets/album-puppy.png" alt="Тони-щенок сидит и смотрит в камеру" width="300" height="400">
              <figcaption>Я в детстве</figcaption>
            </figure>
          </li>
          <li>
            <figure>
              <img src="../assets/album-squirrel.png" alt="Тони лежит в обнимку с плюшевой белкой" width="300" height="400">
              <figcaption>С плюшевой белкой</figcaption>
            </figure>
          </li>
          <li>
            <figure>
              <img src="../assets/album-hoodie.png" alt="Тони стоит в бежевой толстовке с капюшоном" width="300" height="400">
              <figcaption>В худи для холодной погоды</figcaption>
            </figure>
          </li>
          <li>
            <figure>
              <img src="../assets/album-harness.png" alt="Тони в оранжевой шлейке ждёт прогулку" width="300" height="400">
              <figcaption>Шлейка надета — идём гулять!</figcaption>
            </figure>
          </li>
          <li>
            <figure>
              <img src="../assets/album-laugh.png" alt="Тони лежит, запрокинув голову, и широко открыл пасть, будто смеётся" width="300" height="400">
              <figcaption>Смеюсь над шуткой хозяина</figcaption>
            </figure>
          </li>
          <li>
            <figure>
              <img src="../assets/album-sleep.png" alt="Тони спит, положив голову на лапы" width="300" height="319">
              <figcaption>После прогулки</figcaption>
            </figure>
          </li>
        </ul>
      </section>
      <p><a href="../index.html#commands">Какие команды я знаю</a></p>
      <p><a href="../index.html">Вернуться на главную</a></p>
    </main>
    <footer>
      <p><small>&copy; 2026 Тони и его хозяин</small></p>
      <address>Написать хозяину Тони: <a href="mailto:tony@example.com">tony@example.com</a></address>
    </footer>
  </body>
</html>
pages/walks.html
HTML
<!doctype html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>Где гуляет Тони</title>
  </head>
  <body>
    <h1>Мой маршрут</h1>
    <ol>
      <li>Сквер у дома.</li>
      <li>Пруд с утками.</li>
      <li>Поляна для игры с канатом.</li>
    </ol>
  </body>
</html>

Ожидаемый результат: в разделе «Где я гуляю» виден фрейм с маршрутом. Ссылка «Фото с прогулки» показывает фотографию во фрейме, а ссылка «Маршрут» возвращает в него маршрут; адрес над результатом при этом не меняется. Если ссылка заменяет всю страницу, проверьте наличие target; если открывается новое окно или вкладка, сравните его значение с атрибутом name фрейма.

Продолжите в VS Code

  1. Нажмите «Скачать ZIP» в редакторе выше и распакуйте архив в папку my-site: он содержит все страницы и ресурсы примера с вашими текущими правками. Сохраните структуру папок; перед заменой существующих файлов сохраните копию своей версии сайта.
  2. Откройте index.html в браузере и нажмите ссылки раздела «Где я гуляю».

Ожидаемый результат: маршрут и фотография открываются во фрейме так же, как в редакторе. Если результат отличается и найти ошибку не получается, нажмите в редакторе выше «Показать решение» и сравните его со своим кодом.

Дополнительное задание: фотоальбом Тони

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

  1. Первая ссылка загружает во фрейм статью Википедии о породе Тони.
  2. Вторая и третья ссылки загружают во фрейм фотографии из папки assets.
  3. Четвёртая ссылка загружает во фрейм страницу pages/toys.html.

Добавьте после списка фрейм и задайте ему размер по ширине и высоте фотографий — 300 × 400 пикселей. Изначально во фрейме должна быть первая фотография.

Соберите фотоальбом

index.html
HTML
<!doctype html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>Фотоальбом Тони</title>
  </head>
  <body>
    <h1>Фотоальбом Тони</h1>
    <ul>
      <li><a href="https://ru.wikipedia.org/wiki/Карликовый_пинчер">Статья о породе</a></li>
      <li><a href="assets/tony.png">Тони смотрит в камеру</a></li>
      <li><a href="assets/tony-toy.png">Тони с канатом</a></li>
      <li><a href="pages/toys.html">Игрушки Тони</a></li>
    </ul>
  </body>
</html>
pages/toys.html
HTML
<!doctype html>
<html lang="ru">
  <head>
    <meta charset="utf-8">
    <title>Игрушки Тони</title>
  </head>
  <body>
    <header>
      <nav>
        <ul>
          <li><a href="../index.html">Главная</a></li>
          <li><a href="toys.html">Мои игрушки</a></li>
        </ul>
      </nav>
    </header>
    <main>
      <h1>Мои игрушки</h1>
      <ul>
        <li>Канат с мячиком «Удав» — моя любимая игрушка</li>
        <li>Резиновая косточка — для вечеров, когда гулять уже поздно</li>
        <li>Пищащий ёжик — его я прячу <del>под диваном</del> <ins>в своей лежанке</ins></li>
      </ul>
      <img src="../assets/tony.png" alt="Тони сидит и смотрит в камеру" width="300" height="400">
      <h2>Как играть со мной в канат</h2>
      <ol>
        <li>Покажите мне канат.</li>
        <li>Бросьте его подальше.</li>
        <li>Подождите, пока я принесу его обратно.</li>
        <li>Похвалите меня — и всё сначала!</li>
      </ol>
      <section>
        <h2 id="album">Мой фотоальбом</h2>
        <ul>
          <li>
            <figure>
              <img src="../assets/album-puppy.png" alt="Тони-щенок сидит и смотрит в камеру" width="300" height="400">
              <figcaption>Я в детстве</figcaption>
            </figure>
          </li>
          <li>
            <figure>
              <img src="../assets/album-squirrel.png" alt="Тони лежит в обнимку с плюшевой белкой" width="300" height="400">
              <figcaption>С плюшевой белкой</figcaption>
            </figure>
          </li>
          <li>
            <figure>
              <img src="../assets/album-hoodie.png" alt="Тони стоит в бежевой толстовке с капюшоном" width="300" height="400">
              <figcaption>В худи для холодной погоды</figcaption>
            </figure>
          </li>
          <li>
            <figure>
              <img src="../assets/album-harness.png" alt="Тони в оранжевой шлейке ждёт прогулку" width="300" height="400">
              <figcaption>Шлейка надета — идём гулять!</figcaption>
            </figure>
          </li>
          <li>
            <figure>
              <img src="../assets/album-laugh.png" alt="Тони лежит, запрокинув голову, и широко открыл пасть, будто смеётся" width="300" height="400">
              <figcaption>Смеюсь над шуткой хозяина</figcaption>
            </figure>
          </li>
          <li>
            <figure>
              <img src="../assets/album-sleep.png" alt="Тони спит, положив голову на лапы" width="300" height="319">
              <figcaption>После прогулки</figcaption>
            </figure>
          </li>
        </ul>
      </section>
      <p><a href="../index.html">Вернуться на главную</a></p>
    </main>
    <footer>
      <p><small>&copy; 2026 Тони и его хозяин</small></p>
      <address>Написать хозяину Тони: <a href="mailto:tony@example.com">tony@example.com</a></address>
    </footer>
  </body>
</html>

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