Макет сайта HTML и CSS с адаптивной сеткой

Макет сайта html для простой страницы строится из семантических блоков, CSS Grid и Flexbox. Вы соберете шапку с меню, контент, боковую колонку и подвал, а затем перестроите их в одну колонку на узком экране. Bootstrap покажет тот же подход с готовыми классами.

Какие способы верстки макета есть сейчас

Выбирайте технологию по задаче и форме размещения элементов. Для одного макета обычно сочетают несколько способов.

  • CSS Grid. Grid строит двумерную сетку из строк, колонок и областей.
  • Flexbox. Flexbox выравнивает элементы вдоль одной главной оси.
  • Bootstrap. Bootstrap дает готовые контейнеры, строки, колонки и классы адаптивности.
  • float. Float подходит для обтекания изображения текстом.
  • Таблицы. Таблицы описывают данные и помогают собирать email-письма.

Grid отвечает за двумерную сетку страницы, Flexbox – за одномерное выравнивание внутри блоков. На практике Grid задает внешний каркас, а Flexbox раскладывает меню и карточки.

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

Не используйте position: relative со сдвигами в пикселях для каркаса. Свойство меняет видимое место элемента, но сохраняет его исходное место в потоке. При изменении текста блоки могут перекрыться.

Как устроен простой сайт на html и css

Сначала соберите семантические блоки. Тег header содержит шапку, nav – навигацию, main – основной материал, aside – дополнительный контент, а footer – подвал.

Создайте папку проекта и сохраните в ней файл index.html. Код уже содержит атрибуты alt для изображений в карточках. Положите рядом две фотографии растений с именами garden.jpg и flowers.jpg. Если выберете другие изображения, измените описания в alt.

<!doctype html>
<html lang="ru">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Городской сад</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="page">
        <header class="site-header">
            <a class="logo" href="./index.html">Городской сад</a>
            <nav class="site-nav" aria-label="Основная навигация">
                <a href="#about">О проекте</a>
                <a href="#cards">Идеи</a>
                <a href="#contacts">Контакты</a>
            </nav>
        </header>

        <main class="layout">
            <section class="content" id="about">
                <h2>Идеи для городского сада</h2>
                <p>Небольшие решения для балкона и двора.</p>
                <div class="cards" id="cards">
                    <article class="card">
                        <img src="garden.jpg" alt="Ящик с зелеными растениями на балконе">
                        <h2>Балконные травы</h2>
                        <p>Выберите светлое место и легкий грунт.</p>
                    </article>
                    <article class="card">
                        <img src="flowers.jpg" alt="Цветы в горшках на деревянной полке">
                        <h2>Цветы в горшках</h2>
                        <p>Сгруппируйте растения по режиму полива.</p>
                    </article>
                </div>
            </section>

            <aside class="sidebar">
                <h2>Полезные материалы</h2>
                <ul>
                    <li><a href="#about">Выбор места</a></li>
                    <li><a href="#cards">Список растений</a></li>
                </ul>
            </aside>
        </main>

        <footer class="site-footer" id="contacts">Свяжитесь с проектом по почте.</footer>
    </div>
</body>
</html>

Откройте файл в браузере: блоки появятся друг за другом, пока CSS не задаст сетку.

Как собрать макет сайта на CSS Grid

Grid подходит для каркаса с несколькими строками и колонками. В этом примере контент занимает свободное место, а боковая колонка получает отдельную дорожку.

Создайте рядом файл styles.css и вставьте правила:

* {
    box-sizing: border-box;
}

body {
    margin: 0;
    color: #24332b;
    font: 16px/1.5 Arial, sans-serif;
}

.page {
    width: min(100% - 32px, 1120px);
    margin: 0 auto;
}

.site-header {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 24px;
    align-items: center;
    padding: 24px 0;
}

.layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 280px;
    grid-template-areas: "content sidebar";
    gap: 32px;
}

.content {
    grid-area: content;
    min-width: 0;
    overflow-wrap: anywhere;
}

.sidebar {
    grid-area: sidebar;
    min-width: 0;
    padding: 20px;
    background: #eef5ed;
    overflow-wrap: anywhere;
}

.site-footer {
    margin-top: 40px;
    padding: 24px 0;
    border-top: 1px solid #cbd8ce;
}

.cards {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 20px;
}

.card {
    min-width: 0;
    padding: 16px;
    border: 1px solid #cbd8ce;
    border-radius: 8px;
}

.card img {
    display: block;
    width: 100%;
    height: auto;
}

Свойство grid-template-columns задает ширины колонок. Единица fr делит свободное место после фиксированных размеров и промежутков.

В записи minmax(0, 1fr) ноль задает минимальную ширину дорожки. Длинная строка внутри контента тогда не раздвигает страницу.

Имена в grid-template-areas связываются со свойствами grid-area.

Свойство gap создает промежуток между ячейками без внешних отступов.

Свойства Grid описаны в справочнике CSS Grid в MDN. Общую поддержку Grid можно посмотреть на Can I Use.

