Как сместить футер в самый низ страницы: Flexbox vs. Grid
От автора: в течение многих лет я постоянно ссылалась на статью Мэтью Джеймса Тейлора, чтобы узнать, как разместить футер в нижней части страницы независимо от длины основного содержимого. Этот метод основывался на задании явной высоты футера, что являлось не масштабируемым, но очень хорошим решением до Flexbox.
Если вы в основном имеете дело с разработкой SPA, вы можете быть озадачены тем, почему эта проблема вообще все еще существует, но ведь есть возможность, что футер будет размещаться:
на странице входа
в блоге / новостных статьях (без рекламы…)
на промежуточных страницах потока, таких как страница подтверждения действия
на страницах со списком товаров
в описании события
Есть два способа справиться с этим с помощью современного CSS: flexbox и grid. Вот демо, по умолчанию используется метод flexbox. Если вы откроете полный Codepen, вы можете переключить значение переменной $method на grid, чтобы увидеть альтернативный метод.
Ниже демо-версии мы подробно рассмотрим оба способа:
Метод Flexbox
Для этого метода мы определяем следующее:
min-height : 100vh ;
display : flex ;
flex-direction : column ;
margin-top : auto ;
margin : 0 auto ;
// or : align-self : center
max-width : 80ch ;
Как это работает
Во-первых, мы обеспечиваем, чтобы элемент body растягивался как минимум на всю высоту экрана min-height: 100vh. Это не вызовет переполнения, если контент короткий (исключение: некоторые мобильные браузеры), и позволит контенту увеличивать высоту всего контейнера по мере необходимости.
Параметр flex-direction: column поддерживает поведение нормального потока документа с точки зрения сохранения стекирования блочных элементов (что предполагает, что непосредственные потомки body действительно являются блочными элементами).
Преимущество flexbox заключается в использовании поведения margin: auto. Этот странный трюк приведет к тому, что поле заполняет все пространство между элементом, для которого свойство установлено, и его соседним элементов в соответствующем направлении. Установка margin-top: auto эффективно сдвигает футер в нижнюю часть экрана.
Проблемы
В демонстрации я добавил outline для main, чтобы продемонстрировать, что в методе flexbox элемент main не заполняет высоту. Вот почему мы должны использовать хитрость margin-top: auto. Это вряд ли имеет значение для вас, но если это так, посмотрите метод сетки, в котором элемент main растягивается, чтобы заполнить доступное пространство.
Метод сетки
Для этого метода мы задаем следующее:
apt.ru
Timeweb — компания, которая размещает проекты клиентов в Интернете, регистрирует адреса сайтов и предоставляет аренду виртуальных и физических серверов. Разместите свой сайт в Сети — расскажите миру о себе!
Виртуальный хостинг
Быстрая загрузка вашего сайта, бесплатное доменное имя, SSL-сертификат и почта. Первоклассная круглосуточная поддержка.
от 196 руб руб. / мес
Аренда VDS и VPS
Виртуальные серверы с почасовой оплатой. Меняйте конфигурацию сервера в любой момент и в пару кликов.
Начинаем работу с раскладками React Native
В этом уроке вы научитесь верстать приложения на React Native, и узнаете, как сверстать часто используемые в приложениях раскладки страниц. Это такие раскладки, как stack-раскладка, grid-раскладка и absolute-раскладка. Я предполагаю, что вы знакомы с основами написания стилей для приложения на React Native, и в целом с тем, как писать CSS стили, поэтому не буду сильно заострять внимание на Stylesheet.create и на том, как добавлять стили разным элементам.
Исходный код для этого урока вы можете найти на Github.
Развёртывание проекта
Чтобы упростить работу, воспользуемся React Native for Web. C React Native for Web Starter, мы сможем легко запустить новый проект на React Native, который будет работать и в браузере. Этот код 100% совместим с React Native project. Для каждой раскладки страницы мы создадим отдельный компонент, который по желанию можно будет потом импортировать в обычный проект на React Native. Мы будем использовать React Native for Web для того, чтобы было легче настроить и запустить проект.
Для того, чтобы развернуть проект, можно воспользоваться следующими командами:
git clone https://github.com/grabcode/react-native-web-starter.git RNLayouts
cd RNLayouts
rm -rf .git
npm install
После того, как закончится установка, перейдите в директорию app/components. Там лежат файлы, с которыми мы в основном будем работать.
Откройте файл App.js и замените код по умолчанию на следующий код:
import React, Component > from 'react';
//import the components that we'll be creating here
export class App extends Component
render()
return (
//use the components here
Впоследствии, сюда вы можете импортировать компоненты, которые мы будем создавать далее, и отрисовывать их на странице с помощью этого файла. Просто запомните, что любой компонент, который мы сохраним в папке layouts, не должен отрисовываться никаким другим файлом. Например, для файла layouts/StackLayout.js добавьте в App.js:
import React, Component > from 'react';
//import the components that we'll be creating here
import StackLayout from './layouts/StackLayout';
export class App extends Component
render()
return (
StackLayout />
Запустить проект можно следующей командой:
npm run dev
Тогда запущенный проект будет доступен в браузере по адресу http://localhost:3000 . Если вы измените любой из файлов, импортированных в App.js, то произойдёт полная перезагрузка страницы.
Как верстать разные раскладки страниц
Раскладки страниц в React Native верстаются с помощью подмножества спецификации флексбокс. (Я говорю «подмножество», потому что используются не все положения из спецификации). Так что если вы уже знакомы с флексбоксом, то можете применять свои навыки в React Native. Ещё стоит отметить, что в React Native нет плавающих блоков и процентных значений. Так что верстать можно только с помощью флексбокса и CSS позиционирования.
Stack-раскладка
Первая раскладка, которую мы сверстаем, это stack-раскладка. В случае вертикальной ориентации, элементы выкладываются один под другим, а в случае горизонтальной — следуют друг за другом. Давайте сначала рассмотрим случай вертикальной ориентации:
Ниже код этой раскладки:
import React, Component > from 'react';
import
StyleSheet,
View,
Dimensions
> from 'react-native';
var height > = Dimensions.get('window');
var box_count = 3;
var box_height = height / box_count;
export default class VerticalStackLayout extends Component
render()
return (
View style=styles.container>>
View style=<[styles.box, styles.box1]>>/View>
View style=<[styles.box, styles.box2]>>/View>
View style=<[styles.box, styles.box3]>>/View>
/View>
const styles = StyleSheet.create(
container:
flex: 1,
flexDirection: 'column'
height: box_height
box1:
backgroundColor: '#2196F3'
box2:
backgroundColor: '#8BC34A'
box3:
backgroundColor: '#e3aa1a'
Из кода выше ясно, что сначала мы получаем доступную приложению высоту окна. Затем вычисляем высоту каждого блока. Так как у нас три блока, то делим доступную высоту на три.
var height > = Dimensions.get('window');
var box_count = 3;
var box_height = height / box_count;
В вёрстке должен быть контейнер, оборачивающий все эти блоки. Общие стили задаются в объекте box, а уникальные цвета фона — в объектах с уникальными названиями (box1, box2, box3).
View style=styles.container>>
View style=<[styles.box, styles.box1]>>/View>
View style=<[styles.box, styles.box2]>>/View>
View style=<[styles.box, styles.box3]>>/View>
/View>
При использовании флексбокса контейнеру нужно добавить свойство flex . Значение этого свойства влияет на то, сколько пространства займет блок. Если оно равно 1 , это означает, что он займёт всё доступное пространство, при условии, что у него нет соседей. Позже мы рассмотрим пример использования свойства flex в случае, когда у блока есть соседи.
flexDirection позволяет задать главную ось раскладки. По умолчанию это column . Для flexDirection , равного column , дочерние элементы контейнера будут выкладываться вертикально (друг под другом), а для row — горизонтально (друг за другом). Для того, чтобы высота блоков была одинаковой, задайте высоту box равной вычисленному ранее значению.
const styles = StyleSheet.create(
container:
flex: 1,
flexDirection: 'column'
height: box_height //set this one
box1:
backgroundColor: '#2196F3'
box2:
backgroundColor: '#8BC34A'
box3:
backgroundColor: '#e3aa1a'
Вот рисунок, который помогает понять, как контент будет распределяться по странице в зависимости от значения flexDirection .

Только что я вам продемонстрировал фиксированную вёрстку. Вы не сможете использовать Dimensions для вычисления ширины или высоты элементов, если ваше приложение поддерживает как портретный, так и ландшафтный режимы ориентации устройства. Потому что как только пользователь повернёт устройство, ширина или высота, которую вы вычислили до этого, станут неправильными. React Native не станет их автоматически пересчитывать, так что приложение будет странно выглядеть.
Флексбокс сможет сделать вычисления за вас, нужно только указать правильные значения. Для того, чтобы добиться такой раскладки, как в примере выше, без использования Dimensions , всё, что вам нужно сделать, это указать flex: 1 для всех блоков вместо указания конкретного значения height .
flex: 1
Теперь рассмотрим пример использования flex в случае, когда у блока есть соседи. Пусть есть 3 соседних блока с одним и тем же значением flex . Так как значение flex у всех одинаковое, то все три блока поровну разделят между собой доступное пространство. (Вообще в этом случае любое значение flex даст тот же эффект, если оно будет одинаковым у всех этих блоков).
С помощью этих знаний вы теперь сможете верстать раскладки с шапкой, основным контентом и подвалом:
//header
box1:
flex: 1,
backgroundColor: '#2196F3'
//content
box2:
flex: 10,
backgroundColor: '#8BC34A'
//footer
box3:
flex: .5,
backgroundColor: '#e3aa1a'
Вот как будет выглядеть результат:

Отметим, что эта вёрстка статична. Если основной контент не поместится по высоте в заданную область, то его часть будет скрыта. Если хотите избежать подобного эффекта, можно использовать встроенный ScrollView компонент, чтобы автоматически генерировалась вертикальная полоса прокрутки, как у обычных веб-страниц.
Горизонтальные stack-раскладки
Для того, чтобы сверстать горизонтальные stack-раскладки, всё, что вам нужно сделать, это изменить значение flexDirection на row .
container:
flex: 1,
flexDirection: 'row'
Если поменяем значение свойства flex у блоков обратно на 1 , то получится такая раскладка:

Мы поменяли только свойство flexDirection , которое теперь равно row . Так как у всех блоков flex: 1 , то они будут одинаковой ширины и высоты. Все идеи вертикальной stack-раскладки применимы и в этом случае.
Выравнивание контента
Если хотите проконтролировать то, как распределятся дочерние элементы внутри контейнера, установите свойство justifyContent для контейнера.
Ниже пять возможных значений этого свойства. В примерах ниже высота каждого дочернего элемента уменьшена для наглядности. Вы бы не увидели никакой разницы, если у каждого дочернего элемента свойство flex было бы равно 1 , потому что в итоге они заняли бы всё доступное пространство
- flex-start : дочерние элементы прижаты к началу. Обратите внимание на белый фон прямо под последним дочерним элементом. Вот как вы понимаете, что используется flex-start , потому что все дочерние элементы сдвинуты к началу. Из-за этого в конце осталось пустое пространство.

- flex-end : дочерние элементы прижаты к концу. Отметим, что в этом случае пустое пространство осталось в начале.

- center : дочерние элементы выровнены по центру контейнера. В этом случае пустое пространство делится поровну между началом и концом контейнера.

- space-around : дочерние элементы распределены так, что между ними появились одинаковые отступы. Это означает, что у внешних элементов осталось меньше пространства на их внешних сторонах, а отступы между каждыми двумя соседними элементами удвоились.

- space-between : дочерние элементы распределены так, что между ними появились отступы одинакового размера.

Как вы могли заметить, каждое из этих стилевых свойств зависит от высоты или ширины дочерних элементов. Оно зависит от ширины, если flexDirection равно row , или от высоты, если flexDirection равно column .
Например, space-between никак не повлияет на вертикальную stack-раскладку, если каждый дочерний элемент использует свойство flex для контроля высоты. Это потому, что не останется никакого свободного пространства на отступы между дочерними элементами.
Выравнивание элементов
На первый взгляд justifyContent и alignItems как будто делают одну и ту же вещь. У них также совпадают три возможных значения: flex-start , flex-end и center , помимо этого у align-items есть свойство stretch .
Основное различие между justifyContent и alignItems заключается в том, по какой оси будут выравниваться дочерние элементы. Как вы уже знаете, justifyContent всегда выравнивает дочерние элементы по главной оси. А alignItems — по поперечной оси, которая перпендикулярна главной.
Мы уже знаем, что то, какая ось будет главной, а какая — поперечной, зависит от значения свойства flexDirection . Так что, если flexDirection равно row , основная ось идёт слева направо. Значит, поперечная ось идёт сверху вниз. С другой стороны, если flexDirection равно column , тогда поперечная ось идёт слева направо.
Ниже приведено несколько примеров, в которых попарно сравниваются результаты применения justifyContent и alignItems , при условии, что flexDirection равно row . В каждом примере сначала показан результат применения justifyContent , а за ним — результат применения alignItems .
- flex-start : элементы позиционируются одинаково, поэтому результат применения alignItems выглядит точно так же, как и justifyContent .

- flex-end : теперь мы начинаем видеть разницу. В первом случае, блоки сдвинуты к концу первого ряда, а во втором случае — к началу последнего ряда.

- center : в случае center блоки располагаются по тем же принципам, как и в других рассмотренных выше случаях. В первом случае блоки центрированы по оси x, а во втором — по оси y.



- stretch : используйте это значение, если хотите, чтобы дочерние элементы растянулись и полностью заполнили контейнер. Это значение по умолчанию свойства alignItems , так что явно указывать его необязательно. Вы уже видели, как оно работает, когда мы верстали вертикальную и горизонтальную stack-раскладки.
Вот код для рассмотренных выше примеров. Просто поиграйте со значениями свойств flexDirection , justifyContent и alignItems , если хотите понять, как они влияют на раскладку:
import React, Component > from 'react';
import
