Тег <frameset> делит окно браузера на фреймы, то есть области, в каждой из которых тег frame загружает свой документ. Он парный и заменяет тег <body>: в таком документе обычного тела нет. Раскладку задают атрибуты cols (столбцы) и rows (строки). Стандарт HTML запрещает тег и советует брать iframe и CSS.
<frameset rows="80,*">
<frame src="top.html">
<frame src="main.html">
</frameset>
В этой статье
Что делает тег frameset и что писать внутри
Тег frameset стоит в документе сразу после <head>, без <body>. Внутри браузер разбирает только теги frame и вложенные frameset. Текст, блок <div> и любая другая разметка внутри пропадают, а второй frameset на том же уровне и абзац после первого тоже не попадают в документ.
По HTML 4.01 закрывающий тег </frameset> обязателен. Браузер строит фреймы и без него, но закрывающий тег лучше писать: по нему видно, где кончается набор. Работает тег и в документе с <!doctype html>, хотя стандарт его запрещает.
Пример: что остаётся в документе с frameset
Кнопки выбирают разметку, код показан над рамкой. Под рамкой записаны число тегов, число фреймов, тело документа и то, что осталось в нём кроме фреймов.
Во всех вариантах фреймов два, а лишнего в документе нет. Во втором варианте набор не закрыт, а в последних двух пропали лишний frameset и абзац.
Атрибуты frameset: cols, rows, border, bordercolor и события
Атрибутов у frameset немного. Главные cols и rows: первый делит документ на столбцы, второй на строки. Остальные про границу между фреймами и про события окна.
| Атрибут | Что задаёт | Значения |
|---|---|---|
cols | Ширину каждого столбца | Список через запятую |
rows | Высоту каждой строки | Список через запятую |
border | Толщину границы между фреймами | Число пикселей |
bordercolor | Цвет границы между фреймами | Название цвета или код |
frameborder | Показывать ли границу | 0 или 1 |
framespacing | Зазор между фреймами, обычно не действует | Число пикселей |
onload, onresize | Обработчики событий окна | Код на JavaScript |
Как работают border, frameborder и framespacing, подробно разобрано на странице frame: зазор меняют border и frameborder, а framespacing на него не влияет. Здесь показаны цвет границы, события и свойство cols.
Пример: bordercolor, события и свойство cols
Первый ряд кнопок выбирает цвет границы, второй сужает документ и меняет cols. Под рамкой записаны счётчики событий, свойство cols и ширина левого фрейма.
Событие load срабатывает один раз при загрузке, а resize при каждом изменении ширины документа. Присвоение document.body.cols меняет раскладку сразу: при записи 30%,* левый фрейм сужается. Цвет границы виден на полосе между фреймами: при записи red она красная, при blue синяя.
Значения cols и rows: пиксели, проценты и звёздочка
Каждое значение в списке задаёт один столбец или одну строку. Число означает пиксели, запись 100px даёт то же. Процент берёт долю документа. Звёздочка занимает остаток, а число перед ней задаёт долю: 2* вдвое больше, чем *. Для rows правила те же, только по высоте.
<frameset cols="100,*,25%">
<frame src="a.html">
<frame src="b.html">
<frame src="c.html">
</frameset>
Пример: значения cols и rows
Кнопки выбирают атрибут, значение и размер документа. Под рамкой записаны размеры фреймов в пикселях, граница убрана записью border=0, чтобы она не мешала счёту.
Пиксели остаются прежними, если рядом есть звёздочка или проценты: они принимают остаток и пересчитываются при смене размера документа. Если все значения в пикселях, фреймы растягиваются на весь документ пропорционально: 100,200 в документе шириной 688px даёт 229 и 459 px. Если сумма процентов больше 100%, фреймы сжимаются пропорционально долям. Если пикселей больше, чем места, фрейму со звёздочкой остаётся 0 px. Неверное значение вроде abc даёт нулевой фрейм, а дробная часть в 1.5* не учитывается.
Число фреймов и сетка из cols и rows
Если задать cols и rows вместе, фреймы встают сеткой слева направо и сверху вниз. Число тегов frame должно совпадать с числом ячеек: лишний фрейм получает нулевой размер, а нехватка оставляет ячейки пустыми. Без обоих атрибутов первый фрейм занимает весь документ.
Пример: сетка и несовпадение числа фреймов
Кнопки выбирают значения и число фреймов. Над рамкой показана запись, под рамкой записаны размеры фреймов и что случилось с лишними ячейками.
Браузер ошибки не показывает: пустая ячейка или фрейм 0 на 0 просто остаются на странице, поэтому такую опечатку легко не заметить.
Вложенные теги frameset
Обычно один frameset делит документ в одном направлении. Чтобы получить шапку и под ней два столбца, внутрь набора добавляют второй frameset: внешний делит документ на строки, а внутренний делит одну из строк на столбцы. Два набора на одном уровне не складываются: второй пропадает.
<frameset rows="80,*">
<frame src="top.html">
<frameset cols="100,*">
<frame src="menu.html">
<frame src="main.html">
</frameset>
</frameset>
Пример: один набор, вложенный набор и два подряд
Кнопки выбирают разметку, код показан над рамкой. Под рамкой записаны число тегов frameset, число фреймов и их размеры.
Вложенный набор даёт три фрейма, и закрывающие теги можно опустить и здесь. Два набора подряд дают те же два фрейма, что и первый, а второй не создаёт ничего.
Чем заменить тег frameset: iframe и CSS grid
Раскладку из фреймов строит CSS grid, а сами фреймы заменяет тег iframe (встроенный фрейм). Шапку и меню, общие для всех страниц, стандарт советует собирать на сервере: тогда каждая страница приходит целой и открывается по своему адресу.
<div class="layout">
<iframe src="top.html"></iframe>
<iframe src="menu.html"></iframe>
<iframe src="main.html"></iframe>
</div>
.layout {
display: grid;
grid-template-columns: 100px 1fr;
grid-template-rows: 80px minmax(0, 1fr);
height: 100vh;
}
.layout iframe {
width: 100%;
height: 100%;
border: 0;
}
.layout iframe:first-child {
grid-column: 1 / 3;
}
Пример: те же три фрейма на frameset и на grid
Кнопки выбирают способ. Под рамкой записаны число фреймов и их размеры в пикселях.
Размеры фреймов совпадают в обоих вариантах. Проверка в Nu Html Checker для <frameset> сообщает: The “frameset” element is obsolete. Use the “iframe” element and CSS instead, or use server-side includes. Тот же совет выдаётся для <frame>, он разобран отдельно. Про ссылки между фреймами рассказано в уроке «Ссылки: тег a и его атрибуты».