Flexbox для меню, шапки и карточек

Flexbox работает с одной осью за раз. Главная ось зависит от flex-direction, а поперечная проходит перпендикулярно ей.

Главная и поперечная оси контейнера Flexbox

Свойство justify-content распределяет элементы по главной оси. align-items выравнивает их по поперечной, flex-wrap включает перенос, а gap задает промежуток.

Добавьте правила в конец styles.css. Внешняя сетка останется на Grid, а внутренние элементы перейдут на Flexbox.

.site-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 24px;
}

.site-nav {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    flex-wrap: wrap;
    gap: 16px;
}

.site-nav a {
    color: inherit;
    text-decoration: none;
}

.cards {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
}

.card {
    flex: 1 1 260px;
}

.card h2 {
    margin-bottom: 8px;
}

Шапка раздвигает логотип и меню по краям контейнера.

При нехватке места навигация переносится на новую строку.

Запись flex: 1 1 260px задает карточке базовую ширину 260 пикселей. Карточка может сжиматься и занимать свободное место.

Если карточки не помещаются в ряд, flex-wrap переносит их. Более позднее значение display: flex меняет Grid для контейнера .cards.

Подробности о Flexbox есть в справочнике Flexbox в MDN.

Как сделать макет адаптивным с медиазапросами, minmax и auto-fit

Медиазапрос меняет композицию при уменьшении окна. Боковая колонка переходит под основной материал, а карточки занимают доступную ширину.

Добавьте правила в конец styles.css:

@media (max-width: 720px) {
    .site-header {
        flex-direction: column;
        align-items: stretch;
        gap: 12px;
    }

    .site-nav {
        justify-content: flex-start;
    }

    .layout {
        grid-template-columns: 1fr;
        grid-template-areas:
            "content"
            "sidebar";
        gap: 24px;
    }

    .card {
        flex-basis: 100%;
    }
}

@media (max-width: 520px) {
    .page {
        width: min(100% - 20px, 1120px);
    }
}

При ширине до 720 пикселей Grid получает одну колонку. Боковая колонка встает после контента, а карточки переходят на отдельные строки.

Точки переключения выбирайте по содержимому.

Если меню уже не помещается, перенесите порог выше.

Для неизвестного числа карточек подойдет автоматическая сетка:

.cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
    gap: 20px;
}

Значение auto-fit в функции repeat() создает столько колонок, сколько помещается в контейнере. minmax удерживает минимальную ширину карточки, а min() не дает ей стать шире узкого контейнера.

Вариант с Grid удобен для карточек, когда их число меняется. Вариант с Flexbox проще, когда важны перенос и выравнивание элементов в ряд.

subgrid позволяет вложенной сетке использовать дорожки родительской сетки. Container queries меняют оформление компонента по размеру его контейнера. Для первого каркаса хватит Grid и медиазапросов.

Подробнее о вложенных сетках рассказывает документация MDN по subgrid.

Как подключить Bootstrap и собрать макет на container, row и col-*

Bootstrap сокращает объем собственного CSS для типового интерфейса. Его сетка использует контейнер, строки и колонки с адаптивными классами.

Создайте копию index.html с именем bootstrap.html.

Внутри head замените подключение styles.css готовой строкой подключения Bootstrap через CDN:

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous">

Для этого макета достаточно CSS фреймворка: подключать JavaScript не нужно. Браузер загрузит стили по указанному адресу, поэтому для CDN-варианта требуется интернет.

Чтобы работать без подключения к сети, откройте адрес из href в браузере. Сохраните CSS рядом с bootstrap.html под именем bootstrap.min.css. Затем замените CDN-подключение локальным:

<link rel="stylesheet" href="bootstrap.min.css">

Замените содержимое body в копии страницы следующим фрагментом. Сохраните файл и откройте bootstrap.html в браузере.

<div class="container">
    <header class="d-flex flex-wrap justify-content-between align-items-center gap-3 py-4">
        <a class="fs-3 text-dark text-decoration-none" href="./bootstrap.html">Городской сад</a>
        <nav class="d-flex flex-wrap gap-3" aria-label="Основная навигация">
            <a href="#about">О проекте</a>
            <a href="#cards">Идеи</a>
            <a href="#contacts">Контакты</a>
        </nav>
    </header>

    <div class="row">
        <main class="col-md-8" id="about">
            <h2>Идеи для городского сада</h2>
            <p>Небольшие решения для балкона и двора.</p>
            <div class="row row-cols-1 row-cols-sm-2 g-4" id="cards">
                <article class="col">
                    <div class="card h-100">
                        <img src="garden.jpg" class="card-img-top" alt="Ящик с зелеными растениями на балконе">
                        <div class="card-body">
                            <h2 class="card-title h4">Балконные травы</h2>
                            <p class="card-text">Выберите светлое место и легкий грунт.</p>
                        </div>
                    </div>
                </article>
                <article class="col">
                    <div class="card h-100">
                        <img src="flowers.jpg" class="card-img-top" alt="Цветы в горшках на деревянной полке">
                        <div class="card-body">
                            <h2 class="card-title h4">Цветы в горшках</h2>
                            <p class="card-text">Сгруппируйте растения по режиму полива.</p>
                        </div>
                    </div>
                </article>
            </div>
        </main>

        <aside class="col-md-4">
            <div class="p-4 bg-light">
                <h2 class="h4">Полезные материалы</h2>
                <ul>
                    <li><a href="#about">Выбор места</a></li>
                    <li><a href="#cards">Список растений</a></li>
                </ul>
            </div>
        </aside>
    </div>

    <footer class="py-4 mt-4 border-top" id="contacts">Свяжитесь с проектом по почте.</footer>
