← Назад к вопросам

В чём разница между mainAxisAlignment и crossAxisAlignment?

1.6 Junior🔥 192 комментариев
#Flutter виджеты

Комментарии (2)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

mainAxisAlignment vs crossAxisAlignment

Это фундаментальная концепция во Flutter, которая определяет расположение виджетов в Flex контейнерах (Row, Column).

Основная идея

  • mainAxis — это основная ось контейнера
  • crossAxis — это перпендикулярная ось
Для Row (горизонтальный):
┌─────────────────────────┐
│ ┌──┐ ┌──┐ ┌──┐          │ ← mainAxis (слева → направо)
│ │  │ │  │ │  │          │
│ └──┘ └──┘ └──┘          │
└─────────────────────────┘
↓ crossAxis (сверху → вниз)

Для Column (вертикальный):
┌────────┐
│ ┌────┐ │
│ │    │ │ ↑ mainAxis
│ ├────┤ │
│ │    │ │
│ ├────┤ │
│ │    │ │
│ └────┘ │
└────────┘
← crossAxis →

Row и Column ориентация

// ROW — горизонтальное расположение
Row(
  mainAxisAlignment: MainAxisAlignment.spaceEvenly,  // Горизонтально
  crossAxisAlignment: CrossAxisAlignment.center,      // Вертикально
  children: [
    Icon(Icons.star),
    Icon(Icons.favorite),
    Icon(Icons.share),
  ],
);

// COLUMN — вертикальное расположение
Column(
  mainAxisAlignment: MainAxisAlignment.spaceAround,   // Вертикально
  crossAxisAlignment: CrossAxisAlignment.stretch,     // Горизонтально
  children: [
    Text('Заголовок'),
    Text('Описание'),
    Text('Подпись'),
  ],
);

mainAxisAlignment значения

// 1. MainAxisAlignment.start (по умолчанию)
Row(
  mainAxisAlignment: MainAxisAlignment.start,
  children: [Box("A"), Box("B"), Box("C")],
)
// Результат: A B C ______

// 2. MainAxisAlignment.end
Row(
  mainAxisAlignment: MainAxisAlignment.end,
  children: [Box("A"), Box("B"), Box("C")],
)
// Результат: ______ A B C

// 3. MainAxisAlignment.center
Row(
  mainAxisAlignment: MainAxisAlignment.center,
  children: [Box("A"), Box("B"), Box("C")],
)
// Результат: ___ A B C ___

// 4. MainAxisAlignment.spaceBetween
Row(
  mainAxisAlignment: MainAxisAlignment.spaceBetween,
  children: [Box("A"), Box("B"), Box("C")],
)
// Результат: A _____ B _____ C

// 5. MainAxisAlignment.spaceAround
Row(
  mainAxisAlignment: MainAxisAlignment.spaceAround,
  children: [Box("A"), Box("B"), Box("C")],
)
// Результат: _ A _ _ B _ _ C _

// 6. MainAxisAlignment.spaceEvenly
Row(
  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  children: [Box("A"), Box("B"), Box("C")],
)
// Результат: __ A __ B __ C __

crossAxisAlignment значения

// 1. CrossAxisAlignment.start
Row(
  crossAxisAlignment: CrossAxisAlignment.start,  // Сверху
  children: [
    Column(children: [Box("A"), Box("B")]),
    Box("Single"),
  ],
)
// Результат: [A]  Single
//            [B]

// 2. CrossAxisAlignment.center (по умолчанию)
Row(
  crossAxisAlignment: CrossAxisAlignment.center,
  children: [Box("A"), Box("B"), Box("C")],
)
// Результат: все выравнены в центре по высоте

// 3. CrossAxisAlignment.end
Row(
  crossAxisAlignment: CrossAxisAlignment.end,    // Снизу
  children: [
    Column(children: [Box("A"), Box("B")]),
    Box("Single"),
  ],
)
// Результат: [A]
//            [B]  Single

// 4. CrossAxisAlignment.stretch
Row(
  crossAxisAlignment: CrossAxisAlignment.stretch,
  children: [
    Expanded(child: Container(color: Colors.blue)),
    Text("Будет растянут по высоте"),
  ],
)
// Дочерние элементы растягиваются на всю высоту

// 5. CrossAxisAlignment.baseline
Row(
  crossAxisAlignment: CrossAxisAlignment.baseline,
  textBaseline: TextBaseline.alphabetic,
  children: [
    Text("Hello", style: TextStyle(fontSize: 24)),
    Text("World", style: TextStyle(fontSize: 16)),
  ],
)
// Выравнивание по базовой линии текста

Практические примеры

Хедер с логотипом и менюшкой

Row(
  mainAxisAlignment: MainAxisAlignment.spaceBetween,
  crossAxisAlignment: CrossAxisAlignment.center,
  children: [
    Image.asset('logo.png', width: 50),
    Row(
      mainAxisSize: MainAxisSize.min,
      children: [
        TextButton(onPressed: () {}, child: Text('Home')),
        TextButton(onPressed: () {}, child: Text('About')),
        TextButton(onPressed: () {}, child: Text('Contact')),
      ],
    ),
  ],
)

Карточка с информацией

Column(
  mainAxisAlignment: MainAxisAlignment.start,
  crossAxisAlignment: CrossAxisAlignment.stretch,
  children: [
    Image.network('https://example.com/image.jpg'),
    Padding(
      padding: EdgeInsets.all(16),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text('Title', style: Theme.of(context).textTheme.headlineSmall),
          SizedBox(height: 8),
          Text('Description text here'),
          SizedBox(height: 16),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              ElevatedButton(onPressed: () {}, child: Text('Action 1')),
              ElevatedButton(onPressed: () {}, child: Text('Action 2')),
            ],
          ),
        ],
      ),
    ),
  ],
)

Важные моменты

  1. mainAxisSize — контролирует как контейнер занимает место:

    Row(
      mainAxisSize: MainAxisSize.min,  // Только столько, сколько нужно детям
      children: [...]
    )
    
  2. Expanded и Flex игнорируют mainAxisAlignment:

    Row(
      children: [
        Expanded(flex: 2, child: Container(color: Colors.blue)),
        Expanded(flex: 1, child: Container(color: Colors.red)),
      ],
    )
    
  3. Для сложных layouts используй Align:

    Align(
      alignment: Alignment.topRight,
      child: FloatingActionButton(onPressed: () {}),
    )
    

Шпаргалка

ОсьRowColumn
Mainслева → справасверху → вниз
Crossсверху → внизслева → справа
mainAxisAlignmentгоризонтальноевертикальное
crossAxisAlignmentвертикальноегоризонтальное
В чём разница между mainAxisAlignment и crossAxisAlignment? | PrepBro