Статья Пример использования flex для адаптивного дизайна

Flex — это одна из великолепных возможностей новых версий CSS. Используя один только flex можно очень простым кодом (заданием стилей) настроить внешний вид сайта в зависимости от размера экрана, на котором происходит просмотр. Можно изменять порядок, пропорции, делать невидимыми блоки веб-сайта. И всё это без использования JavaScript или сложных конструкций CSS стилей.

По flex уже сейчас много достаточно полной документации, в том числе на русском языке. Но читая длинные справочные статьи не всем просто понять мощь и возможности, которые приносит flex. В этой заметке представлен простой пример реализации flex для создания адаптивного дизайна. Главная задача — показать возможности flex, подтолкнуть вас к собственным экспериментам и использованию flex.

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


Итак, приступим.

Сразу уточную — из приведённого кода убраны стили, отвечающие за внешний вид, не связанный с адаптивностью. Это сделано для упрощения восприятия действительно важных участков кода. Полный пример кода вы можете скачать по этой ссылке.

Мы создали html файл со структурой:
HTML:
<!DOCTYPE html>
<html>
    <head>
        <title>...</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="styles.css">
    </head>
    <body>
        <div class="topbar">
            <div class="topbar-inner">
                <div class="logo">
                    <img src="logo.png" alt="">         
                </div>
                <ul class="navbar">
                    <li><a>Страница 1</a></li>
                    <li><a>Страница 2</a></li>
                    <li><a>Страница 3</a></li>
                    <li><a>Страница 4</a></li>
                </ul>
            </div>

            <div class="main-content">
                <div class="mynav">
                    <p>Навигация</p>
                </div>
                <div class="news">
                    <article>
                        <h2>...</h2>
                        <p>... </p>
                    </article>
                    <article>
                        <h2>...</h2>
                        <p>...</p>
                    </article>
                    <article>
                        <h2>...</h2>                     
                        <p>...</p>
                    </article>
                </div>
                <div class="widgets">
                    <div class="widget">Первый</div>
                    <div class="widget">Второй</div>
                    <div class="widget">Третий</div>
                </div>
            </div>
        </div>
    </body>
</html>
Главное содержимое страницы — класс main-content — то, что ниже шапки. Мы подключаем flex-контекст для всех его непосредственных потомков:
CSS:
.main-content {
    /** подключает flex-контекст для всех его непосредственных потомков  **/
    display: flex;
    display: -webkit-flex;
    display: -moz-flex;
    /** Устанавливает главную ось main-axis, определяя тем самым направление для flex-элементов, размещаемых в контейнере.  **/
    flex-direction: row;
    -webkit-flex-direction: row;
    -moz-flex-direction: row; 
    /** Задаём ширину и выравниваем этот блок по центру  **/
    max-width: 1140px;
    margin: 0 auto;
}
Редактируем первый (левый) блок. Мы задаём его ширину в 20% — flex: 2;. На самом деле, ширина определяется как 2/10. 2 — это установленное нами значение. А 10 — сумма значений всех блоков. Нумерацию порядка элементов (order: 0;) можно начинать с нуля.
CSS:
.main-content .mynav {
    /**  Задаём ширину 20% **/
    flex: 2;
    -webkit-flex: 2;
    -moz-flex: 2;
    /** Задаём порядок - элемент является первым  **/
    order: 0;
    -webkit-order: 0;
    -moz-flex-order: 0;
}
Аналогично задаём параметры для среднего (главного) блока. Только устанавливаем ширину 60% и другой порядковый номер:
CSS:
.main-content .news {
    /**  Задаём ширину 60% **/
    flex: 6;
    -webkit-flex: 6;
    -moz-flex: 6;
    /** Задаём порядок - элемент является вторым  **/
    order: 1;
    -webkit-order: 1;
    -moz-flex-order: 1;
}
Последний, третий элемент:
CSS:
.main-content .widgets {
    /**  Задаём ширину 20% **/
    flex: 2;
    -webkit-flex: 2;
    -moz-flex: 2;
    /** Задаём порядок - элемент является третьим  **/
    order: 2;
    -webkit-order: 2;
    -moz-flex-order: 2;
    /** Устанавливает главную ось main-axis, определяя тем самым направление для flex-элементов, размещаемых в контейнере.  **/
    flex-direction: column;
    -webkit-flex-direction: column;
    -moz-flex-direction: column;
}
На этом этапе у нас получился вот такой макет:

27461


При изменении размеров экрана, элементы будут изменять свой размер в заданных пропорциях.
Имитация планшета:

27462


Имитация мобильного телефона:

27463


Внешний вид, особенно на мобильный устройствах, неудовлетворительный. Поэтому продолжаем.

Дизайн для средних экранов вроде планшетов