</div>

Класс container ограничивает ширину содержимого, row создает строку, а col-md-8 и col-md-4 делят ее между контентом и боковой колонкой. Префикс md задает порог, после которого колонки стоят рядом.

Классы row-cols-1 и row-cols-sm-2 задают одну колонку карточек на узком экране и две колонки при более широкой ширине. Компонент card заменяет старый класс thumbnail.

На широком экране появятся две колонки и карточки с рамками. При сужении окна боковая колонка перейдет под основной материал. Если оформление не появилось при локальном подключении, проверьте имя bootstrap.min.css и расположение файла рядом с HTML. Для CDN-варианта проверьте подключение к интернету и адрес в href.

Не подключайте к этой странице styles.css из первого примера. Правила .card изменят внешний вид компонента Bootstrap. Исходный вариант останется в index.html, поэтому вы сможете вернуться к нему без отмены изменений.

Где еще нужны float и таблицы

float удобно применять, когда текст должен обтекать изображение внутри статьи. Для внешнего каркаса Grid и Flexbox понятнее: их правила прямо описывают строки и колонки.

Добавьте фрагмент внутрь .content в исходном HTML-файле:

<article class="article">
    <h2>Как выбрать место для растений</h2>
    <img class="article-image" src="garden.jpg" alt="Растения в ящике на балконе">
    <p>Оцените освещение балкона утром, днем и вечером. Для светолюбивых трав выберите место с прямым солнцем.</p>
</article>

Добавьте правила изображения и очистки обтекания в styles.css:

.article-image {
    float: left;
    width: 180px;
    max-width: 40%;
    height: auto;
    margin: 0 16px 8px 0;
}

.article::after {
    display: table;
    clear: both;
    content: "";
}

Текст расположится справа от фотографии и продолжится под ней. Псевдоэлемент очистит обтекание после статьи.

Таблица подходит для данных, где строки и столбцы несут смысл. В email-верстке таблицы также применяют для каркаса письма, потому что почтовые клиенты по-разному обрабатывают CSS.

Табличная сетка с видимыми границами ячеек

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

Какой способ верстки макета сайта выбрать

Для нового сайта начните с семантического HTML, Grid для каркаса и Flexbox для внутренних рядов. Bootstrap подойдет, если проекту нужны готовые классы и компоненты.

КритерийGridFlexboxBootstrapFloatТаблицы
Для чего подходитДвумерный каркас страницыМеню, шапка, ряды карточекТиповой интерфейс на готовых классахОбтекание картинки текстомТабличные данные и email-письма
АдаптивностьГибкие дорожки и медиазапросыПеренос и изменение размеровГотовые классы брейкпоинтовТребует ручной перестройки каркасаТребует дополнительных приемов
Объем кодаКомпактные правила сеткиКомпактные правила выравниванияМеньше собственного CSS, больше классов в HTMLДля каркаса нужны очистка и расчеты ширинДля каркаса нужны строки и ячейки
Порог входаНужно освоить дорожки и областиНужно понять оси и размерыНужно выучить классы и устройство сеткиПрост для обтекания, сложнее для каркасаПрост для данных, сложнее для адаптивного письма
  • Grid. Берите его, когда нужно управлять строками и колонками одновременно.
  • Flexbox. Используйте его для выравнивания элементов внутри блока.
  • Bootstrap. Выбирайте его, когда нужны готовые сетка и компоненты.
  • Float. Оставляйте его для обтекания изображения текстом.
  • Таблицы. Используйте их для данных и email-писем.

Проверьте макет в DevTools браузера. Откройте инструменты разработчика через контекстное меню страницы и включите режим адаптивного просмотра с помощью кнопки устройства.

Выберите в дереве элементов <main class="layout"> и включите подсветку Grid-контейнера. Подсветка покажет границы дорожек и промежутки между ними.

Затем выберите <nav class="site-nav"> и включите подсветку Flex-контейнера. Сравните расположение пунктов меню при ширине 320 и 720 пикселей.

При ширине 320 пикселей контент должен помещаться по ширине, боковая колонка – стоять снизу, а карточки – не создавать горизонтальную прокрутку. Если это условие выполняется, медиазапрос работает.

Комментарии

Оставьте свой комментарий
Пока никто не оставил комментариев