Flexbox в React Native — руководство по гибким макетам

Flexbox — это инструмент CSS-подобной модели, который позволяет строить гибкие одноосные макеты. Он даёт контроль над позиционированием дочерних элементов внутри контейнера. В React Native flexbox включён по умолчанию, поэтому вам не нужно явно указывать display: flex.
Что важно знать в двух строках: “flex” управляет дроблением доступного пространства; “flexDirection” задаёт основную ось; “justifyContent” выравнивает по основной оси; “alignItems” — по перекрёстной оси.
Почему Flexbox в React Native отличается от web
Кратко о ключевых различиях между поведением flexbox в вебе и в React Native:
- flexDirection по умолчанию: в вебе — row, в React Native — column. Это влияет на основную ось.
- alignContent по умолчанию: web — stretch, React Native — flex-start.
- flexShrink по умолчанию: web — 1, React Native — 0.
Важно: многие туториалы в интернете ориентированы на CSS в браузере. В RN часть предположений меняется, поэтому не копируйте стили из веба без проверки.
Быстрая шпаргалка по свойствам (определения в одну строку)
- flex — число; доля доступного пространства, которую занимает элемент.
- flexDirection — определяет основную ось: row или column.
- justifyContent — выравнивает дочерние элементы вдоль основной оси.
- alignItems — выравнивает дочерние элементы вдоль поперечной (вторичной) оси.
- alignSelf — переопределяет alignItems для конкретного элемента.
- flexWrap — позволяет переносить элементы на новую строку.
- gap — расстояние между элементами (поддерживается в современных версиях RN).
Принцип работы flex: практические примеры
Ниже — корректные примеры кода с комментариями. Обратите внимание: в исходных примерах иногда встречались опечатки в свойстве backgroundColor — их мы исправили.
Пример 1: один View занимает весь экран (flex: 1)
import React from "react";
import { View } from "react-native";
export default function App() {
return (
);
}Пояснение: контейнер (корневой View) занимает весь экран, так как у дочернего элемента flex: 1 и больше ничего ему не конкурирует.
Пример 2: два View с соотношением 1:3
import React from "react";
import { View } from "react-native";
export default function App() {
return (
);
}Пояснение: доступное пространство делится на 4 части (1 + 3). Первый элемент занимает 1/4, второй — 3/4.
flexDirection: как задавать основную ось
flexDirection определяет направление основной оси. В React Native по умолчанию column, поэтому элементы по умолчанию укладываются сверху вниз.
Варианты: row, column, row-reverse, column-reverse.
Пример: горизонтальное расположение трёх квадратов
import React from "react";
import { StyleSheet, View } from "react-native";
const styles = StyleSheet.create({
container: {
backgroundColor: "#00FF00",
flex: 1,
alignItems: "center",
flexDirection: "row",
},
square: {
backgroundColor: "#FF0000",
width: 98,
height: 98,
margin: 4,
},
});
export default function App() {
return (
);
}Совет: если вам нужно менять порядок визуального представления без изменения DOM/JSX-структуры, используйте row-reverse или column-reverse.
justifyContent: выравнивание вдоль основной оси
justifyContent управляет распределением пространства вдоль основной оси. Возможные значения:
- flex-start — в начале оси
- flex-end — в конце оси
- center — по центру
- space-between — равные промежутки между элементами
- space-around — промежутки вокруг элементов
- space-evenly — равномерные промежутки
Пример: выравнивание в строке
import React from "react";
import { StyleSheet, View } from "react-native";
const styles = StyleSheet.create({
container: {
backgroundColor: "#00FF00",
flex: 1,
justifyContent: "flex-start",
flexDirection: "row",
},
square: {
backgroundColor: "#FF0000",
width: 98,
height: 98,
margin: 6,
},
});
export default function App() {
return (
);
}Если flexDirection = column, то justifyContent применяет вертикальное выравнивание. Если row — горизонтальное.
alignItems: выравнивание вдоль поперечной оси
alignItems управляет тем, как дети располагаются по перекрёстной (вторичной) оси. Значения: flex-start, flex-end, center, baseline, stretch.
Пример: alignItems: flex-start в строке
import React from "react";
import { StyleSheet, View } from "react-native";
const styles = StyleSheet.create({
container: {
backgroundColor: "#00FF00",
flex: 1,
alignItems: "flex-start",
flexDirection: "row",
},
square: {
backgroundColor: "#FF0000",
width: 98,
height: 98,
margin: 6,
},
});
export default function App() {
return (
);
}Если задать flexDirection: column и alignItems: center, элементы будут стопкой по вертикали, а их центры будут выровнены по горизонтали.
alignSelf: индивидуальное выравнивание элемента
alignSelf позволяет переопределить alignItems для конкретного дочернего элемента. Значения те же, что и у alignItems.
Пример:
import React from "react";
import { StyleSheet, View } from "react-native";
const styles = StyleSheet.create({
container: {
backgroundColor: "#00FF00",
flex: 1,
alignItems: "center",
justifyContent: "center",
flexDirection: "row",
},
square: {
backgroundColor: "#FF0000",
width: 98,
height: 98,
margin: 6,
},
});
export default function App() {
return (
);
}Дополнительные свойства
- flexWrap: nowrap (по умолчанию) или wrap. Используйте, когда дочерние элементы не помещаются в одну линию и вам нужен перенос.
- gap: расстояние между элементами. В новых версиях RN поддерживается как числовое значение (в пикселях/pt).
Замечание: gap в RN работает иначе, чем gap в CSS Grid; проверяйте поддержку в вашей версии React Native.
Практическая методология: как проектировать макет с Flexbox (мини-SOP)
- Начните с определения основной оси (flexDirection).
- Разбейте макет на логические контейнеры (header, content, footer). Каждый контейнер — отдельный View.
- Для каждого контейнера определите правило заполнения пространства (flex значения).
- Используйте justifyContent для распределения элементов по основной оси.
- Используйте alignItems для выравнивания по перекрёстной оси.
- При необходимости переопределяйте отдельные элементы через alignSelf.
- Тестируйте на устройствах разного размера и ориентации.
Чеклист перед релизом макета (роль: разработчик)
- Корневые контейнеры имеют предсказуемые flex-значения.
- Нет магических абсолютных размеров, мешающих адаптивности.
- Проверены сценарии с длинным контентом (перенос/скролл).
- Отладочные границы (border) временно включены для проверки выравнивания.
- Тесты на разных плотностях пикселей и ориентациях устройства.
Частые ошибки и как их исправить
Ошибка: элементы не выравниваются как ожидается. Решение: проверьте flexDirection — вы могли считать ось горизонтальной, но она вертикальная по умолчанию.
Ошибка: элемент внезапно исчезает или перекрывается. Решение: проверьте отрицательные margin, абсолютное позиционирование или несовместимые flex-правила у соседних элементов.
Ошибка: gap не применяется. Решение: убедитесь в поддержке gap в вашей версии RN или реализуйте отступы через margin у дочерних элементов.
Когда Flexbox не подходит (кратко)
- Сложные двумерные макеты (табличные сетки с точным выравниванием по строкам и столбцам) удобнее делать через Grid-подобные библиотеки или вручную позиционируя элементы.
- Для графических редакторов или канвасов лучше использовать абсолютное позиционирование.
Ментальные модели и эвристики
- Представляйте контейнер как полку: flexDirection выбирает ориентацию полки. justifyContent размещает предметы вдоль полки, alignItems — контролирует высоту расположения предметов.
- Всегда начинайте с контейнера, затем переходите к элементам внутри. Меньшие изменения у родителя часто проще и правильнее, чем много индивидуальных правок детей.
Диаграмма принятия решения (Mermaid)
flowchart TD
A[Нужен адаптивный макет?] -->|Да| B{Основная ось}
B -->|Горизонтально| C[flexDirection: row]
B -->|Вертикально| D[flexDirection: column]
C --> E{Требуется перенос?}
D --> E
E -->|Да| F[flexWrap: wrap]
E -->|Нет| G[flexWrap: nowrap]
F --> H[Использовать gap или margin между элементами]
G --> HГлоссарий (1 строка каждая)
- Flex: число, определяющее долю доступного пространства.
- Основная ось: направление, заданное flexDirection.
- Перекрёстная ось: ось, перпендикулярная основной.
Советы по отладке
- Включайте временные рамки (border: ‘1px solid red’) для контейнеров.
- Используйте инспектор макета в отладчике (React Native Debugger / Flipper).
- Проверьте поведение при изменении ориентации экрана.
Совместимость и миграция
- Проверьте вашу версию React Native перед использованием gap. Если gap не поддерживается, используйте margin у дочерних элементов.
- flexBasis и некоторые расширенные свойства могут отличаться в поведении. Всегда проверяйте на целевых устройствах.
Короткое практическое задание (тестовые случаи)
- Создать экран с header (фиксированная высота), content (скролл, занимает всё оставшееся пространство) и footer (фиксированная высота).
- Критерии приёмки: header и footer всегда видимы; content занимает остаток и скроллится при переполнении.
- Создать сетку карточек 3xN, которая переносится на новую строку при уменьшении ширины.
- Критерии приёмки: карточки равномерно распределены; нет перекрытий.
Резюме и следующие шаги
Flexbox в React Native — мощный и гибкий инструмент для построения адаптивных интерфейсов. Начните с простых контейнеров и постепенно добавляйте правила выравнивания. Тестируйте на реальных устройствах и используйте отладочные рамки для визуальной валидации.
Важно: если вы переносите стили с веба, проверьте значения по умолчанию (особенно flexDirection и flexShrink).
Дополнительные шаги:
- Изучите компоненты Layout в документации React Native.
- Попробуйте построить несколько макетов разной сложности и сравнить поведение.
Ключевые ресурсы: официальная документация React Native по Layout и статьи по flexbox (в англоязычных источниках — «Flexbox in React Native»).
Похожие материалы
Анимация в Keynote на iPad — быстрый старт
Как использовать Paste Special в Excel
История буфера обмена в Windows 11: включение и использование
Настройка роутера — быстрый практический гид
Fire Toolbox — как настроить планшет Amazon Fire