Все нижеследующие стили помещаются в конструкцию:
CSS:
@media screen and (min-width: 768px) and (max-width: 1024px) {
}
Т.е. они начинают применяться, когда экран меньше чем 1024px, но больше чем 768px:
CSS:
 .main-content {
        /** подключает flex-контекст для всех его непосредственных потомков  **/
        display: flex;
        display: -webkit-flex;
        display: -moz-flex;
        /** Устанавливает главную ось main-axis, определяя тем самым направление для flex-элементов, размещаемых в контейнере.  **/
        flex-direction: row;
        -webkit-flex-direction: row;
        -moz-flex-direction: row;
    }
    .main-content .mynav {
        /** Ширина навигации - оставлено прожнее значение  **/
        flex: 2;
        -webkit-flex: 2;
        -moz-flex: 2;
    }
    .main-content .widgets {
        /** Ширина виджетов - уменьшена, чтобы осталось больше места на осной раздел  **/
        flex: 1;
        -webkit-flex: 1;
        -moz-flex: 1;
        /** Обрать не очень важные элементы - хорошее решение. Благодаря этому лучше будет восприниматься основной контент, для которого останется больше места  **/
        display: none;
    }
    .main-content .news {
        /** Ширина основного раздела - увеличина за счёт виджетов, которые мы убралис с экрана  **/
        flex: 8;
        -webkit-flex: 8;
        -moz-flex: 8;
    }
Теперь, при изменении размеров экрана, раздел с виджетами будет убираться с экрана, а основной раздел (который был в центре), станет занимать чуть больше места:

27464


Тем не менее, даже с учётом убранного раздела с виджетами, вид на мобильных устройствах не очень:

27465


Устанавливаем дизайн для небольших экранов вроде телефонов

Все последующие стили находятся в секции
CSS:
@media screen and (max-width: 768px) {
}
Обратите внимание на опцию стиля flex-direction: column;. Теперь в главном контейнере сайта (.main-content — всё то, что ниже шапки), элементы будут размещаться не столбиками, а полосками.
Ещё мы вернули раздел с виджетами, но перенесли его ниже главного контейнера (.news), который теперь стал первым.
Т.е. при открытии сайта на мобильном устройстве, пользователь увидит не навигацию или какую-то второстепенную информацию, он уведет основной контент. При необходимости, он сможет пролистать вниз до навигации. Причём, основной контент теперь занимает 100% ширины небольшого экрана мобильного устройства (поскольку теперь каждый контейнер внутри класса main-content размещён «полосками»):
CSS:
 .main-content {
        /** подключает flex-контекст для всех его непосредственных потомков  **/
        display: flex;
        display: -webkit-flex;
        display: -moz-flex;
        /** Устанавливает главную ось main-axis, определяя тем самым направление для flex-элементов, размещаемых в контейнере.  **/
        flex-direction: column;
        -webkit-flex-direction: column;
        -moz-flex-direction: column;
    }
    .main-content .mynav {
        /** Задаём порядок - элемент становится третьим  **/
        order: 2;
        -webkit-order: 2;
        -moz-flex-order: 2;
    }

    .main-content .news {
        /** Задаём порядок - элемент становится первым  **/
        order: 0;
        -webkit-order: 0;
        -moz-flex-order: 0;
    }

    .main-content .widgets {
        /** Задаём порядок - элемент становится вторым  **/
        order: 1;
        -webkit-order: 1;
        -moz-flex-order: 1;
    }
Стало лучше, но ещё хотелось бы позаботиться о логотипе и о ссылка в шапке.

27467


Логотип мы переместим в центр на самую высокую линию. А ссылки в шапке мы также выстроим в линии, причём, зададим им фоновый цвет — чтобы они не сливались с основным контентом:
CSS:
 .topbar {
        padding: 0;
    }

    .topbar-inner {
        /** подключает flex-контекст для всех его непосредственных потомков  **/
        display: flex;
        display: -webkit-flex;
        display: -moz-flex;
        /** Устанавливает главную ось main-axis, определяя тем самым направление для flex-элементов, размещаемых в контейнере.  **/
        flex-direction: column;
        -webkit-flex-direction: column;
        -moz-flex-direction: column;
    }

    /** Меняем расположение логотипа - переносим его в центр.  **/
    .topbar-inner .logo {     
        order: 0;
        -webkit-order: 0;
        -moz-flex-order: 0;
    }

    .topbar-inner .logo img {
        padding: 1em;
        display: block;
        margin: 0 auto;
        position: relative;
        float: none;
    }

    .topbar-inner ul.navbar {
        /** подключает flex-контекст для всех его непосредственных потомков  **/
        display: flex;
        display: -webkit-flex;
        display: -moz-flex;

        /** Устанавливает главную ось main-axis, определяя тем самым направление для flex-элементов, размещаемых в контейнере.  **/
        flex-direction: column;
        -webkit-flex-direction: column;
        -moz-flex-direction: column;    

        order: 1;
        -webkit-order: 1;
        -moz-flex-order: 1;  

        /**  **/
        background-color: #c1c7b3;
        box-shadow: inset 0px 1px 0px #41560e;
    }
    .topbar-inner ul.navbar li {
        padding: 0;

        flex: 1;
        -webkit-flex: 1;
        -moz-flex: 1;
    }
Теперь мобильный вид у нас выглядит так:

27466


Заключение

У flex ещё много чего интересного, много опций и стилей. Я показал только самую базовую реализацию. Рекомендую также прочитать дополнительную справочную информацию.
 
  • Нравится
Реакции: shkolnick_lamer
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!